我有一个程序,应该通过串行连接向 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 usingm.set_state('stop')
.
It's mandatory to start theThread
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/