Проблема здесь состоит в том, что ваш while
цикл просто продолжает работать, не означает ни один из остальной части вашего кода никогда не получает бежать. Это включает в себя графический интерфейс Tkinter, что означает, что ваша программа не отвечает на любые пользовательские события, в том числе нажатие кнопки, поэтому endloop
никогда не вызывается.
В более общем плане, вы действительно не можете иметь функцию, которая работает только навсегда, или даже более чем на долю секунды, внутри программы GUI. Однопоточная программа может делать только одно за раз; если то, что он делает, зацикливается навсегда, тогда это не делает ничего другого.
Итак, что может вы?
Есть два основных варианта:
Помещенный петлю на фоне потока. Это означает, что любые общие данные теперь должны быть явно синхронизированы, и это означает, что цикл не может касаться каких-либо виджетов GUI, но в вашем случае это оказывается довольно простым.
Разбить петлю. Попробуйте сделать одну итерацию (или, скажем, 100 итераций, если они действительно быстрые), а затем используйте after
или after_idle
, чтобы попросить Tkinter вызвать функцию, которая выполняет еще одну итерацию (или 100 итераций) и after
s снова, и так далее, пока все не закончится.
Я покажу вам, как сделать первый здесь.
import threading
from tkinter import*
root = Tk()
def real_loop():
while True:
with superman_lock:
if not superman:
return
print("It's doing something")
def loop():
global superman
global superman_lock
superman=False
superman_lock = threading.Lock()
thread = threading.Thread(target=real_loop, daemon=True)
def endloop():
global superman
with superman_lock:
superman=True
btn_1 = Button(root, text="stop", command=endloop)
btn_1.pack()
btn_2 = Button(root, text="start", command=loop)
btn_2.pack()
Для случая, когда только общие данные «стоп» флаг, Condition
или Event
часто лучше, чем Lock
. Документы threading
объясняют различия между различными типами объектов синхронизации, но не на начальном уровне. Статья Википедии о monitors может стать лучшей отправной точкой для изучения, но если вы можете найти хороший учебник по многопоточности (не обязательно для Python-специфичного; у Python есть в основном те же объекты синхронизации, что и библиотека C pthreads, библиотека C++ Boost, Java stdlib и т. Д.), Что, вероятно, было бы лучше.
Для более подробного обсуждения см. Why your GUI app freezes.
Вы не * звоните * 'endloop'. – user2357112
Как вы называете обе функции? Предполагается, что в потоках. – bereal
Уверен, но это на самом деле в tkinter и кнопке, вызывающей endloop() –