CustomTkinter中ComboBox无法动态更新COM端口列表求助
CustomTkinter ComboBox COM端口列表不更新问题修复
问题根源
CustomTkinter的CTkComboBox组件无法通过直接赋值['values']的方式更新下拉选项,必须使用组件的configure()方法修改属性,才能触发界面刷新。直接修改字典式索引不会通知组件更新UI。
修复方案
修改runfindcomports函数中更新ComboBox的代码,将直接赋值改为调用configure()方法:
def runfindcomports(afterfirstrun=True): ports = [] # 优化端口获取逻辑,避免截取字符出错(如COM10会被误截为COM1) for info in serial.tools.list_ports.comports(): ports.append(info.device) # 直接获取完整端口名,更可靠 if afterfirstrun: # 使用configure方法更新下拉选项,触发界面刷新 combobox_1.configure(values=ports) print(ports) return ports
额外优化点
原代码中port1[0:4]的截取方式存在隐患,当端口号大于9时(如COM10),会得到错误的端口名称。改用info.device可直接获取完整的端口标识(如COM10),避免此类问题。
完整修改后的代码
import customtkinter import serial from serial.tools import list_ports customtkinter.set_appearance_mode("light") customtkinter.set_default_color_theme("blue") app = customtkinter.CTk() app.geometry("500x500") app.title("Connex Link") def runfindcomports(afterfirstrun=True): ports = [] for info in list_ports.comports(): ports.append(info.device) if afterfirstrun: combobox_1.configure(values=ports) print(ports) return ports ports = runfindcomports(False) onoroff = False ser = None # 初始化串口变量,避免未定义错误 def onswitch(): global onoroff global ser if onoroff: onoroff = False if ser and ser.is_open: ser.close() else: onoroff = True print('on') selected_port = combobox_1.get() if selected_port != "Select Com Port": ser = serial.Serial(selected_port, 9600, timeout=2) frame_1 = customtkinter.CTkFrame(master=app) frame_1.pack(pady=20, padx=60, fill="both", expand=True) label_1 = customtkinter.CTkLabel(master=frame_1, justify=customtkinter.LEFT, text='Vibrac') label_1.pack(pady=10, padx=10) combobox_1 = customtkinter.CTkComboBox(frame_1) combobox_1.pack(pady=10, padx=10) combobox_1.set("Select Com Port") combobox_1.configure(values=ports) switch_1 = customtkinter.CTkSwitch(master=frame_1, command=onswitch, text='receive') switch_1.pack(pady=10, padx=10) button_1 = customtkinter.CTkButton(master=frame_1, command=runfindcomports, text='refresh') button_1.pack(pady=10, padx=10) text_1 = customtkinter.CTkTextbox(master=frame_1, width=300, height=300) text_1.pack(pady=10, padx=10) def textfilter(bytes_data): text = str(bytes_data) text = text[2:] text = text.split('\\', 1)[0] return text def printline(): global onoroff global ser if onoroff and ser and ser.is_open: line = ser.readline() if len(line) > 2: text_1.insert("end", textfilter(line) + '\n') app.after(500, printline) app.after(500, printline) app.mainloop()
其他修复说明
- 初始化
ser变量为None,避免开关切换时出现未定义错误 - 在
onswitch函数中增加端口选择判断,防止未选端口就打开串口 - 在
printline函数中增加串口状态判断,避免串口未打开时调用ser.readline()报错
内容的提问来源于stack exchange,提问作者koorn5
相关产品推荐
相关产品推荐

