Я создаю приложение, которое сочетает в себе графический интерфейс Tkinter и веб-утилизацию. Функция search_window использует два потока: один для длинного процесса (процесс очистки веб-страниц) и один для GUI. В графическом интерфейсе я смоделировал GIF, используя холст и 24 кадра GIF. Я думаю, что проблема, с которой я сталкиваюсь, заключается в удалении всех изображений, созданных на холсте, после долгого процесса, потому что я получаю 24 разных ошибки, точное количество изображений при их удалении. Или, может быть, это потому, что я использую тему для Tkinter? Но ошибки появляются не сразу, я могу пойти и использовать следующее окно графического интерфейса, и после закрытия каждого окна Tkinter появляются ошибки.
def prev_window():
root = Tk()
root.mainloop()
def next_window():
root = Tk()
root.mainloop()
def searching_window(settings):
def long_process(settings):
...
def app(settings):
def event_gif(n=0):
global timer_id
gif = giflist[n%len(giflist)]
canvas.create_image(gif.width()//2, gif.height()//2, image=gif)
if t1.is_alive():
timer_id = root.after(100, event_gif, n+1)
else:
canvas.delete(ALL)
root.after_cancel(timer_id)
canvas.place_forget()
img_done.place(x=335, y=30)
lbl_done.place(x=330, y=183)
after = utils.number_html_files()
lbl_found.configure(text="I found {} items.".format(after-before))
lbl_found.place(x=217, y=205)
def event_btn(event):
if not t1.is_alive():
root.destroy()
if utils.number_html_files() != 0:
next_window()
gifpath = datapath + "gif"
_ = ["frame_{}.png".format(i) for i in range(1, 25)]
imgfn = "checked.png"
global timer_id
timer_id = "after#0"
before = utils.number_html_files()
root = Tk()
root.geometry("650x300+100+100")
root.title("Searching...")
font = Font(family="Times New Roman", size=15)
font2 = Font(family="Times New Roman", size=12)
background = Label(root, image=smallbackground)
background.image = smallbackground
__ = PhotoImage(file="{}{}".format(gifpath, _[0]))
canvas = Canvas(root, width=300, height=198)
giflist = []
for img in _:
photo = PhotoImage(file="{}{}".format(gifpath, img))
giflist.append(photo)
img_done = Label(root, image=imgfn)
img_done.image = imgfn
lbl_done = Label(root, text="Done!", font=font)
lbl_found = Label(root, font=font, text="I found {} items.")
btn_done = Button(root, text="Continue", font=font)
btn_done.bind("<Button-1>", event_btn)
background.place(x=-1, y=-1)
canvas.place(x=258, y=30)
btn_done.place(x=343, y=235)
root.after(100, event_gif)
root.mainloop()
t1 = threading.Thread(target=long_process, args=[settings])
t2 = threading.Thread(target=app, args=[settings])
t2.start()
t1.start()
t2.join()
t1.join()
Вот ошибки:
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f0b8>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f0f0>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f128>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f160>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f198>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f1d0>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f208>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f240>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f278>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f2b0>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f2e8>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f320>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f358>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f390>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f3c8>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f400>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f438>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f470>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f4a8>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f4e0>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f518>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f550>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f588>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Image.__del__ of <tkinter.PhotoImage object at 0x7fc45c92f5c0>>
Traceback (most recent call last):
File "/usr/lib/python3.6/tkinter/__init__.py", line 3507, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Tcl_AsyncDelete: async handler deleted by the wrong thread
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
РЕДАКТИРОВАТЬ: я исправил ошибку, переместив создание корня и основной цикл туда, где определены потоки, и удалив последнее изображение холста перед созданием нового:
def prev_window():
root = Tk()
root.mainloop()
def next_window():
root = Tk()
root.mainloop()
def searching_window(settings):
def long_process(settings):
...
def app(settings):
def event_gif(n=0):
global timer_id
gif = giflist[n%len(giflist)]
canvas.delete(ALL)
canvas.create_image(gif.width()//2, gif.height()//2, image=gif)
if t1.is_alive():
timer_id = root.after(100, event_gif, n+1)
else:
canvas.delete(ALL)
root.after_cancel(timer_id)
canvas.place_forget()
img_done.place(x=335, y=30)
lbl_done.place(x=330, y=183)
after = utils.number_html_files()
lbl_found.configure(text="I found {} items.".format(after-before))
lbl_found.place(x=217, y=205)
def event_btn(event):
if not t1.is_alive():
root.destroy()
if utils.number_html_files() != 0:
next_window()
gifpath = datapath + "gif"
_ = ["frame_{}.png".format(i) for i in range(1, 25)]
imgfn = "checked.png"
global timer_id
timer_id = "after#0"
before = utils.number_html_files()
font = Font(family="Times New Roman", size=15)
font2 = Font(family="Times New Roman", size=12)
background = Label(root, image=smallbackground)
background.image = smallbackground
__ = PhotoImage(file="{}{}".format(gifpath, _[0]))
canvas = Canvas(root, width=300, height=198)
giflist = []
for img in _:
photo = PhotoImage(file="{}{}".format(gifpath, img))
giflist.append(photo)
img_done = Label(root, image=imgfn)
img_done.image = imgfn
lbl_done = Label(root, text="Done!", font=font)
lbl_found = Label(root, font=font, text="I found {} items.")
btn_done = Button(root, text="Continue", font=font)
btn_done.bind("<Button-1>", event_btn)
background.place(x=-1, y=-1)
canvas.place(x=258, y=30)
btn_done.place(x=343, y=235)
root.after(100, event_gif)
root = Tk()
root.geometry("650x300+100+100")
root.title("Searching...")
t1 = threading.Thread(target=long_process, args=[settings])
t2 = threading.Thread(target=app, args=[settings])
t2.start()
t1.start()
root.mainloop()
t2.join()
t1.join()