Label error in tkinter while exiting window - python

I am trying to make a digital clock through python tkinter .My code is
import tkinter,time
def exiter():
root.destroy()
root=tkinter.Tk()
root.title("Digital Clock")
root.geometry("340x100")
root.resizable(False,False)
root.protocol("WM_DELETE_WINDOW",exiter)
def time_setter():
hr=tkinter.Label(root,font=('k',60,'bold'),text=time.strftime("%H:%M:%S"))
hr.grid(row=0,column=0)
while True:
root.update()
time_setter()
After I close the window I get an error
Traceback (most recent call last):
File "c:\Users\Tanmay Daga\OneDrive\Documents\Programming\Clock-Tkinter\digital_clock.py", line 20, in <module>
time_setter()
File "c:\Users\Tanmay Daga\OneDrive\Documents\Programming\Clock-Tkinter\digital_clock.py", line 13, in time_setter
hr=tkinter.Label(root,font=('k',60,'bold'),text=time.strftime("%H:%M:%S"))
File "C:\Program Files\Python39-32\lib\tkinter\__init__.py", line 3145, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Program Files\Python39-32\lib\tkinter\__init__.py", line 2569, in __init__
self.tk.call(
_tkinter.TclError: can't invoke "label" command: application has been destroyed
How do I break the loop when the window is closed.
How do I know when the window is closed

from tkinter import *
from time import strftime
def clock_tick():
string = strftime('%H:%M:%S %p')
lbl.config(text=string)#set the text
lbl.after(1000, time)#updater
root=Tk()
lbl = Label(root, font=('calibri', 40, 'bold'),
background='purple',
foreground='white')
lbl.pack(anchor = 'center')
clock_tick()
root.title("Digital Clock")
root.geometry("340x100")
root.resizable(False,False)
root.mainloop() #this is the loop you are looking for instead of the while loop
The loop is wrong. For tkinter there is a built in loop that is much better to use. Exiting this with the X will provide a clean exit if you set the loop up by using root.mainloop(). Here is a good example of what you are trying to do
https://www.geeksforgeeks.org/python-create-a-digital-clock-using-tkinter/

Related

Tkinter error: image "pyimage2" doesn't exist working with classes and frames

i'm working with classes on tkinter and i have this problem:
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 549, in _clicked
self._command()
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\input_frame.py", line 88, in go_back
from main import SerialFrame
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\main.py", line 126, in <module>
SerialFrame(root).place(x=25, y=50)
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\main.py", line 20, in __init__
self.createWidgetsMain()
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\main.py", line 101, in createWidgetsMain
refresh_serials = customtkinter.CTkButton(master=self, command=refresh_menu, image=my_image, width=20,
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 106, in __init__
self._draw()
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 261, in _draw
self._update_image() # set image
File "D:\PYCHARM\pycharmprojects\lumacol_frontend\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 172, in _update_image
self._image_label.configure(image=self._image.create_scaled_photo_image(self._get_widget_scaling(),
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1675, in configure
return self._configure('configure', cnf, kw)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1665, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage2" doesn't exist
This is the code on my application and explanation about how it should work:
First of all, i have a file with the class SerialFrame, and the creation of the window and the frame:
class SerialFrame(customtkinter.CTkFrame):
# CONSTRUCTOR FOR THE FRAME
def __init__(self, master, *args, **kwargs):
super(SerialFrame, self).__init__(master)
self.master = master
self.serial_port = ""
self.configure(width=400, height=400)
self.createWidgetsMain()
# METHOD TO CREATE ALL WIDGETS
def createWidgetsMain(self):
...
# CREATING THE APP
root = customtkinter.CTk()
root.geometry("700x500")
root.title("Lumalcol Conf")
back = backend.MyAppBackend()
# CREATING THE FIRST FRAME CALLING THE CLASS MY APP
SerialFrame(root).place(x=25, y=50)
root.mainloop()
And i have another 2 files with other diferent classes for other frames in similar way.
The problem is when i press a button to go back to the first frame, here is the code in the other classes:
def go_back():
self.destroy()
btn_back.destroy()
from main import SerialFrame
SerialFrame(self.master).place(x=25, y=50)
btn_back = customtkinter.CTkButton(self.master, text="Go Back",
command=go_back, cursor="hand2")
btn_back.place(x=465, y=400)
Obviously, while coding the app i had many different problems and if you see something that shouldn't be work well, you can tell me.
I think that probably the error would come here. This code is on def createWidgetsMain, on the main file, and the SerialFrame class.
my_image = customtkinter.CTkImage(light_image=Image.open("images/refresh.png"),
dark_image=Image.open("images/refresh.png"),
size=(20, 20))
# CREATE REFRESH BUTTON
refresh_serials = customtkinter.CTkButton(master=self, command=refresh_menu, image=my_image, width=20,
text="")
I think that when i press the go_back button, on the other classes, it should create a new object of SerialFrame class and place in the root.
Obviously, when i create the other frames, i always send the root, the Tk().
Here is the code of the button to go create the other classes (it's inside the createWidgedsMain method):
def segmented_button_callback(value):
if value == "Inputs":
self.destroy()
input_frame.InputFrame(self.master, back).place(x=75, y=75)
if value == "Menu":
try:
connection = back.get_connection()
self.destroy()
menu_frame.MenuFrame(self.master, back).place(x=25, y=75)
except:
self.destroy()
SerialFrame(self.master).place(x=25, y=50)
segemented_button = customtkinter.CTkSegmentedButton(master=self,
values=["Menu", "Inputs"],
command=segmented_button_callback)
All application works well, my only problem is that, thank you.
Here are some pics of the app
Since you have the following code inside main.py:
...
# CREATING THE APP
root = customtkinter.CTk()
root.geometry("700x500")
root.title("Lumalcol Conf")
back = backend.MyAppBackend()
# CREATING THE FIRST FRAME CALLING THE CLASS MY APP
SerialFrame(root).place(x=25, y=50)
root.mainloop()
So when the line from main import SerialFrame inside go_back() is executed, another instance of customtkinter.CTk() will be created which causes the exception.
You need to put the code block inside a if __name__ == "__main__" block as below:
...
if __name__ == "__main__":
# CREATING THE APP
root = customtkinter.CTk()
root.geometry("700x500")
root.title("Lumalcol Conf")
# CREATING THE FIRST FRAME CALLING THE CLASS MY APP
SerialFrame(root).place(x=25, y=50)
root.mainloop()
Then the code block will not be executed when main is imported.

Python tkinter giving me an error when I try to set me logo (GUI WINDOW)

When I try to add an image and set it as my GUI window logo it gives me these errors
Traceback (most recent call last):
File "C:\Users\Meina Jia\PycharmProjects\guwindow\main.py", line 7, in <module>
icon = PhotoImage(file='logo.jpg')
File "C:\Users\Meina Jia\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 4093, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Users\Meina Jia\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 4038, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't recognize data in image file "logo.jpg"
Process finished with exit code 1
I already changed the file type using code.
from tkinter import *
window = Tk()
window.geometry("420x420")
window.title("Backrooms in A Nutshell")
icon = PhotoImage(file='logo.jpg')
window.iconphoto(True, icon)
window.mainloop()
For this, you will need the Pillow Library.
import tkinter as tk
from PIL import ImageTk, Image
window = tk.Tk()
window.geometry("420x420")
window.title("Backrooms in A Nutshell")
icon = ImageTk.PhotoImage(Image.open('logo.jpg'))
window.iconphoto(True, icon)
window.mainloop()
Note: It is good practice to import a library directly:
Run
import tkinter
instead of
from tkinter import *

(Python tkinter): RuntimeError: main thread is not in main loop

I coded a python GUI program with tkinter that displays a label wherein its text changes every 0.25 seconds, according to the chronology of the list in the variable 'loadings'. I made it work by putting the function as a thread. Otherwise, it would not work. The code works perfectly as intended. However, every time i close the program, a RuntimeError appears and i do not know what the problem is. I searched on the internet for the error but none of what i have found are related to tkinter at all.
code:
from tkinter import *
import threading, time
root = Tk()
loading_label = Label(root)
loading_label.pack()
loadings = ['loading', 'loading.', 'loading..', 'loading...']
def loadingscreen():
while True:
for loading in loadings:
loading_label.config(text=loading)
time.sleep(0.25)
loadingthread = threading.Thread(target=loadingscreen)
loadingthread.start()
root.mainloop()
error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/HP/PycharmProjects/myfirstproject/threadingtest.py", line 14, in loadingscreen
loading_label.config(text=loading)
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1637, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1627, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
RuntimeError: main thread is not in main loop
Process finished with exit code 0
The reason is that u have used the Threading in the Tkinter loop which I guess we shouldn't.
Safe play is to use after. so Custom label can help us in this case
from tkinter import *
import threading, time
import sys
root = Tk()
class Custom(Label):
def __init__(self,parent,lst):
super().__init__(parent)
self['text']=lst[0]
self.marker=0
self.lst=lst[:]
self.note=len(lst)
self.after(250,self.change)
def change(self):
if self.marker>=self.note:self.marker=0
self['text']=self.lst[self.marker]
self.marker+=1
self.after(250,self.change)
loadings = ['loading', 'loading.', 'loading..', 'loading...']
loading_label = Custom(root,loadings)
loading_label.pack()
# destroy it whenever u want
root.mainloop()

I am just trying to show an image in a GUI. What am I doing wrong?

I am trying to display an image in a GUI, and don't understand what is wrong. I keep getting this error:
AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
What should my code (especially the line with my_img=...) look like?
My Code:
from tkinter import *
from PIL import ImageTk,Image
my_img = ImageTk.PhotoImage(Image.open("iu.jpeg"))
my_label = Label(image=my_img)
my_label.pack()
root = Tk()
root.title("ICON PRACTICE")
root.iconbitmap('iu.ico')
button_quit = Button(root, text = "EXIT", command=root.quit)
button_quit.pack()
root.mainloop()
The full error
Traceback (most recent call last):
File "main.py", line 4, in <module>
my_img = ImageTk.PhotoImage(Image.open("test.png"))
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/PIL/ImageTk.py", line 112, in __init__
self.__photo = tkinter.PhotoImage(**kw)
File "/usr/lib/python3.8/tkinter/__init__.py", line 4064, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "/usr/lib/python3.8/tkinter/__init__.py", line 3997, in __init__
raise RuntimeError('Too early to create image')
RuntimeError: Too early to create image
Exception ignored in: <function PhotoImage.__del__ at 0x7f7148fadc10>
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/PIL/ImageTk.py", line 118, in __del__
name = self.__photo.name
AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
Try doing this, its probably because you create the root object after opening the image and creating the photo object.
import os
from tkinter import *
from PIL import ImageTk,Image
root= Tk()
i = Image.open("C:/path/to/the/image/directory/image.png")
photo = ImageTk.PhotoImage(i)
root.mainloop()
The Label widget will only work after root = Tk() (Tk() starts the underlying Tcl interpreter) is declared. Then, all child widgets must have root as their first parameter (e.g., Label(root, text='hi')). You started the interpreter after you tried to use it, so Python raised an exception.

Binding a Color to a Button in Tkinter Results in a TclError

I am currently trying to implement code into my program to update a buttons color when the user hovers the mouse cursor over it. The program recognizes the hover, but returns an error.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1482, in __call__
return self.func(*args)
File "C:\Users\oiest\Documents\Programs\iNTMI\v1.1.3b\iNTMI.py", line 252, in <lambda>
achievementsButton.bind("<Enter>", lambda event: achievementsButton.configure(bg = "red"))
File "C:\Python34\lib\tkinter\__init__.py", line 1270, in configure
return self._configure('configure', cnf, kw)
File "C:\Python34\lib\tkinter\__init__.py", line 1261, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: unknown option "-bg"
I had Googled how to do the changing of colors when hovering and found the following code. Though for some reason, it does not work for me. What am I doing wrong?
achievementsButton.bind("<Enter>", lambda event: achievementsButton.configure(bg = "red"))
achievementsButton.bind("<Leave>", lambda event: achievementsButton.configure(bg = "white"))
This is the code from where I originally defined achievementsButton.
achievementsButton = ttk.Button(self, text = "Achievements", command = lambda: controller.show_frame(achievements), width = "25")
ttk.Button instances do not have a bg or background attribute. There are two solutions:
Use an ordinary tkinter.Button, which does have a bg attribute.
Keep using the ttk.Button, and configure it using a style object. See Using and customizing ttk styles for more information. Example:
from Tkinter import *
import ttk
root = Tk()
s = ttk.Style()
s.configure("regular.TButton", background="red")
s.configure("onhover.TButton", background="white")
button = ttk.Button(root, style="regular.TButton")
button.pack()
button.bind("<Enter>", lambda event: button.configure(style="onhover.TButton"))
button.bind("<Leave>", lambda event: button.configure(style="regular.TButton"))
root.mainloop()
However, this will only change the background color of the area behind the actual button, rather than the button's face. This
post seems to indicate that it's impossible to change the face color of a ttk Button.

Categories

Resources