I want to make screen transition framework.
Please tell me the best way.
Conditions
- Use
tkraise()method. - Fast process during screen transitions is performed in main thread. (ex. tkinter(gui), change variable)
- Processing that takes time during screen transitions is performed on the sub thread. (ex. control for databases, files)
- Don't tkinter process in sub thread. Polling between threads is done using a queue.
- File hierarchy is below. Create a file for each screen.
Multi threads ex
Frame1
↓
↓ Raise waiting frame: main thread
↓ Data get from database: sub thread
↓ Set data Label and Treeview: main thread
↓ Raise control frame: main thread
↓
Frame2
File hierarchy
app\
├ gui\
├ frames.py ・・・ This file is define frame1, frame2, ・・・, frameN.
├ frame1.py
├ frame2.py
・・・
└ frameN.py
├ db\
├ (Omit)
└ main.py
I made this sample code.
Screen transition and multi threads.
import tkinter as tk
from tkinter import ttk
def on_button1():
frame2.tkraise()
def on_button2():
frame1.tkraise()
if name == 'main':
root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
frame1 = ttk.Frame(root)
frame1.grid(row=0, column=0, sticky='nsew')
frame2 = ttk.Frame(root)
frame2.grid(row=0, column=0, sticky='nsew')
button1 = ttk.Button(frame1, text='To frame2', command=on_button1)
button1.pack()
button2 = ttk.Button(frame2, text='To frame1', command=on_button2)
button2.pack()
root.mainloop()
import queue
import threading
import time
import tkinter as tk
from datetime import datetime
from tkinter import ttk
def on_button():
button['state'] = tk.DISABLED
thread = threading.Thread(target=ctrl_db)
thread.start()
def ctrl_db():
# Long process. (omit)
time.sleep(3)
# Don't tkinter process in sub thread.
def func():
svar.set(datetime.now().strftime('%Y/%m/%d (%a) %H:%M:%S'))
button['state'] = tk.NORMAL
# Request tkinter process to main thread.
queue.put([func,])
def polling():
# Process the received tkinter process.
while not queue.empty():
func, *args = queue.get()
func(*args)
root.after(1000, polling)
if __name__ == '__main__':
queue = queue.Queue()
root = tk.Tk()
button = ttk.Button(root, text='Button', command=on_button)
button.pack()
svar = tk.StringVar()
label = ttk.Label(root, textvariable=svar)
label.pack()
root.after(1000, polling)
root.mainloop()