I have a small tkinter GUI, which just contains an image of a thermostat. I have an image for each temperature to make a little animation of the temperature increasing. I have got this working to the point where it loops through all the images succesfully, however after the last image is displayed it just disappears. Here is my code so far
#!/usr/bin/python3
import tkinter as tk
from PIL import ImageTk, Image
import time
root = tk.Tk()
root.geometry("1280x720")
root.configure(background='white')
def loopTemp(maxTemp):
for x in range(0, maxTemp + 1):
if x < 22:
thermostat = ImageTk.PhotoImage(Image.open("thermo_"+str(x)+".png"))
panel.configure(image = thermostat)
panel.configure(text = str(x))
root.update_idletasks()
time.sleep(0.07)
light = ImageTk.PhotoImage(Image.open("light-on.png"))
thermostat = ImageTk.PhotoImage(Image.open("thermo_0.png"))
B = tk.Button(root, text ="Start", command= lambda: loopTemp(21))
panel = tk.Label(root, image = thermostat, text="0", compound=tk.CENTER, font=("Helvetica", 60), fg="white")
panel.configure(background='white')
B.pack()
panel.pack(side=tk.LEFT, fill = "both", expand = "yes")
root.mainloop()
Replace:
...
thermostat = ImageTk.PhotoImage(...)
panel.configure(image = thermostat)
...
with:
...
panel.img = ImageTk.PhotoImage(...)
panel.configure(image = panel.img)
...
In order to keep the reference of the image object wherever panel exists, thus have a consistent image display like suggested in the comment here.
Related
So I am doing my first programming class this semester and for our exam I am creating this very basic Lightroom clone.
I am using opencv for the image processing and Tkinter as GUI. Everything kind of works so far, but I am struggling to hide the main menu (Tkinter GUI) when the image is opened (OpenCV GUI).
I want to call the .withdraw method for the TKinter root window from the innit function of the image processing class. Image opens -> Menu hides. I think these pictures might help:
Here the GUI initializes
from tkinter import *
import Panels
def createpanels(amount=10):
img1 = "thumbnail.jpg"
for i in range(0, amount):
Panel = (Panels.Panel("Image A", img1, i + 1, 5))
button_edit = Button(window, text="Bild Bearbeiten", command=Panel.showpath)
button_edit.grid(column=i + 1, row=6, pady = 10)
def hidegui():
window.withdraw()
def showgui():
window.deiconify()
if __name__ == "__main__":
window = Tk()
window.title("File Explorer")
window.config(background="white")
current_value = tk.DoubleVar()
createpanels()
button_exit = Button(window, text = "Exit", command = exit)
button_exit.grid(column=11, row=5, padx=10, pady=10)
window.mainloop()
Here I am trying to call the withdraw method
from tkinter import *
from tkinter import messagebox
import TkinterGUI as gui
import Filter
import Goldencut as g
from PIL import Image
import Filter as f
class Image:
counter = 0
def __init__(self, path):
self.path = path
self.img = cv.imread(self.path)
self.imgcopy = self.img.copy()
self.gc = self.img.copy()
cv.namedWindow("Image", cv.WINDOW_NORMAL)
cv.namedWindow("Controlls", cv.WINDOW_NORMAL)
gui.hidegui()
Unfortunately this is not working and I get this error message:
Error
I am pretty sure this is an absolute beginner mistake and easy to fix, but I just can't fix it myself. Any help very appreciated :)
window = Tk() use outside of function like this
here is the complete code because you are calling an undefined class name
from tkinter import *
import Panels
window = Tk() # use here
def createpanels(amount=10):
img1 = "thumbnail.jpg"
for i in range(0, amount):
Panel = (Panels.Panel("Image A", img1, i + 1, 5))
button_edit = Button(window, text="Bild Bearbeiten", command=Panel.showpath)
button_edit.grid(column=i + 1, row=6, pady = 10)
def hidegui():
window.withdraw()
def showgui():
window.deiconify()
if __name__ == "__main__":
window.title("File Explorer")
window.config(background="white")
current_value = tk.DoubleVar()
createpanels()
button_exit = Button(window, text = "Exit", command = exit)
button_exit.grid(column=11, row=5, padx=10, pady=10)
window.mainloop()
i wrote this code on the school computer, and it was totally fine. i wrote the same code on my personal pc and now it shows the picture with no transparency (with black background). the picture is the same picture(a png with no background)
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
root.geometry("1300x731")
root.resizable(width=False, height=False)
photo = Image.open("logo.png")
zoom = 0.5
pixels_x, pixels_y = tuple([int(zoom * x) for x in photo.size])
img = ImageTk.PhotoImage(photo.resize((pixels_x, pixels_y)))
panel = Label(root, image = img).place(relx = 0.5, rely = 0.1, anchor = 'center')
#panel.grid(row=5000, column=3)
#panel.pack(side = "bottom", fill = "both", expand = "yes")
root.config(cursor="#curs.cur")
while True:
root.mainloop()
try it with another import method.
use photo = PhotoImage(file="logo.png")
this should remove the black background.
Remove the "while True:"
root.mainloop() is a loop by itself
I want to change the image of the one labels in time with 2 other images but it immideatly skipts to the last one. Any suggestions?
I have tried using time.sleep incase it might happen so fast that before i could notice but it didnt work.
import tkinter
from tkinter import *
from PIL import Image , ImageTk
import time
window = tkinter.Tk()
window.geometry("500x500")
window.title("Pomodoro Timer")
window.image_1 = ImageTk.PhotoImage(Image.open("1.jpg"))
window.image_2 = ImageTk.PhotoImage(Image.open("2.jpg"))
window.image_3 = ImageTk.PhotoImage(Image.open("3.jpg"))
lbl_1 = tkinter.Label(window, image=window.image_1)
lbl_1.place(x=150,y=100)
lbl_2 = tkinter.Label(window, image=window.image_2)
lbl_2.place(x=200,y=100)
def display_numbers():
lbl_1
lbl_2
display_numbers()
def clicked():
i=1
while i<3:
if i==1:
lbl_1.configure(image=window.image_2)
time.sleep(0.91)
i += 1
elif i==2:
lbl_1.configure(image=window.image_3)
time.sleep(0.91)
i += 1
btn = tkinter.Button(window, text="Start", command=clicked)
btn.place(x=200,y=450,width=100)
window.mainloop()
This is my code in Tkinter. I tried to show buttons with the image when I select the grid size in tkinter UI. My problem is that when I go to put an image inside a button, it does not display it. List grid2 already have images with using the shuffle method.
Any help is appreciated.
import tkinter
import tkinter.ttk
import random
def startButton():
global my_list, roundNum, tmp_list, startTime
grid_size = combobox1.get()[0]
roundNum = combobox2.get()[0]
gridActorList(my_list)
imageUpdate()
startTime=time.time()
def imageUpdate():
global grid_size
t = []
if grid_size == 2:
photo_1 = tkinter.PhotoImage(file="picture/"+grid2[0]+".png")
photo_2 = tkinter.PhotoImage(file="picture/"+grid2[1]+".png")
photo_3 = tkinter.PhotoImage(file="picture/"+grid2[2]+".png")
photo_4 = tkinter.PhotoImage(file="picture/"+grid2[3]+".png")
for k in range(1,5):
t.append(tkinter.Button(window, image=photo_+str(k)))
for i in range(0,4):
t[i].pack()
window = tkinter.Tk()
window.title('Finding different picture!')
window.geometry('500x400')
#combobox
values1=[str(i)+"x"+str(i) for i in range(2,6)] #grid size
values2=[str(j)+"times" for j in range(1,10,2)] #play time size
combobox1=tkinter.ttk.Combobox(window, height=5, width=15, values=values1,
justify='center', takefocus=True )
combobox2=tkinter.ttk.Combobox(window, height=5, width=15, values=values2,
justify='center', takefocus=True )
combobox1.set("select size")
combobox2.set("select times")
combobox1.place(x=15, y=15)
combobox2.place(x=155, y=15)
#startButton
startBtn = tkinter.Button(window, text='start', command=startButton)
startBtn.place(x=300, y=15)
#variables
my_list = []
roundNnum = 0
window.mainloop()
I've tried to minimize the code. If there are more codes required, I'll edit it.
Your code does not run. This makes it hard to debug. But I can see that you're not saving references to the images you put in the buttons.
As the images are created inside a function they will be garbage collected when the function exits. Fix this by saving a reference to the image with the button widget. Examine the example below:
import tkinter as tk
def create_button():
photo = tk.PhotoImage(file="images/gilliam.png")
image_button = tk.Button(window, image=photo)
image_button.image = photo # Save a reference to the image
image_button.pack()
window = tk.Tk()
create_button()
window.mainloop()
I wrote an Arduino code which reacts to buttons and physical interactions and then send the results to the computer on which my python program (2.7) is running.
The python code has two functions:
Create a new text file named after the unixtimestamp and fill it
with all the data it receives.
Look through the data it receives for the code phrases "a1" and "b1"
and then show the corresponding image.
When the Arduino starts it will send the "a1" as a first value to fill the window. After that, it should switch based on the data it sends.
This is my current code:
from Tkinter import *
from random import *
import serial
import time
root = Tk()
prompt = StringVar()
root.title("vision")
label = Label(root, fg="dark green")
label.pack()
frame = Frame(root,background='red')
frame.pack()
canvas = Canvas(height=200,width=200)
canvas.pack()
timestamp = int(time.time())
filename=str(timestamp)+".txt"
f = open(str(filename),"w")
f.write("\n")
f.write(str(filename))
f.write("\n")
arduino = serial.Serial('COM5', 115200, timeout=.1)
while True:
data = arduino.readline()[:-2] #the last bit gets rid of the new-line chars
print data
f.write(str(data))
f.write("\n")
#Invoking through button
TextWindow = Label(frame,anchor = NW, justify = LEFT, bg= 'white', fg = 'blue', textvariable = prompt, width = 75, height=20)
TextWindow.pack(side = TOP)
if data == "a1":
canvas.delete("all")
image1 = PhotoImage(file = "c2.gif")
canvas.create_image(0,0,anchor='nw',image=image1)
canvas.image = image1
if data == "b1":
canvas.delete("all")
image1 = PhotoImage(file = "c2.gif")
canvas.create_image(0,0,anchor='nw',image=image1)
canvas.image = image1
root.mainloop()
It generates the window but it is empty.
I can not seem to find where my error is.
Additionaly:
I used an other tutorial wich gave me he basic code for the gui and images. In this there are two buttons wich switch the images which works.
from Tkinter import *
from random import *
pathy = randint(1, 2)
root = Tk()
prompt = StringVar()
root.title("vision")
label = Label(root, fg="dark green")
label.pack()
frame = Frame(root,background='red')
frame.pack()
canvas = Canvas(height=200,width=200)
canvas.pack()
def Image1():
canvas.delete("all")
image1 = PhotoImage(file = "c2.gif")
canvas.create_image(0,0,anchor='nw',image=image1)
canvas.image = image1
def Image2():
canvas.delete("all")
image1 = PhotoImage(file = "c1.gif")
canvas.create_image(0,0,anchor='nw',image=image1)
canvas.image = image1
TextWindow = Label(frame,anchor = NW, justify = LEFT, bg= 'white', fg = 'blue', textvariable = prompt, width = 75, height=20)
TextWindow.pack(side = TOP)
conversationbutton = Button(frame, text='right button',width=25,fg="green",command = Image1)
conversationbutton.pack(side = RIGHT)
stopbutton = Button(frame, text='left button',width=25,fg="red",command = Image2)
stopbutton.pack(side = RIGHT)
root.mainloop()
Once the mainloop() function has been called you have to use callbacks in order to run your own code. The Tkinter after() method can be used to run a section of code after a set amount of time.
In your case your code would look something like:
def update():
#your code here
root.after(1000, update)
update()
root.mainloop()
Calling root.after() inside of the update functions allows the function to keep running until the window is closed.
The after method as described at effbot gives the arguments as:
root.after(milliseconds, callback)
In your case you might have to call your processing code more often then every second.