Tk Как закрыть окно в процессе цикла другого потока и удалить файл

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
У меня есть код:
Python:
from tkinter import *
import os
b = 0
files = ["file"]

def func(thread_number=[0]):
    local_thread_number = thread_number[0]
    thread_number[0] += 1

    root1 = Toplevel(root)
    root1.state('zoomed')
    text_vidget1 = scrolledtext.ScrolledText(root1, width = 200, height = 100, state=DISABLED )
    text_vidget1.pack()
    for i, item in enumerate(files):
        b += 1
        os.remove(filename)
        text_vidget = scrolledtext.ScrolledText(root1, width = 120, height = 20)
        text_vidget1.window_create(INSERT, window=text_vidget)
        text_vidget.insert(1.0,b)
def my_thread():
    # вызов потока
    global thread1, thread2
    thread1 = threading.Thread(target = func, name = "Thread-1")
    thread1.start()

root = Tk()
btn = Button(text = "click me", command = my_thread).pack()
root.mainloop()
Пользователь должен закрыть окно "root" или "root1" в момент работы цикла но нужно чтобы обязательно удалился файл если он уже создался но не удалился в самом цикле. Я пробовал ловить протокол закрытия с функцией удаления файла и закрытия окна, но у меня выходила ошибка.
 
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Я пробовал ловить протокол закрытия с функцией удаления файла и закрытия окна, но у меня выходила ошибка.
Покажите как пробовали и какая ошибка.
 

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
Python:
from tkinter import *
import os
b = 0
files = ["file"]

def func(thread_number=[0]):
    local_thread_number = thread_number[0]
    thread_number[0] += 1

    root1 = Toplevel(root)
    root1.protocol("WM_DELETE_WINDOW",destroy_window)
    root1.state('zoomed')
    text_vidget1 = scrolledtext.ScrolledText(root1, width = 200, height = 100, state=DISABLED )
    text_vidget1.pack()
    for i, item in enumerate(files):
        b += 1
        os.remove(filename)
        text_vidget = scrolledtext.ScrolledText(root1, width = 120, height = 20)
        text_vidget1.window_create(INSERT, window=text_vidget)
        text_vidget.insert(1.0,b)
def destroy_window():
    if filename_img != "":
        os.remove(filename_img)
    root1.destroy()
def my_thread():
    # вызов потока
    global thread1, thread2
    thread1 = threading.Thread(target = func, name = "Thread-1")
    thread1.start()

root = Tk()
btn = Button(text = "click me", command = my_thread).pack()
root.mainloop()
Ошибка:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\пк\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init
__.py", line 1883, in __call__
return self.func(*args)
Traceback (most recent call last):


