背景:我用自带tk界面写了个程序,后面觉得太丑就换ttkbootstrap试试,但是在修改程序过程中发现消息框始终无法在def中正常运行。求帮忙看看咋回事。
这是tk的代码,关闭程序正常弹消息框。
import sys
import threading
import tkinter as tk
from tkinter import messagebox
from tkinter.messagebox import askyesno
class TestGui:
def __init__(self, init_window_name):
self.init_window_name = init_window_name
self.init_window_name.title("555")
self.init_window_name.geometry("310x380")
self.init_window_name.protocol('WM_DELETE_WINDOW', lambda: self.thread_it(self.clos_window))
def thread_it(self, func, *args):
""" 将函数打包进线程 """
self.myThread = threading.Thread(target=func, args=args)
self.myThread .setDaemon(True) # 主线程退出就直接让子线程跟随退出,不论是否运行完成。
self.myThread .start()
def clos_window(self):
ans = askyesno(title='通知', message='是否退出程序')
if ans:
self.init_window_name.destroy()
sys.exit()
else:
return None
if __name__ == '__main__':
init_window = tk.Tk()
init_window.attributes("-topmost", 1)
test_gui = TestGui(init_window)
init_window.mainloop()
这个是换ttk后改的代码 消息框始终无法正常运行,弹窗之前的555是能打印出来的。报了这个错误:RuntimeError: Calling Tcl from different apartment
import ttkbootstrap as ttk
from ttkbootstrap.dialogs import Messagebox
import threading
class TestGui:
def __init__(self, root_window):
self.root_windows = root_window
self.root_windows.title("11111111")
self.root_windows.geometry("380x285")
self.root_windows.protocol('WM_DELETE_WINDOW', lambda: self.thread_it(self.clos_window))
self.Messgebox = Messagebox
def clos_window(self):
print("555")
self.Messgebox.show_warning(message="显示警告")
def thread_it(self, func, *args):
self.myThread = threading.Thread(target=func, args=args)
self.myThread .setDaemon(True)
self.myThread .start()
if __name__ == '__main__':
root_window = ttk.Window()
root_window.attributes("-topmost", 1)
root_window.resizable(width=False, height=False)
test_gui = TestGui(root_window)
root_window.mainloop()
起初以为没执行函数 后面加了打印发现正常执行的,唯独这个消息框报错,不清楚是线程原因还是我写的不对。我试过添加按钮去执行def 也是报错。但我在原来的tk程序里边用就没问题。