在tkinter中停止long python函数

时间:2017-03-07 17:04:36

标签: python multithreading tkinter interrupt pyserial

我在基于tkinter的GUI上通过 serial 命令一些设备,通常我只想要一个长时间的过程来确保所有设备都是健康的。但偶尔如果我在这个过程运行时看到一些奇怪的东西,我想打断它,发送一些手动命令,然后让它回到正轨。

因此,鉴于下面的代码,我希望该过程看起来像:

  • 点击暂停,应用程序停止命令所有设备并终止其串行连接

  • 用户“参与手动模式”然后他们可以命令他们想要的设备

  • 然后用户将恢复校准。

根据我目前的设置,是否有明显的方法可以做到这一点?

我想避免多个线程,但我并不完全反对线程。我需要访问ec1内的ec2calibrate_devices()对象,以便安全地关闭它们的串行连接,但是想在那里有一堆if语句来查看是否暂停被击中似乎是一个特别笨重的解决方案。

import Tkinter as tk
import ttk
import serial
import time  

class Equipment_Controller_One():
    def __init__(self):
        # create serial connection, etc

    def turn_on(self):
        # command equipment on

    def is_healthy(self):
        # run through lots of tests here

    def kill(self):

    # all other necessary functions

class Equipment_Controller_Two():
    def __init__(self):
        # create serial connection, etc

    def turn_on(self):
        # command equipment on

    def is_healthy(self):
        # run through lots of tests here

    def kill(self):

    # all other necessary functions

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.grid()
        print("Firing up the GUI window.")

        ### creating all application variables
        self.status = tk.StringVar()
        self.status.set("Awaiting instruction.")
        self.details = tk.StringVar()
        self.details.set("Please initiate a command.")
        self.errors = tk.StringVar()
        self.errors.set("No errors yet detected.")

        self.createWidgets()

    def createWidgets(self):
        ttk.Label(self, text="Manual Commands").grid(column=5, row=1)

        ttk.Label(self, text="STATUS:").grid(column=1, row=8)
        ttk.Label(self, textvariable=self.status).grid(column=2, row=8, columnspan=3)

        ttk.Label(self, text="Details:").grid(column=1, row=9)
        ttk.Label(self, textvariable=self.details).grid(column=2, row=9, columnspan=3)

        ttk.Label(self, text="Errors:").grid(column=1, row=10)
        ttk.Label(self, textvariable=self.errors).grid(column=2, row=10, columnspan=3)

        # buttons
        ttk.Button(self, text="Set Temp", command=self.setTemp).grid(column=6, row=5)
        ttk.Button(self, text="Begin Calibration", command=self.calibrate).grid(column=4, row=3)
        ttk.Button(self, text="Pause Calibration", command=self.pause).grid(column=4, row=4)
        ttk.Button(self, text="Engage Manual Mode", command=self.engageManual).grid(column=4, row=5)

    def abortProcedure(self, my_string):
        # safely exit everything here
        self.quit()

    def calibrate(self):
        calibrate_devices(self)

    def pause(self):
        self.status.set("Calibration paused.")
        # when this button is hit I want to command all equipment to stop what they're doing

    def engageManual(self):
        self.status.set("Manual mode engaged.")

        # run through any safety checks here to make sure it is in manual

        self.in_manual = True

    def setTemp(self):
        if not self.in_manual:
            # report some error and don't proceed
            self.errors.set("ERROR: Not safely in manual mode.")
            return
        ec = Equipment_Controller_One()
        bc.turn_on()
        self.details.set("Manully commanding device one.")
        # run through some commands here like setting the temperature on device one



def calibrate_devices(app):
    app.status.set("Calibration initiated.")

    # begin commanding equipment

    ec1 = Equipment_Controller_One()

    # this takes a long time to run
    if (ec1.is_healthy() == True):
        # mark as healthy
    else:
        # something is wrong and neet to trip a pause and alarm and wait for input
        app.errors.set("Device One is unhealthy, stopping calibration.")

    ec2 = Equipment_Controller_Two()

    # this takes a long time to run
    if (ec2.is_healthy() == True):
        # mark as healthy
    else:
        # something is wrong and neet to trip a pause and alarm and wait for input
        app.errors.set("Device Two is unhealthy, stopping calibration.")


def main():
    app = Application()         
    app.master.title('Equipment Calibration')

    app.mainloop()    

if __name__ == '__main__':
    main()

非常欢迎任何想法!

0 个答案:

没有答案