按下按钮 tkinter 会阻止部分软件的执行
pressing button tkinter blocks execution of a part of the software
我在 python 中有一个程序可以读取我的串口数据。我正在写一个新的部分,在同一个串行端口上单击一个按钮,我发送特定的数据。
下面是我正在使用的部分代码
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
# def sch_plus_callback():
# self.ser.reset_input_buffer()
# self.ser.reset_output_buffer()
# self.ser.write(b'\x02\x56\x81\x80\x80\x80\x80\x80\x42\x33\x04')
# logging.info("write on serial")
# self.ser.reset_input_buffer()
# self.ser.reset_output_buffer()
tk.Tk.__init__(self, *args, **kwargs)
# self.insert_lengh_text_label = tk.Label(self, text="Max Packet Length")
# self.insert_lengh_text_label.pack()
# self.insert_lengh_text = tk.Entry(self, width=2)
# self.insert_lengh_text.pack()
self.serial_text_label = tk.Label(self, text="String")
self.serial_text_label.pack()
self.serial_text = tk.Text(self, height=1, width=50)
self.serial_text.pack()
self.port = 'COM3'
self.baud = 38400
self.ser = serial.Serial(self.port, self.baud, timeout=None)
if self.ser.isOpen():
self.ser.close()
self.ser.open()
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
logging.info("created serial port")
# self.sch_plus_button = tk.Button(self, text="S+", command=sch_plus_callback)
# self.sch_plus_button.pack()
# start the serial_text_label "ticking"
self._update_scheduled = threading.Condition()
self._terminating = threading.Event()
self.update_screen()
def mainloop(self):
with ThreadPoolExecutor() as executor:
future = executor.submit(self._do_update_screen_loop)
try:
return super().mainloop()
finally:
# letting the thread to know we're done
self._terminating.set()
with self._update_scheduled:
self._update_scheduled.notify_all()
def update_screen(self):
with self._update_scheduled:
self._update_scheduled.notify_all()
self.after(500, self.update_screen)
def _do_update_screen_loop(self):
while True:
with self._update_scheduled:
self._update_scheduled.wait()
if self._terminating.is_set():
return
self._do_data_screen()
def _do_data_screen(self):
self.serial_text.delete('1.0', tk.END)
# dimension = self.insert_lengh_text.get()
# if dimension == "":
# dimension = 1
data = ""
data_raw = self.ser.read(1)
if data_raw == b'\x02':
data_raw = self.ser.read_until(b'\x03')
data = "02-" + str(data_raw.hex('-'))
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
hex_list = [int(x, 16) for x in data.split('-')]
check = checksum_calculation(hex_list)
if hex_list[4] == check[0] and hex_list[5] == check[1]:
logging.debug("Checksum correct")
logging.debug(str(hex_list))
self.serial_text.insert(tk.END, data)
# self.serial_text_label.configure(text=data)
我正在使用按钮写入串口
self.sch_plus_button = tk.Button(self, text="S+", command=sch_plus_callback)
self.sch_plus_button.pack()
调用
def sch_plus_callback():
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
self.ser.write(b'\x02\x56\x81\x80\x80\x80\x80\x80\x42\x33\x04')
logging.info("write on serial")
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
当数据发送到串口时,它就起作用了。唯一的问题是,在某个随机时刻,至少按一次按钮后,程序停止读取端口。
知道为什么吗?
似乎解决方案是将 sch_plus_callback
带到 init
之外并调用
self.sch_plus_button = tk.Button(self, text="S+", command=self.sch_plus_callback)
init 之外的函数
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# all my other code
def sch_plus_callback(self):
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
self.ser.write(b'\x02\x56\x81\x80\x80\x80\x80\x80\x39\x35\x04')
logging.info("write on serial")
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
我在 python 中有一个程序可以读取我的串口数据。我正在写一个新的部分,在同一个串行端口上单击一个按钮,我发送特定的数据。
下面是我正在使用的部分代码
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
# def sch_plus_callback():
# self.ser.reset_input_buffer()
# self.ser.reset_output_buffer()
# self.ser.write(b'\x02\x56\x81\x80\x80\x80\x80\x80\x42\x33\x04')
# logging.info("write on serial")
# self.ser.reset_input_buffer()
# self.ser.reset_output_buffer()
tk.Tk.__init__(self, *args, **kwargs)
# self.insert_lengh_text_label = tk.Label(self, text="Max Packet Length")
# self.insert_lengh_text_label.pack()
# self.insert_lengh_text = tk.Entry(self, width=2)
# self.insert_lengh_text.pack()
self.serial_text_label = tk.Label(self, text="String")
self.serial_text_label.pack()
self.serial_text = tk.Text(self, height=1, width=50)
self.serial_text.pack()
self.port = 'COM3'
self.baud = 38400
self.ser = serial.Serial(self.port, self.baud, timeout=None)
if self.ser.isOpen():
self.ser.close()
self.ser.open()
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
logging.info("created serial port")
# self.sch_plus_button = tk.Button(self, text="S+", command=sch_plus_callback)
# self.sch_plus_button.pack()
# start the serial_text_label "ticking"
self._update_scheduled = threading.Condition()
self._terminating = threading.Event()
self.update_screen()
def mainloop(self):
with ThreadPoolExecutor() as executor:
future = executor.submit(self._do_update_screen_loop)
try:
return super().mainloop()
finally:
# letting the thread to know we're done
self._terminating.set()
with self._update_scheduled:
self._update_scheduled.notify_all()
def update_screen(self):
with self._update_scheduled:
self._update_scheduled.notify_all()
self.after(500, self.update_screen)
def _do_update_screen_loop(self):
while True:
with self._update_scheduled:
self._update_scheduled.wait()
if self._terminating.is_set():
return
self._do_data_screen()
def _do_data_screen(self):
self.serial_text.delete('1.0', tk.END)
# dimension = self.insert_lengh_text.get()
# if dimension == "":
# dimension = 1
data = ""
data_raw = self.ser.read(1)
if data_raw == b'\x02':
data_raw = self.ser.read_until(b'\x03')
data = "02-" + str(data_raw.hex('-'))
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
hex_list = [int(x, 16) for x in data.split('-')]
check = checksum_calculation(hex_list)
if hex_list[4] == check[0] and hex_list[5] == check[1]:
logging.debug("Checksum correct")
logging.debug(str(hex_list))
self.serial_text.insert(tk.END, data)
# self.serial_text_label.configure(text=data)
我正在使用按钮写入串口
self.sch_plus_button = tk.Button(self, text="S+", command=sch_plus_callback)
self.sch_plus_button.pack()
调用
def sch_plus_callback():
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
self.ser.write(b'\x02\x56\x81\x80\x80\x80\x80\x80\x42\x33\x04')
logging.info("write on serial")
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
当数据发送到串口时,它就起作用了。唯一的问题是,在某个随机时刻,至少按一次按钮后,程序停止读取端口。
知道为什么吗?
似乎解决方案是将 sch_plus_callback
带到 init
之外并调用
self.sch_plus_button = tk.Button(self, text="S+", command=self.sch_plus_callback)
init 之外的函数
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# all my other code
def sch_plus_callback(self):
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
self.ser.write(b'\x02\x56\x81\x80\x80\x80\x80\x80\x39\x35\x04')
logging.info("write on serial")
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()