Tkinter - Preload window?

后端 未结 4 661
死守一世寂寞
死守一世寂寞 2021-01-01 02:57

I started building a python tkinter gui, the problem is, after adding many features to the gui, the loading started looking really ugly. When starting the m

4条回答
  •  说谎
    说谎 (楼主)
    2021-01-01 03:41

    Here are two more ideas for preloading a window before displaying anything to the user. Specifically, do not execute the mainloop of the application until loading is complete. The main disadvantage is that the program might a take a while to appear. Both the main function and the main method finish setting up the frame before the root window is ever displayed. The code at the bottom of the example randomly picks an implementation to run, but both version accomplish the same thing for the user.

    #! /usr/bin/env python3
    import contextlib
    import random
    import time
    import tkinter
    
    
    def main():
        root = tkinter.Tk()
        frame = Application(root)
        frame.setup_frame('Hello, world!', ' ' * 50)
        frame.grid()
        root.mainloop()
    
    
    class Application(tkinter.Frame):
    
        @classmethod
        def main(cls):
            with cls.setup_root('Tkinter Program') as root:
                root.resizable(False, False)
                frame = cls(root)
                frame.setup_frame('Hello, world!', ' ' * 50)
                frame.grid()
    
        @staticmethod
        @contextlib.contextmanager
        def setup_root(title):
            tkinter.NoDefaultRoot()
            root = tkinter.Tk()
            root.withdraw()
            root.title(title)
            yield root
            root.after_idle(root.deiconify)
            root.mainloop()
    
        def setup_frame(self, *args):
            self.after_idle(self.__setup, *args)
    
        def __setup(self, *args):
            time.sleep(5)   # simulate taking a long time
            self.label = tkinter.Label(self, text='{1}{0}{1}'.format(*args))
            self.label.grid()
            self.button = tkinter.Button(
                self,
                text='Raise a KeyboardInterrupt exception.',
                command=lambda: self.throw(KeyboardInterrupt)
            )
            self.button.grid()
    
        @staticmethod
        def throw(kind):
            raise kind()
    
    
    if __name__ == '__main__':
        random.choice((main, Application.main))()
    

提交回复
热议问题