Переменная Python Tkinter внутри основного цикла не отображается, если она не вызывается извне цикла

Пробую tkinter в первый раз. В приведенном ниже коде есть 4 оператора print#. Тут два вопроса -

1) - При выполнении я ожидал, что поток кода будет таким же, как операторы print #, но кажется, что поток другой. Сначала я вижу print2,3, а затем print1. почему это так ?

2)- Только print1 и 4 имеют значение переменной u_input (или e1.get). Почему print2,3 не показывают одно и то же значение? .. это, вероятно, та же причина, что и поток кода.

from tkinter  import *

w = Tk()
w.title(" Main Window")
w.geometry('800x800')      

def test ():
    ux = u_input.get()
    print("print1 : " , ux )

u_input = StringVar()

e1 = Entry(w , textvariable = u_input )
e1.grid(row=0,column=1, padx = 300 , pady= 20 )
b1 = Button(w, text ="button1", width = 12 , justify = "center", command = test )
b1.grid(row=10,column=1 , padx= 300 , pady= 40)


print("print 2 : ", str(u_input.get()))
print("print 3 : ", str(e1.get()))

w.mainloop()

User_Entry = str(u_input.get())
print("print 4 ", User_Entry)

===============================

сравнивая приведенный выше код с приведенным ниже - этот печатает в порядке вызова функций.

a= 1
b= 2
def func2 ():
    a=100
    b=200
    print("print3 :", a+b)
def func1 ():
    a=10
    b=20
    print("print1 :",a+b)

func1()
print("print2 :", a+b)
func2()

person DS_    schedule 07.09.2020    source источник
comment
Сначала я вижу print2,3, а затем print1. почему это так ? По вашим собственным словам, почему вы ожидаете иного? Почему код внутри test должен выполняться до того, как будут достигнуты другие вызовы печати?   -  person Karl Knechtel    schedule 07.09.2020
comment
Также: в вашем коде нет операторов печати в 3.x. print теперь функция.   -  person Karl Knechtel    schedule 07.09.2020
comment
Button() не ждет вашего щелчка - он только сообщает mainloop() какой виджет отображать в окне - и mainloop() запускает программу и окно отображения. Итак, "print 2" "print 3" выполняется до того, как mainloop() покажет окно - и до того, как вы нажмете кнопку, которая запускает код с "print 1"   -  person furas    schedule 07.09.2020


Ответы (1)


Все графические интерфейсы работают иначе, чем команда input().

Button() не ждет вашего клика - он только создает информацию для mainloop() того, какой виджет он должен отображать в окне - и позже mainloop() запускает программу и отображает окно и все виджеты в этом окне. И он запускает цикл, который получает события клавиатуры / мыши из системы, отправляет их в виджеты, запускает функцию, когда вы нажимаете какую-либо кнопку, (повторно) рисуете виджеты и т. д.

Таким образом, "print 2", "print 3" выполняются до того, как mainloop() покажет окно, и до того, как вы сможете нажать кнопку, которая запускает код с "print 1".

И то же самое со второй проблемой. В "print 2", "print 3" он печатает значения до того, как mainloop() отобразит окно, и до того, как вы сможете поместить какой-либо текст в Entry.


Как я уже сказал, так же работают и другие графические интерфейсы — не только tkinter, но и PyQt, PyGTK и т. д. И не только в Python, но и в других языках C, C++, Java и т. д.

Так же могут работать и игры - в них тоже может быть event loop. В PyGame вам придется даже написать этот цикл самостоятельно.

person furas    schedule 07.09.2020
comment
Спасибо, фурас!! .. Я как бы понимаю вашу точку зрения, что графические интерфейсы всегда работают таким образом, что весь код перед mainloop() является просто информацией, а функция, определенная при тестировании, на самом деле не вызывается. Но только что опубликовал еще один обычный код, с которым я его сравнивал. - person DS_; 07.09.2020
comment
вы сравниваете tkinter с кодом, который работает нормально. Он запускает func1() напрямую, но tkinter запускает test() в mainloop(). Когда вы щелкаете внутри окна вашей программы, система отправляет событие мыши в вашу программу, mainloop() получает это событие, оно отправляет его всем виджетам, каждый виджет проверяет, была ли мышь в своей области, когда кнопка распознала, что она была в своей области, и она была щелкнул left mouse button, и кнопка определила command=, затем она запускает назначенную функцию test(). - person furas; 07.09.2020