Why my image buttons are not appearing? - python

I am trying to place two image buttons on my image background in a certain position, but my buttons are not appearing. I think their images are behind the background.
I tried to use place and pack, both did not work. What could be the problem?
from tkinter import*
import tkinter as tk
import settings
class Application(Frame):
def __init__ (self, master):
Frame.__init__(self,master)
self.grid()
self.create_widgets()
def create_widgets(self):
button1 = PhotoImage(file ="button1.gif")
button2 = PhotoImage(file ="button2.gif")
settings_button = Button(self, image = button1,
command = self.mult_command, width = 15)
settings_button.place(x=1, y=1)
rules_button = Button(self, image = button2,
command = self.the_rules, width = 15)
rules_button.place(x=50, y=50)
def main_code():
window = Tk()
window.title("The Bouncer")
bg_image = PhotoImage(file ="pic.gif")
x = Label (image = bg_image)
x.image = bg_image
x.place(x = 0, y = 0, relwidth=1, relheight=1)
window.geometry("600x300")
app = Application(window)
window.mainloop()
main_code()
thanks

It is likely that your image is being garbage collected before it is displayed. This is a common Tkinter gotcha. Try changing the lines:
button1 = PhotoImage(file ="button1.gif")
button2 = PhotoImage(file ="button2.gif")
to
self.button1 = PhotoImage(file ="button1.gif")
self.button2 = PhotoImage(file ="button2.gif")
and use
settings_button = Button(self, image = self.button1, command = self.mult_command, width = 15)
etc.
This should keep a reference to your image, stopping it from getting garbage collected.

In addition to keeping a reference to the image, you have a problem with this line:
self.grid()
in the __init__ method of Application. It's gridding the Frame into the window, but since nothing is ever packed or gridded into the frame, it doesn't ever expand past a little, tiny frame, so you just don't see the Buttons inside it. A simple fix here would be the pack method, with arguments to fill the window and expand when needed:
self.pack(fill=BOTH, expand=1)

Related

How to add multiple effects to a picture such as contrast and brightness at the same time

