Я написал приложение на основе Python 3 TkInter, которое запускает рабочий поток в фоновом режиме.После завершения рабочего потока он ждет две секунды (чтобы избежать возможного состояния гонки), а затем отправляет KeyboardInterrupt, чтобы сообщить основному потоку, что он может закрыться.
Ожидаемое поведение: при запуске программы запускается окно графического интерфейса пользователя, выводится текст на консоль, после чего программа автоматически закрывается.
Фактическое поведение: вместо автоматического закрытия, это происходит только послеПользователь либо наводит указатель мыши на область окна GUI, либо нажимает клавишу на клавиатуре!Кроме того, программа работает без сообщений об ошибках.
Кто-нибудь имеет представление, почему это происходит, и как это исправить?Я уже пытался обернуть KeyboardInterrupt в отдельную функцию, а затем вызвать ее через объект таймера , но это приводит к тому же поведению.
Я смог воспроизвести эту проблему на2 разные машины Linux, на которых работает Python 3.5.2.и 3.6.6 соответственно.
#! /usr/bin/env python3
import os
import threading
import _thread as thread
import time
import tkinter as tk
import tkinter.scrolledtext as ScrolledText
class myGUI(tk.Frame):
# This class defines the graphical user interface
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.build_gui()
def build_gui(self):
# Build GUI
self.root.title('TEST')
self.root.option_add('*tearOff', 'FALSE')
self.grid(column=0, row=0, sticky='ew')
self.grid_columnconfigure(0, weight=1, uniform='a')
# Add text widget to display logging info
st = ScrolledText.ScrolledText(self, state='disabled')
st.configure(font='TkFixedFont')
st.grid(column=0, row=1, sticky='w', columnspan=4)
def worker():
"""Skeleton worker function, runs in separate thread (see below)"""
# Print some text to console
print("Working!")
# Wait 2 seconds to avoid race condition
time.sleep(2)
# This triggers a KeyboardInterrupt in the main thread
thread.interrupt_main()
def main():
try:
root = tk.Tk()
myGUI(root)
t1 = threading.Thread(target=worker, args=[])
t1.start()
root.mainloop()
t1.join()
except KeyboardInterrupt:
# Close program if subthread issues KeyboardInterrupt
os._exit(0)
main()
(ссылка на Github Gist на приведенный выше скрипт здесь )