python - 我想在按下按钮时运行并终止线程

标签 python multithreading tkinter

我有一个程序,应该通过串行连接向 arduino 发送一些数据点,该 arduino 将控制一些电机移动。我可以单独发送控制信号,也可以通过 txt 文件发送控制信号,该文件将重复运行,直到文件完成。在运行 txt 文件时,我希望能够像暂停或停止按钮一样退出循环。我认为最好的方法是通过一个可以关闭的线程。我以前从未做过任何线程,我的初步尝试没有成功。这是发送文件数据的函数。

def send_file():
    # Global vars
    global moto1pos
    global motor2pos
    # Set Ready value
    global isready
    # Get File location
    program_file_name = file_list.get('active')
    file_path = "/home/evan/Documents/bar_text_files/"
    program_file = Path(file_path + program_file_name)
    file = open(program_file)
    pos1 = []
    pos2 = []
    speed1 = []
    speed2 = []
    accel1 = []
    accel2 = []
    for each in file:
        vals = each.split()
        pos1.append(int(vals[0]))
        pos2.append(int(vals[1]))
        speed1.append(int(vals[2]))
        speed2.append(int(vals[3]))
        accel1.append(int(vals[4]))
        accel2.append(int(vals[5]))
    # Send file values
    try:
        while isready == 1:
            for i in range(len(pos1)):
                print("Step: " + str(i+1))
                data = struct.pack("!llhhhh", pos1[i], pos2[i], speed1[i], speed2[i], accel1[i], accel2[i])
                ser.write(data)

                try:
                    pos1time = abs(pos1[i]/speed1[i])
                except:
                    pos1time = 0
                try:
                    pos2time = abs(pos2[i]/speed2[i])
                except:
                    pos2time = 0
            time_array = (pos1time, pos2time)
            time.sleep(max(time_array))
            motor1pos = ser.readline()
            motor2pos = ser.readline()
            if i < (len(pos1)-1):
                isready = ord(ser.read(1))
            else:
                isready = 0
except:
    print("Error: data not sent. Check serial port is open")

这是我希望 sendfile 命令起作用的线程命令。

def thread():
    try:
        global isready
        isready = 1
        t = threading.Thread(name='sending_data', target=command)
        t.start()
    except:
        print("Threading Error: you don't know what you are doing")

这是我希望杀死线程的停止函数:

def stop():
    try:
        global isready
        isready = 0
        t.kill()
    except:
        print("Error: thread wasn't killed")

我知道你不应该杀死一个线程,但数据并不是很重要。更重要的是在出现故障之前停止电机。

tkinter 中的按钮是:

run_file_butt = tk.Button(master = file_frame, text = "Run File", command = thread)

当我单击按钮时,程序会运行,但停止功能不会停止运动。

最佳答案

Question: run and kill a thread on a button press

不存在所谓的.kill(....
开始使您的 def send_file(... 成为等待您的命令的 Thread 对象

Note: As it stands, your inner while isready == 1: will not stop by using m.set_state('stop').
It's mandatory to start the Thread object inside:

if __name__ == '__main__':
    m = MotorControl()
import threading, time

class MotorControl(threading.Thread):
    def __init__(self):
        super().__init__()
        self.state = {'is_alive'}
        self.start()

    def set_state(self, state):
        if state == 'stop':
            state = 'idle'

        self.state.add(state)

    def terminate(self):
        self.state = {}

    # main function in a Thread object
    def run(self):
        # Here goes your initalisation
        # ...

        while 'is_alive' in self.state:

            if 'start' in self.state:
                isready = 1
                while isready == 1:
                    # Here goes your activity
                    # Simulate activity
                    print('running')
                    time.sleep(2)
                    isready = 0

                self.state = self.state - {'start'}
                self.state.add('idle')

            elif 'idle' in self.state:
                print('idle')
                time.sleep(1)

if __name__ == '__main__':
    m = MotorControl()

    time.sleep(2)
    m.set_state('start')
    time.sleep(3)
    m.set_state('stop')
    time.sleep(3)
    m.set_state('start')

    time.sleep(4)
    m.terminate()
    print('EXIT __main__')
<小时/>

您的tk.Button应如下所示:

tk.Button(text = "Run File", command = lambda:m.set_state('start'))
tk.Button(text = "Stop File", command = lambda:m.set_state('stop'))
tk.Button(text = "Terminate", command = m.terminate)

关于python - 我想在按下按钮时运行并终止线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57677228/

相关文章:

python - 如何从 Tkinter 条目小部件获取字节数组

python - 如何在 Flask-SQLAlchemy 中同时设置一对多和一对一关系?

python - 运行 python 脚本/GTKBuilder 应用程序时出现段错误?

java - 这段代码创建了多少个线程?

java - RMI:在服务器端等待的线程

python - Tkinter 盒子循环打包速度很慢

python - 在 OS X 菜单栏中更改 Tkinter 应用程序的标题

python - 将 sympy 表达式分解为矩阵系数?

python - Python 3 中的相对导入

multithreading - boost::thread:运行优化版本时出现段错误