I created a simple program using python to change picture Contrast,Brightness color and etc. First I just added one effect, and it worked well, I managed to link it with a Scaler. Then I tried to add multiple effect at once which I've also linked with scalers, but when I try to add multiple effects on the picture (e.g Contrast and brightness at the same time) I got a grey Screen, or just nothing happened to the picture.
from tkinter import *
from tkinter import ttk
from tkinter.filedialog import askopenfilename
from PIL import Image
from PIL import ImageEnhance
def main():
window = Tk()
window.geometry("400x290")
window.configure(background="#EBEBEB")
OpenB = ttk.Button(window, text="Import Photo")
OpenB.pack()
def onClickImport():
askimage = askopenfilename()
global img
img=Image.open(askimage)
OpenB.config(command=onClickImport)
window.mainloop()
window2 = Tk()
window2.geometry("400x290")
window2.configure(background="#EBEBEB")
DisplayButton=ttk.Button(window2,text="Show")
DisplayButton.pack()
ScalerContrast= ttk.Scale(window2, from_=1.0, to_=5.0)
ScalerContrast.pack()
ScalerBrightness = ttk.Scale(window2, from_=1.0, to_=5.0)
ScalerBrightness.pack()
ScalerColor = ttk.Scale(window2, from_=1, to_=100)
ScalerColor.pack()
ScalerSharpness = ttk.Scale(window2, from_=1, to_=100)
ScalerSharpness.pack()
textCon=Text(window2,width=8,height=1)
textCon.insert(END,"Contrast")
textCon.config(state=DISABLED)
textCon.configure(background="#EBEBEB")
textCon.configure(font="Roboto")
textCon.pack()
textBr=Text(window2,width=8,height=1)
textBr.insert(END,"Brightness")
textBr.config(state=DISABLED)
textBr.configure(background="#EBEBEB")
textBr.configure(font="Roboto")
textBr.pack()
textCor=Text(window2,width=8,height=1)
textCor.insert(END,"Color")
textCor.config(state=DISABLED)
textCor.configure(background="#EBEBEB")
textCor.configure(font="Roboto")
textCor.pack()
textSh=Text(window2,width=8,height=1)
textSh.insert(END,"Sharpness")
textSh.config(state=DISABLED)
textSh.configure(background="#EBEBEB")
textSh.configure(font="Roboto")
textSh.pack()
converter = ImageEnhance.Contrast(img)
converter1= ImageEnhance.Brightness(img)
converter2= ImageEnhance.Color(img)
converter3= ImageEnhance.Sharpness(img)
def onClickDisplay():
img2=converter.enhance(ScalerContrast.get()) and converter1.enhance(ScalerBrightness.get()) and\
converter2.enhance(ScalerColor.get()) and converter3.enhance(ScalerColor.get())
img2.show()
DisplayButton.config(command=onClickDisplay)
window2.mainloop()
if __name__=='__main__':
main()
Welcome to SO!
First of all, you don't have to use config for all your Buttons, Text widgets and so on - you can simply give all those options as arguments when you're creating a widget, e.g.
textCon = Text(window2, width=8, height=1, state=DISABLED, background="#EBEBEB", font="Roboto")
This makes your code shorter, simpler and faster.
What you're doing in onClickDisplay does not work for a simple reason. You are using and, which is a boolean operator, to try to make multiple things happen at once - which is not what and is about. This is how i would rewrite your code:
class CustomImageEnhancer()
def __init__(self):
def onClickImport():
askimg = fd.askopenfilename()
self.img = Image.open(askimage)
return self.img
def converted_image(img_a, contrast, brightness, color, sharpness):
contrast_converter = ImageEnhance.Contrast(img_a)
img_b = contrast_converter.enhance(contrast)
brightness_converter = ImageEnhance.Brightness(img_b)
img_c = brightness_converter.enhance(brightness)
color_converter = ImageEnhance.Color(img_c)
img_d = color_converter.enhance(color)
sharpness_converter = ImageEnhance.Sharpness(img_d)
img_final = sharpness_converter.enhance(sharpness)
return img_final
def onClickDisplay():
cont = ScalerContrast.get()
bright = ScalerBrightness.get()
col = ScalerColor.get()
sharp = ScalerSharpness.get()
img = self.img
new_img = converted_image(img, cont, bright, col, sharp)
new_img.show()
root = Tk()
OpenB = ttk.Button(root, text="Import Photo", command=onClickImport)
OpenB.pack()
DisplayButton=ttk.Button(root, text="Show", command=onClickDisplay)
ScalerContrast= ttk.Scale(root, from_=1.0, to_=5.0)
ScalerBrightness = ttk.Scale(root, from_=1.0, to_=5.0)
ScalerColor = ttk.Scale(root, from_=1, to_=100)
ScalerSharpness = ttk.Scale(root, from_=1, to_=100)
DisplayButton.pack()
ScalerContrast.pack()
ScalerBrightness.pack()
ScalerColor.pack()
ScalerSharpness.pack()
textCon=Text(root, width=8, height=1, state=DISABLED, background="#EBEBEB", font='Roboto')
textCon.insert(END, 'Contrast')
textCon.pack()
textBr=Text(root, width=8, height=1, state=DISABLED, background='#EBEBEB', font='Roboto')
textBr.insert(END, 'Brightness')
textBr.pack()
textCor=Text(root, width=8, height=1, state=DISABLED, background='#EBEBEB', font='Roboto')
textCor.insert(END, 'Color')
textCor.pack()
textSh=Text(root, width=8, height=1, state=DISABLED, background='#EBEBEB', font='Roboto')
textSh.insert(END, 'Color')
textSh.pack()
root.mainloop()
window=CustomImageEnhancer()
By defining a class, you can work around having to use global variables. Opening two windows is not necessary in your case, as you can just add the button for choosing the image file to your other window. I would recommend using place() instead of pack(), as it will allow you to define exact x and y coordinates for your different widgets inside the window, which will make it look more structured - pack simply places widgets one after another.

