使用 tkinter 按钮触发和停止进程
triggering and stopping a process with tkinter buttons
(向下滚动查看此问题的编辑版本)
我希望在“播放”回调函数中设置为 global 的变量“a”在我每次按下“播放”或“停止”按钮时更新。正如您在 运行 代码中看到的那样,只要我按下按钮,回调函数就会更新它的值,但是如果尝试在 tkinter mainloop 中测试全局变量的值,我只会在程序运行时得到更新首先开始,然后没有任何变化。
from tkinter import *
a = 0
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
global a
a = switch
print (a)
root = Tk()
if a == 1:
print ("one")
elif a == 0:
print ("zero")
app = gui(root)
root.mainloop()
编辑 1:
我重新编写了代码,以便使问题更清楚,并模拟在我尝试使用这些简化示例重现的情况下发生的情况。我希望测试器功能根据我按下的每个按钮打印出“运行”或“not 运行”。我是线程中的 运行“测试人员”,因为在实际项目中,我正在处理“测试人员”是一个更复杂的过程:
from tkinter import *
import threading
import time
a = 0
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
global a
a = switch
print (a)
root = Tk()
def tester(trig):
while True:
if trig == 1:
time.sleep(0.5)
print ("running")
elif trig == 0:
time.sleep(0.5)
print ("not running")
t1 = threading.Thread (target = tester, args = [a], daemon = True)
t1.start()
app = gui(root)
root.mainloop()
如果语句只被运行一次,如果你想打印出一个或两个
每次按下按钮时,我建议将 if 语句放在 play 函数中。
from tkinter import *
a = 0
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
global a
a = switch
if a == 1:
print ("one")
elif a == 0:
print ("zero")
root = Tk()
app = gui(root)
root.mainloop()
将原始类型传递给函数使用 pass by value
,因此以下行:
t1 = threading.Thread (target = tester, args = [a], daemon = True)
会将 a
的值(因为 a
是原始类型 int
)传递给 tester
即 0
.
您可以使用 IntVar
代替 a
,这样就可以使用 pass by reference
:
from tkinter import *
import threading
import time
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
a.set(switch) # update 'a'
print(a.get())
root = Tk()
a = IntVar(value=0)
def tester(trig):
while True:
value = trig.get()
if value == 1:
time.sleep(0.5)
print ("running")
elif value == 0:
time.sleep(0.5)
print ("not running")
t1 = threading.Thread (target = tester, args = [a], daemon = True)
t1.start()
app = gui(root)
root.mainloop()
(向下滚动查看此问题的编辑版本)
我希望在“播放”回调函数中设置为 global 的变量“a”在我每次按下“播放”或“停止”按钮时更新。正如您在 运行 代码中看到的那样,只要我按下按钮,回调函数就会更新它的值,但是如果尝试在 tkinter mainloop 中测试全局变量的值,我只会在程序运行时得到更新首先开始,然后没有任何变化。
from tkinter import *
a = 0
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
global a
a = switch
print (a)
root = Tk()
if a == 1:
print ("one")
elif a == 0:
print ("zero")
app = gui(root)
root.mainloop()
编辑 1:
我重新编写了代码,以便使问题更清楚,并模拟在我尝试使用这些简化示例重现的情况下发生的情况。我希望测试器功能根据我按下的每个按钮打印出“运行”或“not 运行”。我是线程中的 运行“测试人员”,因为在实际项目中,我正在处理“测试人员”是一个更复杂的过程:
from tkinter import *
import threading
import time
a = 0
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
global a
a = switch
print (a)
root = Tk()
def tester(trig):
while True:
if trig == 1:
time.sleep(0.5)
print ("running")
elif trig == 0:
time.sleep(0.5)
print ("not running")
t1 = threading.Thread (target = tester, args = [a], daemon = True)
t1.start()
app = gui(root)
root.mainloop()
如果语句只被运行一次,如果你想打印出一个或两个 每次按下按钮时,我建议将 if 语句放在 play 函数中。
from tkinter import *
a = 0
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
global a
a = switch
if a == 1:
print ("one")
elif a == 0:
print ("zero")
root = Tk()
app = gui(root)
root.mainloop()
将原始类型传递给函数使用 pass by value
,因此以下行:
t1 = threading.Thread (target = tester, args = [a], daemon = True)
会将 a
的值(因为 a
是原始类型 int
)传递给 tester
即 0
.
您可以使用 IntVar
代替 a
,这样就可以使用 pass by reference
:
from tkinter import *
import threading
import time
class gui:
def __init__(self, window):
# play button
self.play_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.play_frame.grid(row=0, column=0, padx=1, pady=1)
self.play_button = Button(self.play_frame, text="play", fg="blue", command=lambda: self.play(1))
self.play_button.pack()
# stop button
self.stop_frame = Frame(master=window, relief=FLAT, borderwidth=1)
self.stop_frame.grid(row=0, column=2, padx=1, pady=1)
self.stop_button = Button(self.stop_frame, text="stop", fg="red", command=lambda: self.play(0))
self.stop_button.pack()
def play(self, switch):
a.set(switch) # update 'a'
print(a.get())
root = Tk()
a = IntVar(value=0)
def tester(trig):
while True:
value = trig.get()
if value == 1:
time.sleep(0.5)
print ("running")
elif value == 0:
time.sleep(0.5)
print ("not running")
t1 = threading.Thread (target = tester, args = [a], daemon = True)
t1.start()
app = gui(root)
root.mainloop()