During handling of the above exception, another exception occurred:


Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\пк\AppData\Local\Programs\Python\Python38-32\lib\threading.py",
line 932, in _bootstrap_inner
self.run()
File "C:\Users\пк\AppData\Local\Programs\Python\Python38-32\lib\threading.py",
line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\пк\Desktop\проги\Проверка кодов.pyw", line 240, in func
text_vidget = scrolledtext.ScrolledText(root1, width = 120, height = 20)
File "C:\Users\пк\AppData\Local\Programs\Python\Python38-32\lib\tkinter\scroll
edtext.py", line 22, in __init__
self.frame = Frame(master)
File "C:\Users\пк\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init
__.py", line 3119, in __init__
Widget.__init__(self, master, 'frame', cnf, {}, extra)
File "C:\Users\пк\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init
__.py", line 2567, in __init__
self.tk.call(
RuntimeError: main thread is not in main loop

Process returned 1 (0x1) execution time : 19.540 s
Для продолжения нажмите любую клавишу . . .
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
В коде не хватает импортов.
При запуске кода и закрытии окна возникает ошибка
Python:
NameError: name 'filename_img' is not defined
потому что переменная filename_img не определена.
 

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
Python:
from tkinter import *
import os
b = 0
files = ["file"]

def func(thread_number=[0]):
    local_thread_number = thread_number[0]
    thread_number[0] += 1

    root1 = Toplevel(root)
    root1.protocol("WM_DELETE_WINDOW",destroy_window)
    root1.state('zoomed')
    text_vidget1 = scrolledtext.ScrolledText(root1, width = 200, height = 100, state=DISABLED )
    text_vidget1.pack()
    for i, item in enumerate(files):
        stream = open(filesi,"rb")
        bytes = bytearray(stream.read())
        numpyarray = numpy.asarray(bytes, dtype=numpy.uint8)
        bgrImage = cv2.imdecode(numpyarray, cv2.IMREAD_UNCHANGED)
        grayImage = cv2.cvtColor(bgrImage, cv2.COLOR_BGR2GRAY)
        filename_img = "{}.png".format(os.getpid())
        cv2.imwrite(filename_img, grayImage)
        b += 1
        os.remove(filename)
        text_vidget = scrolledtext.ScrolledText(root1, width = 120, height = 20)
        text_vidget1.window_create(INSERT, window=text_vidget)
        text_vidget.insert(1.0,b)
def destroy_window():
    if filename_img != "":
        os.remove(filename_img)
    root1.destroy()
def my_thread():
    # вызов потока
    global thread1, thread2
    thread1 = threading.Thread(target = func, name = "Thread-1")
    thread1.start()

root = Tk()
btn = Button(text = "click me", command = my_thread).pack()
root.mainloop()
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
В коде ничего не изменилось, переменная так и не определена.
Не понятно что этот код должен делать, но видно что он плохо структурирован.
Советую переписать его в стиле ООП (на классах) тогда не будет проблем с областями видимости.
 
Последнее редактирование:

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
В коде ничего не изменилось, переменная так и не определена.
Не понятно что этот код должен делать, но видно он плохо структурирован.
Советую переписать на его в стиле ООП (на классах) тогда не будет проблем с областями видимости.
Python:
def func(thread_number=[0]):
    local_thread_number = thread_number[0]
    thread_number[0] += 1

    root1 = Toplevel(root)
    root1.protocol("WM_DELETE_WINDOW",destroy_window)
    root1.state('zoomed')
    text_vidget1 = scrolledtext.ScrolledText(root1, width = 200, height = 100, state=DISABLED )
    text_vidget1.pack()
    for i, item in enumerate(files):
        stream = open(filesi,"rb")
        bytes = bytearray(stream.read())
        numpyarray = numpy.asarray(bytes, dtype=numpy.uint8)
        bgrImage = cv2.imdecode(numpyarray, cv2.IMREAD_UNCHANGED)
        grayImage = cv2.cvtColor(bgrImage, cv2.COLOR_BGR2GRAY)
        filename_img = "{}.png".format(os.getpid())
        cv2.imwrite(filename_img, grayImage)
        b += 1
        os.remove(filename_img)
        text_vidget = scrolledtext.ScrolledText(root1, width = 120, height = 20)
        text_vidget1.window_create(INSERT, window=text_vidget)
        text_vidget.insert(1.0,b)
def destroy_window():
    if filename_img != "":
        os.remove(filename_img)
    root1.destroy()
def my_thread():
    # вызов потока
    global thread1, thread2
    thread1 = threading.Thread(target = func, name = "Thread-1")
    thread1.start()

root = Tk()
btn = Button(text = "click me", command = my_thread).pack()
root.mainloop()
 

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
Python:
def func(thread_number=[0]):
    local_thread_number = thread_number[0]
    thread_number[0] += 1

    root1 = Toplevel(root)
    root1.protocol("WM_DELETE_WINDOW",destroy_window)
    root1.state('zoomed')
    text_vidget1 = scrolledtext.ScrolledText(root1, width = 200, height = 100, state=DISABLED )
    text_vidget1.pack()
    for i, item in enumerate(files):
        stream = open(filesi,"rb")
        bytes = bytearray(stream.read())
        numpyarray = numpy.asarray(bytes, dtype=numpy.uint8)
        bgrImage = cv2.imdecode(numpyarray, cv2.IMREAD_UNCHANGED)
        grayImage = cv2.cvtColor(bgrImage, cv2.COLOR_BGR2GRAY)
        filename_img = "{}.png".format(os.getpid())
        cv2.imwrite(filename_img, grayImage)
        b += 1
        os.remove(filename_img)
        text_vidget = scrolledtext.ScrolledText(root1, width = 120, height = 20)
        text_vidget1.window_create(INSERT, window=text_vidget)
        text_vidget.insert(1.0,b)
def destroy_window():
    if filename_img != "":
        os.remove(filename_img)
    root1.destroy()
def my_thread():
    # вызов потока
    global thread1, thread2
    thread1 = threading.Thread(target = func, name = "Thread-1")
    thread1.start()

root = Tk()
btn = Button(text = "click me", command = my_thread).pack()
root.mainloop()
Попробуйте этот код, здесь идёт создание нового потока в котором идёт создаение окна root1 а потом идёт цикл в котором идёт создание файла и его удаление.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Попробуйте этот код, здесь идёт создание нового потока в котором идёт создаение окна root1 а потом идёт цикл в котором идёт создание файла и его удаление.
Он также будет выдавать ошибку потому что в функции destroy_window() не определены переменные filename_img и root1.
Можно конечно их передать туда аргументами, но лучше переписать на классы, так как потом проще будет работать с областями видимости.
 

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
Он также будет выдавать ошибку потому что в функции destroy_window() не определены переменные filename_img и root1.
Можно конечно их передать туда аргументами, но лучше переписать на классы, так как потом проще будет работать с областями видимости.
У меня в этой части код работает, мне нужно понять как сделать закрытие окна и удаление файла, я уже много способов проделал но ничего не помогло, вылезают ошибки из за того что удаление происходит в другом потоке а не в корневом ткинтера.
 

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
Ошибки вылезают тогда когда удаление происходит в процессе цикла, а когда цикл проходит и окно закрывается всё нормально.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
У меня в этой части код работает
Показывайте примеры, которые можно запустить. По тем нерабочим фрагментам кода трудно что-то понять.
вылезают ошибки из за того что удаление происходит в другом потоке
не понятно зачем вам в коде понадобился другой поток - можно создавать окна TopLevel в основном потоке.
 

Nikita 2020

Новичок
Пользователь
Май 21, 2020
46
3
8
Потому что мне нужно отображать промежуточные результаты в окно чтобы не ждать когда цикл закончится.
 

Форум IT Специалистов