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

如何实现点击Tkinter按钮弹出messagebox显示串口读取的充电器数据

问题原因

  • Tkinter主线程被阻塞:get_com()函数内置无限while True循环+time.sleep(),会长期占用UI主线程资源,导致Tkinter无法处理点击、弹窗等UI事件,永远执行不到messagebox相关代码
  • 布局缺失:按钮创建后没有调用pack()/grid()等布局方法,不会在窗口中显示,无法触发点击事件
  • 变量作用域错误:testvars是get_com()内部的局部变量,show_com11()无法直接访问;且get_com()每次读取完数据后都会调用init_testvars()重置所有参数,就算能拿到变量也都是初始0值
  • 代码细节错误:串口参数拼写错误ser.stopbites应为ser.stopbits、换行符写反为/n应为\n、当前代码串口硬编码为COM9和你要调试的COM11不匹配、colored()生成的带颜色控制字符无法在Tkinter的messagebox中正常显示会出现乱码

修复方案

  1. 去掉get_com()中的无限循环,改成点击按钮时单次读取串口数据
  2. 补充按钮布局逻辑,确保按钮可以正常显示点击
  3. 调整变量作用域,让读取到的测试参数可以正常返回给弹窗调用
  4. 修正所有细节拼写错误,移除messagebox中不支持的带颜色字符串
  5. 串口读取逻辑调整为单次读取后直接返回数据,不要提前重置有效参数

修改后可运行代码

# import modules
from tkinter import *
from tkinter import messagebox
import serial
import time
import sys
import datetime

global testflag
testflag = 0

# 串口配置调整为COM11,修正stopbits参数错误
try:
    ser = serial.Serial('COM11')
    ser.baudrate = 4800
    ser.bytesize = 8
    ser.parity = 'N'
    ser.stopbits = 1
    ser.timeout = 40
except:
    print("#################################################")
    print("# Serial Port could not be found. Exiting ..... #")
    print("#################################################")
    sys.exit()


# configure workspace
ws = Tk()
ws.title("COM Ports")
ws.geometry('500x150')

# 修改get_com为单次读取,返回有效数据
def get_com():
    testvars = {}
    def init_testvars():
        testvars['Capacity'] = 0
        testvars['Vpack'] = 0
        testvars['V1'] = 0
        testvars['V2'] = 0
        testvars['V3'] = 0
        testvars['Current'] = 0
        testvars['Temp'] = 0
        testvars['Version'] = 0
        testvars['Cycles'] = 0

    init_testvars()
    # 移除无限循环,单次读取数据
    lenread = 0
    while lenread < 1:
        outBytes = ser.read()
        lenread = len(outBytes)
    time.sleep(4)
    data_left = ser.inWaiting()
    outBytes += ser.read(data_left)
    outStr = outBytes.decode()
    now = datetime.datetime.now()

    print ("> " + now.strftime("%Y-%m-%d %H:%M:%S") + " <")
    findsum = outStr.find('V1') + outStr.find('V2')+outStr.find('V3')
    findsum += outStr.find('VPACK') + outStr.find('CAPACITY')
    if findsum != -5:
        nindex = outStr.find('V1')
        if nindex != -1:
            testvars['V1'] = float(outStr[nindex+23:nindex+28])
        nindex = outStr.find('V2')
        if nindex != -1:
            testvars['V2'] = float(outStr[nindex+23:nindex+28])
        nindex = outStr.find('V3')
        if nindex != -1:
            testvars['V3'] = float(outStr[nindex+23:nindex+28])
        nindex = outStr.find('VPACK')
        if nindex != -1:
            testvars['Vpack'] = float(outStr[nindex+23:nindex+29])
        nindex = outStr.find('CAPACITY')
        if nindex != -1:
            testvars['Capacity']  = float(outStr[nindex+11:nindex+13])
    
    # 计算 pass/fail 结果,移除不支持的colored样式
    v1_3 = abs(testvars['V1'] - testvars['V3'])
    v1_2 = abs(testvars['V1'] - testvars['V2'])
    v2_3 = abs(testvars['V2'] - testvars['V3'])

    if ((v1_3 < 50) and (v1_2 < 50) and (v2_3 < 50)):
        pass_fail = "\n#######PASS########"
    else:
        pass_fail = "\n#######FAIL#######"

    # 返回读取到的参数和结果
    return testvars, pass_fail

def show_com11():
    testvars, pass_fail = get_com()
    # 修正换行符错误
    v1 = "V1 = {:.3f} V".format(testvars['V1'])
    v2 = "\nV2 = {:.3f} V".format(testvars['V2'])
    v3 = "\nV3 = {:.3f} V".format(testvars['V3'])
    total = v1 + v2 + v3 + pass_fail
    ser.close()
    messagebox.showinfo("COM11", str(total))


# 补充按钮布局
com11 = Button(ws, text="COM11", command = show_com11)
com11.pack(pady=50)

ws.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 04:54:01