Python GUI to scroll through photos in a window

I am trying to develop a Python Tkinter widget that opens a window displaying a photo and allows the user to scroll through the photos using a scroll bar. For context, the idea is to be able to scroll through a timer-series of photographs.
So far I've been able to make a Tkinter canvas displaying an image, and a Tkinter "Scale" slider, but I am having trouble combining them to meet my goal. The result of the below code is an empty canvas window and a separate slider. The slider works and prints its position when moved, but no photo ever loads. I was hoping that when the bar was moved to position 3, photo 3 would load.
Any idea what I'm missing?
import Tkinter as tk
from PIL import ImageTk, Image
from Tkinter import *
class ImageCanvas(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.canvas = Canvas(self, width=720, height=480, bd=0)
self.canvas.grid(row=0, column=0, sticky='nsew', padx=4, pady=4)
self.root = tk.Tk()
self._job = NONE
self.slider = tk.Scale(self.root, from_=0, to=3, orient = "horizontal", command=self.updateValue)
self.slider.pack()
self.root.mainloop()
def updateValue(self, event):
if self._job:
self.root.after_cancel(self._job)
self._job = self.root.after(500, self.result)
def result(self):
self._job=None
print self.slider.get()
returnedValue = self.slider.get()
class ImgTk(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.main = ImageCanvas(self)
self.main.grid(row=0, column=0, sticky='nsew')
self.c = self.main.canvas
self.currentImage = {}
self.load_imgfile(images[ImageCanvas.returnedValue()])
def load_imgfile(self, filename):
self.img = Image.open(filename)
self.currentImage['data'] = self.img
self.photo = ImageTk.PhotoImage(self.img)
self.c.xview_moveto(0)
self.c.yview_moveto(0)
self.c.create_image(0, 0, image=self.photo, anchor='nw', tags='img')
self.c.config(scrollregion=self.c.bbox('all'))
self.currentImage['photo'] = self.photo
images = ['/Users/Evan/Documents/Temp/4744.png', '/Users/Evan/Documents/Temp/4750.png', '/Users/Evan/Documents/Temp/4757.png']
app = ImgTk()
A couple suggestions may get you on the right track. Move the self.root.mainloop() out of the ImageCanvas class and put it at the end, after app = ImgTk(), as simply mainloop(), so it only get's called ones per instance of your app.
Also, ImageCanvas class doesn't have a method called returnedValue, and the result method doesn't return any value. So, add return returnedValue to the result method. Then ImageCanvas.returnedValue() would need to be ImageCanvas.result(), or you could just say self.main.result().
After making these changes, the first image displays, more work will need to be done to get the other images to load.

Image not displaying in Tkinter Label widget

I'm trying to get an image to display in a Tkinter Label widget. This code works inside a class in PyCharm, but doesn't get past the 'tk.Label' line in the main app. I've consulted other answers here but haven't been able to figure out why the image isn't displaying in the main app.
logo_filepath = "/Users/xxx/MASTER/pymol/Master/cache/logos/tmpbhWv2Ts.gif"
self.img = tk.PhotoImage(file = logo_filepath)
self.logo = tk.Label(self, image=self.img)
self.logo.photo = self.img
self.logo.grid(row=0, column=3, rowspan=10, columnspan=4)
It's a very simple error. Just make sure that you aren't defining self.[Your Variable] outside of a class. Because self is only available in classes. Also, Here's my code:
import Tkinter as tk
root = tk.Tk()
logo_filepath = "Your File Path..."
img = tk.PhotoImage(file = logo_filepath)
logo = tk.Label(root, image=img)
logo.photo = img
logo.grid(row=0, column=3, rowspan=10, columnspan=4)
tk.mainloop()

tkinter image button not working inside a function [duplicate]

I am trying to place two image buttons on my image background in a certain position, but my buttons are not appearing. I think their images are behind the background.
I tried to use place and pack, both did not work. What could be the problem?
from tkinter import*
import tkinter as tk
import settings
class Application(Frame):
def __init__ (self, master):
Frame.__init__(self,master)
self.grid()
self.create_widgets()
def create_widgets(self):
button1 = PhotoImage(file ="button1.gif")
button2 = PhotoImage(file ="button2.gif")
settings_button = Button(self, image = button1,
command = self.mult_command, width = 15)
settings_button.place(x=1, y=1)
rules_button = Button(self, image = button2,
command = self.the_rules, width = 15)
rules_button.place(x=50, y=50)
def main_code():
window = Tk()
window.title("The Bouncer")
bg_image = PhotoImage(file ="pic.gif")
x = Label (image = bg_image)
x.image = bg_image
x.place(x = 0, y = 0, relwidth=1, relheight=1)
window.geometry("600x300")
app = Application(window)
window.mainloop()
main_code()
thanks
It is likely that your image is being garbage collected before it is displayed. This is a common Tkinter gotcha. Try changing the lines:
button1 = PhotoImage(file ="button1.gif")
button2 = PhotoImage(file ="button2.gif")
to
self.button1 = PhotoImage(file ="button1.gif")
self.button2 = PhotoImage(file ="button2.gif")
and use
settings_button = Button(self, image = self.button1, command = self.mult_command, width = 15)
etc.
This should keep a reference to your image, stopping it from getting garbage collected.
In addition to keeping a reference to the image, you have a problem with this line:
self.grid()
in the __init__ method of Application. It's gridding the Frame into the window, but since nothing is ever packed or gridded into the frame, it doesn't ever expand past a little, tiny frame, so you just don't see the Buttons inside it. A simple fix here would be the pack method, with arguments to fill the window and expand when needed:
self.pack(fill=BOTH, expand=1)

Image in tkinter window by clicking on button

I need help about this program, this program should open image in new tkinter window by clicking on button, but it doesn't it just opens new window without image.
Where is the problem?
Using: python 3.3 and tkinter
This is program:
import sys
from tkinter import *
def button1():
novi = Toplevel()
canvas = Canvas(novi, width = 300, height = 200)
canvas.pack(expand = YES, fill = BOTH)
gif1 = PhotoImage(file = 'image.gif')
canvas.create_image(50, 10, visual = gif1, anchor = NW)
mGui = Tk()
button1 = Button(mGui,text ='Sklop',command = button1, height=5, width=20).pack()
mGui.mainloop()
create_image needs a image argument, not visual to use the image, so instead of visual = gif1, you need image = gif1. The next problem is that you need to store the gif1 reference somewhere or else it'll get garbage collected and tkinter won't be able to use it anymore.
So something like this:
import sys
from tkinter import * #or Tkinter if you're on Python2.7
def button1():
novi = Toplevel()
canvas = Canvas(novi, width = 300, height = 200)
canvas.pack(expand = YES, fill = BOTH)
gif1 = PhotoImage(file = 'image.gif')
#image not visual
canvas.create_image(50, 10, image = gif1, anchor = NW)
#assigned the gif1 to the canvas object
canvas.gif1 = gif1
mGui = Tk()
button1 = Button(mGui,text ='Sklop',command = button1, height=5, width=20).pack()
mGui.mainloop()
It's also probably not a good idea to name your Button the same name as the function button1, that'll just cause confusion later on.
from tkinter import *
root = Tk()
root.title("Creater window")
def Img():
r = Toplevel()
r.title("My image")
canvas = Canvas(r, height=600, width=600)
canvas.pack()
my_image = PhotoImage(file='C:\\Python34\\Lib\idlelib\\Icons\\Baba.gif', master= root)
canvas.create_image(0, 0, anchor=NW, image=my_image)
r.mainloop()
btn = Button(root, text = "Click Here to see creator Image", command = Img)
btn.grid(row = 0, column = 0)
root.mainloop()

Categories