I tried to figure out how the event queue is processed in tkinter. I found this link once and since I played around but I observed different behavior.
The top of my code is:
import tkinter as tk
from tkinter import ttk
def p_trace(*tkargs):
return print('trace', var.get())
def p_binding(event):
return print(event.type,var.get())
root = tk.Tk()
var = tk.IntVar(root)
var.trace_add('write',p_trace)
The p_after is on different location in the print order by using 0 ms.
def after_done():
return print('after',var.get())
check3= ttk.Checkbutton(root,text='event/trace/after',
command=lambda t=0:root.after(t,after_done),
variable=var)
check3.bind('<Button-1>',p_binding)
check3.pack()
The expected order would be for me, based on the link I have found, like this:
- ButtonPress 0
- trace 1
- after 1
- ButtonPress 1
- trace 0
- after 0
But if you click on the button, like gambling, the actual order can be sometimes:
- ButtonPress 1
- trace 0
- ButtonPress 0
- after 0
- trace 1
- after 1
The p_pseudo should be always on top via when='head' but it isn't, never:
def p_pseudo(*tkargs):
return print('pseudo',var.get())
check2= ttk.Checkbutton(root,text='event/trace/pseudo',
command=lambda:check2.event_generate('<<pseudo_event>>',when='head'),
variable=var)
check2.bind('<Button-1>',p_binding)
check2.bind('<<pseudo_event>>',p_pseudo)
check2.pack()
The p_after with after_idle gives also strange output.
def after_done():
return print('after',var.get())
check4= ttk.Checkbutton(root,text='event/trace/after',
command=lambda:root.after_idle(after_done),
variable=var)
check4.bind('<Button-1>',p_binding)
check4.pack()
This seems like arbitrary behavior and makes it in some of my cases hard to have the right order of events. I need to slow my program down for secure execution. Is it possible to determinate the event queue of tkinter or its not likely?