Dav*_*rný 5 python user-interface tkinter lag
我开始构建python tkinter gui,问题是,在gui中添加了许多功能之后,加载看起来真的很丑。启动主循环时,在加载小部件之前,空白窗口会显示几毫秒,其他顶级窗口也会发生同样的情况(除了具有很少静态元素且不需要更新的窗口)。
有没有一种方法可以“预加载”窗口,以便当我调用它时,它可以顺利启动?
root = MyTkRoot()
root.build_stuff_before_calling()
root.mainloop() # Smooth without widget loading lag
Run Code Online (Sandbox Code Playgroud)
from root_gui import Root
import threading
from time import sleep
from data_handler import DataHandler
def handle_conn():
DataHandler.try_connect()
smtp_client.refresh()
def conn_manager(): # Working pretty well
while 'smtp_client' in locals():
sleep(3)
handle_conn()
smtp_client = Root()
handle_conn()
MyConnManager = threading.Thread(target=conn_manager)
MyConnManager.start() # Thanks to the second thread, the tk window doesn't have to wait for 3 seconds before loading the widgets.
smtp_client.mainloop()
Run Code Online (Sandbox Code Playgroud)
此处没有太多代码...
在您的操作系统上,tkinter似乎Tk在加载窗口小部件之前显示了基本窗口,从而导致了几毫秒的空白窗口。为了使其与所有已加载的小部件一起显示,您需要在启动时隐藏该窗口,并.after在加载后再次显示它。
有多种显示和隐藏窗口的方法,就我个人而言,我通常使用.withdraw()从窗口管理器中删除窗口的方法(就像它从未出现过的那样),然后.deiconify()(基本上是“最小化”)再次显示该窗口。
class TEST(tk.Tk):
def __init__(self,*args,**kw):
tk.Tk.__init__(self,*args,**kw)
self.withdraw() #hide the window
self.after(0,self.deiconify) #as soon as possible (after app starts) show again
#setup app...
Run Code Online (Sandbox Code Playgroud)
完全退出窗口的另一种方法是最小化启动窗口,.iconify()这样它将显示在任务栏/停靠栏上,但要等到窗口完全加载后才能打开窗口。
隐藏/显示窗口的另一种方法是更改-alpha属性,就像@double_j所做的那样,但我不建议在生产代码中使用该窗口,因为从技术上讲该窗口仍在那儿,可以单击/ interacted来单击它(和关闭按钮等)。在显示哪些可能是不希望有的信息之前,先进行了短暂的介绍,以及它的行为在操作系统之间可能是模棱两可的,请参见http://wiki.tcl.tk/9457:
Macintosh属性
-alpha双控制不透明度(从0.0到1.0)
...Unix / X11属性
-alpha双控制不透明度(从0.0到1.0)。
这要求合成窗口管理器起作用。[compiz]是这样的一种,而xfwm4(用于XFCE桌面)是另一种。
...Windows属性
-alpha两倍,整个窗口不透明;请注意,在1.0和任何其他值之间更改可能会导致窗口闪烁(Tk会更改用于实现顶层的窗口的类)。
因此,在某些Unix机器上-alpha可能没有任何作用,并且在Windows上可能会导致窗口闪烁(即使在打开之前,这可能不是问题,但仍然值得注意)
据我所知,withdrawand deiconify在所有平台之间的工作方式相同。