英文:
Tkinter error: image "pyimage2" doesn't exist working with classes and frames
问题
我正在使用tkinter上的类,并且遇到了这个问题:
错误追踪(最近的调用在最上面):
- File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\tkinter_init_.py",第1921行,在__call__中:
返回self.func(*args) - File "D:\PYCHARM\pycharmprojects\lumacol_frontend\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py",第549行,在_clicked中:
self._command() - File "D:\PYCHARM\pycharmprojects\lumacol_frontend\input_frame.py",第88行,在go_back中:
from main import SerialFrame - File "D:\PYCHARM\pycharmprojects\lumacol_frontend\main.py",第126行,在
中:
SerialFrame(root).place(x=25, y=50) - File "D:\PYCHARM\pycharmprojects\lumacol_frontend\main.py",第20行,在__init__中:
self.createWidgetsMain() - File "D:\PYCHARM\pycharmprojects\lumacol_frontend\main.py",第101行,在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",第106行,在__init__中:
self._draw() - File "D:\PYCHARM\pycharmprojects\lumacol_frontend\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py",第261行,在_draw中:
self._update_image() # set image - File "D:\PYCHARM\pycharmprojects\lumacol_frontend\venv\lib\site-packages\customtkinter\windows\widgets\ctk_button.py",第172行,在_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",第1675行,在configure中:
返回self._configure('configure', cnf, kw) - File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2544.0_x64__qbz5n2kfra8p0\lib\tkinter_init_.py",第1665行,在_configure中:
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) - _tkinter.TclError: 图像"pyimage2"不存在
这是我的应用程序代码以及关于它应该如何工作的解释:
首先,我有一个包含SerialFrame类、窗口和框架创建的文件:
class SerialFrame(customtkinter.CTkFrame):
# 框架的构造函数
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()
# 创建所有小部件的方法
def createWidgetsMain(self):
...
# 创建应用程序
root = customtkinter.CTk()
root.geometry("700x500")
root.title("Lumalcol Conf")
back = backend.MyAppBackend()
# 创建第一个框架,调用MyApp类
SerialFrame(root).place(x=25, y=50)
root.mainloop()
我还有另外两个文件,其中包含其他不同类的帧,以类似的方式创建。
问题是当我按按钮返回到第一个帧时,这里是其他类中的代码:
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="返回",
command=go_back, cursor="hand2")
btn_back.place(x=465, y=400)
显然,在编写应用程序时,我遇到了许多不同的问题,如果你看到有什么不正常的地方,请告诉我。
我认为问题可能出在这里。这段代码在主文件的createWidgetsMain
方法和SerialFrame
类中:
my_image = customtkinter.CTkImage(light_image=Image.open("images/refresh.png"),
dark_image=Image.open("images/refresh.png"),
size=(20, 20))
# 创建刷新按钮
refresh_serials = customtkinter.CTkButton(master=self, command=refresh_menu, image=my_image, width=20, text="")
我认为当我按下"返回"按钮时,应该创建一个SerialFrame
类的新对象并将其放置在root
中。显然,当我创建其他帧时,我始终将root
传递给它们。
这是用于创建其他类的按钮的代码(它位于createWidgedsMain
方法中):
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)
整个应用程序都运行正常,我唯一的问题是"返回"按钮,谢谢。
英文:
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
答案1
得分: 0
由于你在 main.py
中有以下代码:
...
# 创建应用程序
root = customtkinter.CTk()
root.geometry("700x500")
root.title("Lumalcol Conf")
back = backend.MyAppBackend()
# 创建第一个框架,调用MY APP类
SerialFrame(root).place(x=25, y=50)
root.mainloop()
所以当在 go_back()
中执行 from main import SerialFrame
这一行时,会创建另一个 customtkinter.CTk()
的实例,导致异常。
你需要将代码块放在一个 if __name__ == "__main__"
块中,如下所示:
...
if __name__ == "__main__":
# 创建应用程序
root = customtkinter.CTk()
root.geometry("700x500")
root.title("Lumalcol Conf")
# 创建第一个框架,调用MY APP类
SerialFrame(root).place(x=25, y=50)
root.mainloop()
然后当导入 main
时,该代码块将不会被执行。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论