-1

I have a main interface with widgets.. it doesn't matter what's on the GUI.

What I m trying to do is to create a splashscreen when the app is launched.

The whole point is that while the interface is loading, the splashscreen should be the thing that takes up that loading time.

I tried a lot of options.

  • Use two libraries, Tkinter and (PyQt5/6, PySide6, PySimpleGUI)

  • Create a new file just for the splash screen

  • tk.Tk for both windows (main and splashscreen)

  • Tk and TopLevel

The last option looked like the best, but there was one problem.
Which was going to be the root and which the TopLevel?

You need to launch first the splashscreen,
so maybe this one can be the root but then you will destroy the splashscreen(bad option) or withdraw it? but after you close your main interface the app will still running.

I know the theory. You can't have or.. to be more precise, it's not recommended to have two instances of Tk.

What should I do.

Below you can find the code. Right now, in the code there are no threads, just the main one. First appears the splashscreen and then my main interface it shows.

This is the main interface, where my widgets are:

class CANGui():

    def __init__(self, gui_revision: str):
        self.splash()                    # splash function 
        self.gui_revision = gui_revision
        self.root = Tk()                 # Tk instance of main interface
        self.root.geometry("600x850")
        self.root.title(f"CanInterfaceGUI {self.gui_revision}")
        ...

The function that calls my splash class:

    def splash(self):
        root = Tk()
        splash = SplashScreen(root)
        for i in range(200):
            if i % 10 == 0:
                splash.abc()
            root.update()
            splash.progressbar.step(0.5)
            time.sleep(0.01)
        splash.destroy()
        root.mainloop()

The class with the splash screen:

class SplashScreen:
    def __init__(self, parent):
        self.parent = parent

        self.logo_image = Image.open("photo.png").resize((500, 250), Image.ANTIALIAS)
        self.logo_animation = ImageTk.PhotoImage(self.logo_image)

        self.parent.overrideredirect(True)

        screen_width = self.parent.winfo_screenwidth()
        screen_height = self.parent.winfo_screenheight()
        logo_width = self.logo_animation.width()
        logo_height = self.logo_animation.height()
        x = (screen_width - logo_width) // 2
        y = (screen_height - logo_height) // 2
        self.parent.geometry("+{}+{}".format(x, y))

        self.logo_frame = Frame(self.parent)
        self.logo_frame.grid(row=0, column=0, sticky='nsew')

        frame = Frame(self.parent)
        frame.grid(row=1, column=0, sticky='nsew')

        self.logo_label = Label(self.logo_frame, image=self.logo_animation)
        self.logo_label.grid(row=0, column=0)

        self.progressbar = Progressbar(frame, orient='horizontal', length=200)
        self.progressbar.config()
        self.progressbar.grid(row=0, column=0, padx=5)

        self.text_label = Label(frame, text="...", font=("Arial", 11))
        self.text_label.grid(row=0, column=1, padx=(200,0), sticky='e')
    
        self.list = ['.modules', 'CAN-HAT.sh' , 'continue', '.install', 'initialize']

        self.parent.update()

    def abc(self):
        self.text_label.config(text = random.choice(self.list))

    def destroy(self):
        self.parent.overrideredirect(False)
        self.parent.destroy()
Timothee
  • 1
  • 3
  • 1
    It's unspecific. See [ask] and [mre]. Implement a prototype with the threading API and ask a specific question. Anyway, see [this answer](https://stackoverflow.com/a/74989468/1186624) for an example of a worker thread. – relent95 Apr 05 '23 at 02:31
  • 1
    Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Apr 05 '23 at 06:43
  • How can I implement a splashcreen in a program using a thread ?? – Timothee Apr 05 '23 at 13:22
  • Use only single Tkinter root instance and main loop. Use a ```Toplevel``` instance for the splash screen. Manipulate the UI objects always in the main thread. Do a time consuming work in a background thread. Just study the example code in the above link in my previous comment and restructure your code. Then, ask a specific question if you confront a problem. – relent95 Apr 07 '23 at 11:36
  • Also you didn't say anything on that time consuming work. If you can't move that work to a worker thread, you need to use a worker process. – relent95 Apr 07 '23 at 11:39

1 Answers1

-2

Simple demo code by using PySimpleGUI

from time import sleep
import PySimpleGUI as sg

def load():
    sleep(5)

win = sg.Window('Title', [[sg.Text("Loading .....")]], no_titlebar=True, finalize=True)
win.perform_long_operation(load, "Done")
win.read(close=True)

sg.Window('Title', [[sg.Text("Main Window"), sg.Button('Exit')]]).read(close=True)
Jason Yang
  • 11,284
  • 2
  • 9
  • 23