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

#python #tkinter #mainloop

#python #ткинтер #основной цикл #ткинтеръ

Вопрос:

Впервые пытаюсь использовать tkinter. Приведенный ниже код содержит 4 оператора print #. Здесь два вопроса —

1) — При выполнении я ожидал, что поток кода of будет таким же, как операторы 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()
  

Комментарии:

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

2. Также: в вашем коде нет инструкций печати в 3.x. print теперь это функция.

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

Ответ №1:

Все графические интерфейсы работают иначе, чем command 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 вам даже придется написать этот цикл самостоятельно.

Комментарии:

1. Спасибо furas !! .. Я отчасти понимаю вашу точку зрения, что графические интерфейсы всегда работают таким образом, что весь код перед mainloop() — это просто информация, а функция, определенная при тестировании, на самом деле не вызывается. Но только что опубликовал другой обычный код, с которым я его сравнивал.

2. вы сравниваете tkinter с кодом, который работает обычным способом. Она выполняется func1() напрямую, но tkinter выполняется test() в mainloop() . Когда вы щелкаете внутри окна вашей программы, система отправляет событие мыши в вашу программу, mainloop() получает это событие, оно отправляет его всем виджетам, каждый виджет проверяет, была ли мышь в его области, когда кнопка распознала, что она была в его области, и была нажата left mouse button , и кнопка определила, command= затем она запускает назначенную функцию test() .