0

大家好,我试图在线程类中调用一个方法,该方法应该在该线程内设置一个事件标志,导致线程在设置事件时停止运行。当前的代码类型可以工作,并调用该函数,但事件标志似乎并未在线程内触发。

该线程负责在 GUI 上按下按钮时运行的操作,但如果设置了事件,则它不应该运行。

我的代码的最小版本:

import threading
import time

GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD.UP)

global run = 0

class Pump_Thread(threading.Thread):
    def __init__(self, interval=0.5):
        super(Pump_Thread, self).__init__()
        self._stop_event = threading.Event()
        self.interval = interval
        Pump_threads = threading.Thread(target=self.run, daemon=True)                           
        Pump_threads.start()

    def stop(self):
        self._stop_event.set()
        print("Things have stopped yo...")

    def resume(self):
        self._stop_event.clear()
        print("And Now Things will resume")
    
    def run(self)
        while not self._stop_event.is_set():
            if (run == 1):
                #doing some stuff when bit set#
                print("Yeah Yeah, I'm running")

class Page1(Page):
   def __init__(self, *args, **kwargs):
       #Some Initializing methods to load buttons and graphics
       self.start_btn=tk.Button(self,height=32,width =80,command=self.Start)
       self.start_btn.place(x=50, y=50)
       self.reset_btn=tk.Button(self,height=32,width =80,command=self.Reset)
       self.reset_btn.place(x=50, y=80)

  def Start(self):
      global run
      run = 1 #<------Set Bit for code to run

  def Reset(self):
      d = Pump_Thread()
      d.resume() #<-----Run Method inside thread
      

class Monitor_Thread(threading.Thread):
    def __init__(self, interval=0.5):
        self.interval = interval
        Monitor_Threads = threading.Thread(target=self.Monitor_Thread, daemon=True)                           
        Monitor_Threads.start()

    def run(self)
        while True:
            if Condition == True:
                d = Pump_Thread()
                d.stop() #<-----Run Method inside thread

class Interrupt_Class(page):
    def Input(self):
        d = Pump_Thread()
        d.stop() #<-----Run Method inside thread

    GPIO.add_event_detect(18, GPIO.FALLING, callback=Input, bouncetime=300)

class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, *kwargs)
        super().__init__()

        p1 = Page1(self) #Other Pages Added here with navigation buttons to raise the page to the front of the GUI#
        p1.show()


if __name__ == "__main__":
    root = tk.TK()
    main = MainView(root)
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("400x400")
    root.attributes("-fullscreen", False)
    Thread1 = Pump_Thread()
    Thread2 = Monitor_Thread()
    root.mainloop()

触发中断时,会打印“Things has stop yo...”,因此会调用该方法,但是当按下 GUI 按钮时该过程仍会启动,这意味着未设置事件。这会是什么原因?

4

2 回答 2

1

你似乎有很多错误堆积在一起。

您需要查看有关如何创建和管理线程的 stackoverflow 上的许多示例。

你可以尝试这样的事情:

class Pump_Thread(threading.Thread):
    def __init__(self, interval=0.5):
        super().__init__()
        self._stop_event = threading.Event()
        self.interval = interval

    def stop(self):
        self._stop_event.set()
        print("Things have stopped yo...")

    def resume(self):
        self._stop_event.clear()
        print("And Now Things will resume")
    
    def run(self)
        while not self._stop_event.is_set():
            print("Yeah Yeah, I'm running")

# other parts elided

if __name__ == "__main__":
    root = tk.TK()
    main = MainView(root)

    Thread1 = Pump_Thread()
    Thread1.start()

但是现在所有其他需要启动和停止的地方都Pump_Thread需要访问Thread1。所以你应该把它传递给创建的对象。

class Interrupt_Class(page):
    def __init__(self, pump):
        self.pump = pump
    def Input(self):
        self.pump.stop() #<-----Run Method inside thread

ic = Interrupt_Class(Thread1)
于 2020-07-17T09:38:18.723 回答
0

您正在调用:

d = Pump_Thread()

每次调用之前:d.stop()这只会使该线程停止。

如何Pump_Thread实例化以及在哪里存储对它的引用?

事实上,你没有展示你的任何类是如何被实例化的。

于 2020-07-17T08:52:55.687 回答