【问题标题】:starting/stopping while loops with button in tkinter使用 tkinter 中的按钮启动/停止 while 循环
【发布时间】:2021-03-11 06:21:19
【问题描述】:

通过使用两个不同的按钮,我试图启动和停止一个基于 while 循环的进程,该循环扫描模式(实际上在这个例子中只是计数)。在下面的代码中,我试图简化和概括我正在从事的实际项目中发生的更复杂的过程。运行代码可以看到,按下播放键就可以开始计数;但是,当您按下停止按钮时,该过程不会立即停止。我以前设法使它按需要工作,但是在使用面向对象的方法重写代码时,没有任何东西可以正常工作。目前,如果问题出在 while 循环构造中,或者我以错误的方式处理线程,我无法再理解了。 任何建议都非常欢迎和赞赏!

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 process(self, trig):
        self.trig = trig

        while True:
            if self.trig == 1:

                for i in range (10):
                    time.sleep(0.5)
                    print (i)


            elif self.trig == 0:
                print ("stopped...")
                break

    def play(self, switch):


        self.switch = int(switch)
        t1 = threading.Thread (target = self.process, args = [self.switch], daemon = True)
        t1.start()
        

root = Tk()

app = gui(root)
root.mainloop()

【问题讨论】:

  • 您希望计数器重新启动吗?每次按停止
  • 您正在启动一个新线程,而不是停止旧线程。我可以向您展示如何解决它,但我认为您过于简化了您的问题。例如, trig 变量的意义何在?你需要多个线程吗?您是否要中断 10 次计数(您当前的代码仅停止外循环)?
  • 是的,我需要多个线程。我正在尝试实现一个步进音序器,理想情况下我会有多个“轨道”和多个线程。 trig 变量用于触发模式扫描过程(现在我只是在“计数”,但我将读取类似于 pattern = [1, 0, 0, 1...] 的模式)。 @coderoftheday 不一定,但由于我描述的应用程序应该实时使用,所以我需要在更新某些变量时“重新触发”整个过程。同样按播放应该重新启动序列。

标签: python class user-interface tkinter while-loop


【解决方案1】:

只需创建一个单独的线程来接收何时开始和停止倒计时的信号

from tkinter import *
import threading
import time


should_run = False
class a:
    def __init__(self):
        while True:
            if should_run:
                for i in range(10):
                    if not should_run:
                        print('Stopped...')
                        break
                    if should_run:
                        time.sleep(0.5)
                        print(i)

t1 = threading.Thread(target=a,daemon=True)
t1.start()

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(True))
        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(False))
        self.stop_button.pack()


    def play(self, switch):
        global should_run
        should_run = switch



root = Tk()

app = gui(root)
root.mainloop()

【讨论】:

  • 谢谢!这当然可以按预期工作,我将尝试在更大的项目中实施您建议的程序,看看它是否会起作用。
  • 不用担心,同样的逻辑,创建一个包含计数器并等待信号停止或启动的线程
  • 我尝试将相同的逻辑应用到我的项目中,并且程序按预期运行。当我将类放在单独的文件中以使代码更易于阅读时,事情就停止了正常工作。线程中的进程似乎对按钮的输入没有响应。如果我设法复制这种情况,我将发布一个示例......
  • 我认为在我刚刚在以下问题中描述的情况下可能会发生一个错误:stackoverflow.com/questions/65079415/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 2021-06-16
  • 2020-11-09
  • 1970-01-01
相关资源
最近更新 更多