代码拉取完成,页面将自动刷新
import tkinter as tk
from tkinter import ttk, messagebox
import serial.tools.list_ports
import serial
import threading
class SerialPortSelector:
def __init__(self, master):
self.master = master
self.master.title("乘风串口小软件")
self.master.geometry("800x600")
self.ser = None # 初始化串口对象为None
self.config_frame = ttk.Frame(master)
self.config_frame.pack(side=tk.LEFT, fill=tk.Y, padx=10, pady=10)
self.port_label = ttk.Label(self.config_frame, text="可用串口:")
self.port_label.pack(anchor=tk.W)
self.ports = serial.tools.list_ports.comports()
self.port_names = [port.device for port in self.ports]
self.port_combo_box = ttk.Combobox(self.config_frame, values=self.port_names)
self.port_combo_box.pack(anchor=tk.W)
self.refresh_button = ttk.Button(self.config_frame, text="刷新串口", command=self.refresh_ports)
self.refresh_button.pack(anchor=tk.W, pady=(5, 0))
self.baud_label = ttk.Label(self.config_frame, text="波特率:")
self.baud_label.pack(anchor=tk.W, pady=(10, 0))
self.baud_rates = [9600, 19200, 38400, 57600, 115200]
self.baud_combo_box = ttk.Combobox(self.config_frame, values=self.baud_rates)
self.baud_combo_box.set(9600)
self.baud_combo_box.pack(anchor=tk.W)
self.toggle_button = ttk.Button(self.config_frame, text="打开串口", command=self.toggle_port)
self.toggle_button.pack(anchor=tk.W, pady=(10, 0))
self.data_frame = ttk.Frame(master)
self.data_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=10, pady=10)
self.received_data_label = ttk.Label(self.data_frame, text="接收的数据:")
self.received_data_label.pack(anchor=tk.W)
self.received_data_text = tk.Text(self.data_frame, height=15)
self.received_data_text.pack(fill=tk.BOTH, expand=True)
self.send_data_label = ttk.Label(self.data_frame, text="发送缓冲区:")
self.send_data_label.pack(anchor=tk.W, pady=(10, 0))
self.send_data_entry = tk.Text(self.data_frame, height=5)
self.send_data_entry.pack(fill=tk.BOTH, expand=True)
self.send_button = ttk.Button(self.data_frame, text="发送", command=self.send_data)
self.send_button.pack(anchor=tk.W, pady=(10, 0))
self.send_newline_var = tk.BooleanVar()
self.send_newline_checkbox = ttk.Checkbutton(self.data_frame, text="发送回车换行", variable=self.send_newline_var)
self.send_newline_checkbox.pack(anchor=tk.W, pady=(10, 0))
self.receive_thread = None
self.stop_thread = threading.Event()
self.master.protocol("WM_DELETE_WINDOW", self.on_closing)
def refresh_ports(self):
self.ports = serial.tools.list_ports.comports()
self.port_names = [port.device for port in self.ports]
self.port_combo_box['values'] = self.port_names
def toggle_port(self):
if self.ser is None:
self.open_port()
else:
self.close_port()
def open_port(self):
selected_port = self.port_combo_box.get()
selected_baud = self.baud_combo_box.get()
if selected_port:
try:
self.ser = serial.Serial(selected_port, int(selected_baud), timeout=1)
print(f"成功打开串口: {selected_port},波特率: {selected_baud}")
self.toggle_button.config(text="关闭串口")
self.stop_thread.clear()
self.receive_thread = threading.Thread(target=self.receive_data)
self.receive_thread.start()
except serial.SerialException as e:
messagebox.showerror("错误", f"打开串口失败: {e}")
def close_port(self):
if self.ser is not None:
self.stop_thread.set()
if self.receive_thread is not None:
self.receive_thread.join() # 等待接收线程结束
self.ser.close()
self.ser = None
print("串口已关闭")
self.toggle_button.config(text="打开串口")
def receive_data(self):
while not self.stop_thread.is_set():
if self.ser.in_waiting > 0:
try:
data = self.ser.read(self.ser.in_waiting).decode('utf-8')
self.master.after(0, self.update_received_data, data)
except serial.SerialException as e:
messagebox.showerror("错误", f"接收数据失败: {e}")
self.stop_thread.wait(0.1)
def update_received_data(self, data):
self.received_data_text.insert(tk.END, data)
self.received_data_text.see(tk.END)
def send_data(self):
if self.ser is not None:
data = self.send_data_entry.get("1.0", tk.END).strip()
if data:
try:
if self.send_newline_var.get():
data += '\r\n'
self.ser.write(data.encode('utf-8'))
# 发送数据后不清空发送缓冲区
# self.send_data_entry.delete("1.0", tk.END)
except serial.SerialException as e:
messagebox.showerror("错误", f"发送数据失败: {e}")
def on_closing(self):
self.close_port()
self.master.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = SerialPortSelector(root)
root.mainloop()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。