首页 > 解决方案 > 试图从串口获取数据以显示在 Tkinter 窗口中

问题描述

我正在尝试使用串行端口从充电器获取信息,我似乎无法让 Tkinter 消息框显示我正在调用的信息。我相信收到的信息很好,因为每次迭代时时间和日期仍然显示在 Power Shell 上。谁能告诉我如何在单击端口按钮时显示消息框?

# import modules
from tkinter import *
from tkinter import messagebox
import serial
from numpy import array
import string
import time
import os, sys
import datetime
from colorama import init
from termcolor import colored

init()
global testflag
global v1, v2, v3, capacity, pass_fail
testflag = 0

#setting up connection with serial port
try:
    ser = serial.Serial('COM9')
    ser.baudrate = 4800
    ser.bytesize = 8
    ser.parity = 'N'
    ser.stopbites = 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')

#defining functions for commands
def get_com():
    #initialize dictionary
    testvars = {}

    def init_testvars():
        testvars['Capacity'] = 0
        testvars['Vpack'] = 0
        testvars['V1'] = 0
        testvars['V2'] = 0
        testvars['V3'] = 0
        testvars['Current'] = 0
        testvars['Vpack'] = 0
        testvars['Temp'] = 0
        testvars['Version'] = 0
        testvars['Cycles'] = 0

    init_testvars()
    os.system('cls')


    #creating continuous loop so the program displays information as it is sent
    while True:
        lenread = 0
        while lenread < 1:
            outBytes = ser.read()           #wait for anything
            lenread = len(outBytes)
        time.sleep(4)
        data_left = ser.inWaiting()
        outBytes += ser.read(data_left)
        outStr = outBytes.decode()
        now = datetime.datetime.now()

        info = array(outStr)
        os.system('cls')

        findsum = outStr.find('V1') + outStr.find('V2')+outStr.find('V3')
        findsum += outStr.find('VPACK') + outStr.find('CAPACITY')
        if findsum != -5:
            print ("> " + now.strftime("%Y-%m-%d %H:%M:%S") + " <")
            nindex = outStr.find('V1')
            if nindex != -1:
                testvars['V1'] = float(outStr[nindex+23:nindex+28])
                v1 = "Voltage 1 = {:.3f} V".format(testvars['V1'])
            else:
                v1 = "v1 Not Found!"

            nindex = outStr.find('V2')
            if nindex != -1:
                testvars['V2'] = float(outStr[nindex+23:nindex+28])
                v2 = "Voltage 2 = {:.3f} V".format(testvars['V2'])
            else:
               v2 = "v2 Not Found!"

            nindex = outStr.find('V3')
            if nindex != -1:
                testvars['V3'] = float(outStr[nindex+23:nindex+28])
                v3 = "Voltage 3 = {:.3f} V".format(testvars['V3'])
            else:
                v3 = "v3 Not Found!"
            
            nindex = outStr.find('VPACK')
            if nindex != -1:
                testvars['Vpack'] = float(outStr[nindex+23:nindex+29])
                vpack = "VPack     = {:.3f} V".format(testvars['Vpack'])
            else:
                vpack = "vpack Not Found!"

            nindex = outStr.find('CAPACITY')
            if nindex != -1:
                testvars['Capacity']  = float(outStr[nindex+11:nindex+13])
                capacity = "Capacity  = {:.1f} %".format(testvars['Capacity'])
            else:
                capacity = "Capacity Not Found!"
        
        #creating pass/fail contraints
        v1_3 = abs(testvars['V1'] - testvars['V3'])
        v1_2 = abs(testvars['V1'] - testvars['V2'])
        v2_3 = abs(testvars['V2'] - testvars['V3'])

        #only pass when voltages are within 50V of eachother
        if ((v1_3 < 50) and (v1_2 < 50) and (v2_3 < 50)):
            pass_fail = colored("#######PASS########", "green")
        else:
            pass_fail = colored("#######FAIL#######", "red")
                            
        init_testvars()
    
        outStr = ' '

def show_com11():
    get_com()
    v1 = "V1 = " + testvars['V1']
    v2 = "/nV2 = " + testvars['V2']
    v3 = "/nV3 = " + testvars['V3']
    total = v1 + v2 + v3 + pass_fail
    ser.close()
    return messagebox.showinfo("COM11", str(total))


#creating buttons for each COM port
com11 = Button(ws, text="COM11", command = show_com11)

ws.mainloop()

请注意,我现在只在 COM11 端口上工作,但我已经包含了所有代码

更新:将代码压缩为仅询问的内容

标签: python-3.xtkinterserial-port

解决方案


示例代码:

import tkinter
from tkinter import *
import numpy as np
from tkinter import messagebox

import time

#luodaan kuva...
ikkuna=tkinter.Tk()
ikkuna.title("Serial data read & show values & message box -example")
ikkuna.geometry("800x400")


kanvaasi=Canvas(ikkuna,width=800,height=400)
kanvaasi.pack(fill="both",expand=True)

kanvaasi.create_text(370,80,text="V1")
kanvaasi.create_text(370,130,text="V2")
kanvaasi.create_text(370,180,text="V3")
kanvaasi.create_text(370,220,text="VPack")
kanvaasi.create_text(370,270,text="Capacity")

def read():
    global v1,v2,v3,vpack,capacity
    global kv1,kv2,kv3,kv4,kv5

    #this is only simulation, in real case replace the simulation code with the real one...
    v1=np.random.random(1)[0].round(decimals=2)
    v2=np.random.random(1)[0].round(decimals=2)
    v3=np.random.random(1)[0].round(decimals=2)
    vpack=np.random.random(1)[0].round(decimals=2)
    capacity=np.random.random(1)[0].round(decimals=2)
    #...end of simulation

    try:
        kanvaasi.delete(kv1)
        kanvaasi.delete(kv2)
        kanvaasi.delete(kv3)
        kanvaasi.delete(kv4)
        kanvaasi.delete(kv5)
    except:
        pass

    #let's update the tkinter accordingly...
    kv1=kanvaasi.create_text(430,80,text=v1)
    kv2=kanvaasi.create_text(430,130,text=v2)
    kv3=kanvaasi.create_text(430,180,text=v3)
    kv4=kanvaasi.create_text(430,220,text=vpack)
    kv5=kanvaasi.create_text(430,270,text=capacity)

    #if some rules are true, let's also show a message box...
    if v1>0.5:
        messagebox.showinfo(title='Serial',message=''.join(['V1 = ',np.str(v1)]))
    if v2>0.5:
        messagebox.showinfo(title='Serial',message=''.join(['V2 = ',np.str(v2)]))
    if v3>0.5:
        messagebox.showinfo(title='Serial',message=''.join(['V3 = ',np.str(v3)]))
    if vpack>0.5:
        messagebox.showinfo(title='Serial',message=''.join(['Vpack = ',np.str(vpack)]))
    if capacity>0.5:
        messagebox.showinfo(title='Serial',message=''.join(['Capacity = ',np.str(capacity)]))


painike1=Button(ikkuna,text="Read",command=read,height=14,width=20)
painike1_ikkuna=kanvaasi.create_window(120,70,anchor="nw",window=painike1)


ikkuna.mainloop()

...建议您如何实现 tkinter 部分,了解如何显示串行数据中的值,以及如何显示消息框。请从您的原始代码中复制并粘贴您的基本代码部分 - 触摸 - 就是这样!

在此处输入图像描述


推荐阅读