用tkinter按钮触发和停止进程 [英] triggering and stopping a process with tkinter buttons

查看:171
本文介绍了用tkinter按钮触发和停止进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(向下滚动以查看此问题的编辑版本)

我希望变量"a"在播放"列表中成为 global .回调函数,每当我按播放"按钮时更新或停止"纽扣.如您所见,通过运行代码,每当我按下按钮时,回调函数都会更新其值,但是如果尝试在tkinter mainloop中测试全局变量的值,则只有在程序首次启动后,我才会获得更新没什么变化.

I expect the variable "a", made global in the "play" callback function, to update every time I press the "play" or "stop" buttons. As you can see by running the code, the callback function update its value whenever I press the buttons, but if a try to test the value of the global variable within tkinter mainloop, I only get an update when the program is firstly started and then nothing the changes.

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()

我再次编写了代码,以使问题更清楚,并模拟在这种情况下我想通过这些简化示例进行重现的情况.我希望测试器功能可以打印出正在运行"的消息.或未运行"根据我按下的每个按钮.我正在运行测试器"在一个线程内,因为在实际项目中我正在研究测试器"是一种更复杂的过程:

I have written the code again in order to make the question clearer and in order to simulate what's going on in the situation I'm trying to reproduce with these simplified examples. I expect the tester function to print out "running" or "not running" according to each button I press. I'm running "tester" inside a thread because in the acutal project I'm working on "tester" is a way more complex process:

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()

推荐答案

将基本类型传递给函数使用的是按值传递,因此,以下行:

Passing a primitive type to a function is using pass by value, so the following line:

t1 = threading.Thread (target = tester, args = [a], daemon = True)

会将 a 的值(由于 a 的原始类型为 int )传递给 tester 0 .

will pass the value of a (since a is of primitive type int) to tester which is 0.

您可以使用 IntVar 代替 a ,以便使用通过引用传递:

You can use IntVar instead for a, so that pass by reference is used:

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()

这篇关于用tkinter按钮触发和停止进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