You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

其他修复说明

  1. 初始化ser变量为None,避免开关切换时出现未定义错误
  2. 在onswitch函数中增加端口选择判断,防止未选端口就打开串口
  3. 在printline函数中增加串口状态判断,避免串口未打开时调用ser.readline()报错

内容的提问来源于stack exchange,提问作者koorn5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 18:33:01