0

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()
person
  • 13

0 Answers0