性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

痞子衡
認證:普通會員
所在專題目錄 查看專題
200行Python代碼實現(xiàn)串口調(diào)試助手(1) - 環(huán)境搭建
200行Python代碼實現(xiàn)串口調(diào)試助手(2) - 界面構建
200行Python代碼實現(xiàn)串口調(diào)試助手(3) - 功能實現(xiàn)
200行Python代碼實現(xiàn)串口調(diào)試助手(4) - 聯(lián)合調(diào)試
200行Python代碼實現(xiàn)串口調(diào)試助手(5) - 軟件優(yōu)化
200行Python代碼實現(xiàn)串口調(diào)試助手(6) - 打包發(fā)布
作者動態(tài) 更多
RT1170的FDCB竟然能允許這樣的騷操作!
4天前
MDK5.40下添加用戶下載算法FLM文件的方法
07-16 09:12
一種多MCU分時復用Flash啟動的創(chuàng)新方法(下)
06-22 10:33
一種多MCU分時復用Flash啟動的創(chuàng)新方法(上)
06-15 10:22
RT10xx系列UART SDP能設置多高波特率?
06-06 09:51

200行Python代碼實現(xiàn)串口調(diào)試助手(5) - 軟件優(yōu)化

大家好,我是痞子衡,是正經(jīng)搞技術的痞子。今天痞子衡給大家介紹的是串口調(diào)試工具pzh-py-com誕生之軟件優(yōu)化。

前面痞子衡已經(jīng)初步實現(xiàn)了pzh-py-com的串口功能,并且通過了最基本的測試,但目前的pzh-py-com相比市面上流行的串口調(diào)試工具還差得很遠,有很大的優(yōu)化空間。優(yōu)化可以從兩方面進行:一、是功能上的優(yōu)化,可以添加更多實用的功能;二、是界面效果上的優(yōu)化,可以增加一些界面動畫效果或者重新配色美化界面。下面痞子衡從這兩方面分別為pzh-py-com做一些簡單的優(yōu)化:

一、功能優(yōu)化

1.1 增強魯棒性

最開始要做的功能優(yōu)化應該是增強軟件魯棒性,即在任何異常用戶輸入的情況下,軟件都不能掛掉,痞子衡在實測中發(fā)現(xiàn)當用戶在"Com Port"里輸入的是無效串口設備號時,軟件會掛掉,因此做了以下改進,在打開設備時使用try except語句,如有異常,直接退出,不會繼續(xù)后面代碼的執(zhí)行。此類改進還有很多,不一一例舉。

class mainWin(win.com_win):

    def openClosePort( self, event ):
        if s_serialPort.isOpen():
            s_serialPort.close()
            self.m_button_openClose.SetLabel('Open')
        else:
            # ...
            self.setParitybits()
            # 添加代碼開始
            try:
                s_serialPort.open()
            except Exception, e:
                # Show warning message
                return
            # 添加代碼結束
            self.m_button_openClose.SetLabel('Close')
            # ...

1.2 自動檢測可用Port

最初版本實現(xiàn)Port口選擇是用戶按標準格式“COMx”手動輸入,但這樣有一個問題,即用戶輸入的格式有可能不合法,并且即使是一個合法的格式輸入,但也可能不是一個可用的有效Port。參照市面上流行的串口調(diào)試助手,有的是下拉菜單選擇所有COM口(比如AccessPort,這樣可以解決不合法格式輸入的問題),有的是下拉菜單選擇可用的COM口(比如sscom,這樣可以解決Port是否有效的問題),痞子衡參照sscom的做法對pzh-py-com進行了如下優(yōu)化:

class mainWin(win.com_win):

    def __init__(self, parent):
        self.refreshComPort(None)
        self.m_choice_comPort.SetSelection( 0 )

    def refreshComPort( self, event ):
        comports = list(serial.tools.list_ports.comports())
        ports = [None] * len(comports)
        for i in range(len(comports)):
            comport = list(comports[i])
            # example comport = [u'COM3', u'Intel(R) Active Management Technology - SOL (COM3)', u'PCI\\VEN_8086&DEV_9D3D&SUBSYS_06DC1028&REV_21\\3&11583659&0&B3']
            ports[i] = comport[0] + ' - ' + comport[1]
        self.m_choice_comPort.Clear()
        self.m_choice_comPort.SetItems(ports)

    def setPort ( self ):
        index = self.m_choice_comPort.GetSelection()
        comPort = self.m_choice_comPort.GetString(index)
        comPort = comPort.split(' - ')
        s_serialPort.port = comPort[0]

1.3 實現(xiàn)格式切換功能

Char/Hex格式轉換屬于比較實用的功能,一般的串口調(diào)試助手都會有這個功能,pzh-py-com之前默認總是按照Char格式來輸入和顯示,"Format"選項框的功能實際上并沒有實現(xiàn),因此痞子衡在這里加上了格式切換功能。

import formatter

s_formatter = formatter.formatter()
s_lastRecvFormat = None
s_lastSendFormat = None

class mainWin(win.com_win):

    # 函數(shù)功能實現(xiàn)
    def setSendFormat( self, event ):
        lines = self.m_textCtrl_send.GetNumberOfLines()
        if lines != 0:
            m_sendFormat = self.m_choice_sendFormat.GetString(self.m_choice_sendFormat.GetSelection())
            global s_lastSendFormat
            if s_lastSendFormat == m_sendFormat:
                return
            else:
                s_lastSendFormat = m_sendFormat
            # Get existing data from textCtrl_send
            data = ''
            for i in range(0, lines):
                data += str(self.m_textCtrl_send.GetLineText(i))
            # Convert data format according to choice_sendFormat
            if m_sendFormat == 'Char':
                status, data = s_formatter.hexToChar(data)
                if not status:
                    self.m_textCtrl_send.Clear()
                    self.m_textCtrl_send.write('Invalid format! Correct example: 12 34 56 ab cd ef')
                    return
            elif m_sendFormat == 'Hex':
                data = s_formatter.charToHex(data)
            # Re-show converted data in textCtrl_send
            self.m_textCtrl_send.Clear()
            self.m_textCtrl_send.write(data)

    def sendData( self, event ):
        if s_serialPort.isOpen():
            lines = self.m_textCtrl_send.GetNumberOfLines()
            if lines != 0:
                data = ''
                for i in range(0, lines):
                    data += str(self.m_textCtrl_send.GetLineText(i))
                # 添加代碼開始
                # Make sure data is always in 'Char' format
                m_sendFormat = self.m_choice_sendFormat.GetString(self.m_choice_sendFormat.GetSelection())
                if m_sendFormat == 'Hex':
                    status, data = s_formatter.hexToChar(data)
                    if not status:
                        self.m_textCtrl_send.Clear()
                        self.m_textCtrl_send.write('Invalid format! Correct example: 12 34 56 ab cd ef')
                        return
                # 添加代碼結束
                s_serialPort.write(data)

    # 函數(shù)功能實現(xiàn)
    def setRecvFormat( self, event ):
        lines = self.m_textCtrl_recv.GetNumberOfLines()
        if lines != 0:
            m_recvFormat = self.m_choice_recvFormat.GetString(self.m_choice_recvFormat.GetSelection())
            global s_lastRecvFormat
            if s_lastRecvFormat == m_recvFormat:
                return
            else:
                s_lastRecvFormat = m_recvFormat
            # Get existing data from textCtrl_recv
            data = ''
            for i in range(0, lines):
                data += str(self.m_textCtrl_recv.GetLineText(i))
            # Convert data format according to choice_recvFormat
            if m_recvFormat == 'Char':
                status, data = s_formatter.hexToChar(data)
            elif m_recvFormat == 'Hex':
                data = s_formatter.charToHex(data)
            # Re-show converted data in textCtrl_recv
            self.m_textCtrl_recv.Clear()
            self.m_textCtrl_recv.write(data)

    def recvData( self ):
        if s_serialPort.isOpen():
            num = s_serialPort.inWaiting()
            if num != 0:
                data = s_serialPort.read(num)
                # 添加代碼開始
                # Note: Assume that data is always in 'Char' format
                # Convert data format if dispaly format is 'Hex'
                m_recvFormat = self.m_choice_recvFormat.GetString(self.m_choice_recvFormat.GetSelection())
                if m_recvFormat == 'Hex':
                    data = s_formatter.charToHex(data)
                # 添加代碼結束
                self.m_textCtrl_recv.write(data)

發(fā)送輸入框格式切換功能實測如下,尤其是在Hex模式下,如果有異常輸入,pzh-py-com會直接清屏,并在輸入框里提示正確的示例。接收顯示框格式切換功能雷同,但并不包含異常輸入提示,因為這是個結果顯示輸出框。

1.4 啟用菜單欄

菜單欄是一個功能齊全的軟件的標配,用于實現(xiàn)各種特性功能,此處痞子衡僅添加了一個“Help”菜單,用于顯示pzh-py-com的主頁以及作者信息。首先需要在wxFormBuilder添加menu控件,然后設置回調(diào)函數(shù)名,下面是回調(diào)函數(shù)的實現(xiàn):

def showHomepageMessage( self, event ):
        messageText = (('Code: \n    https://github.com/JayHeng/pzh-py-com.git \n') +
                       ('Doc: \n    https://www.cnblogs.com/henjay724/p/9416096.html \n'))
        wx.MessageBox(messageText, "Homepage", wx.OK | wx.ICON_INFORMATION)

    def showAboutMessage( self, event ):
        messageText = (('Author: Jay Heng \n') +
                       ('Email: hengjie1989@foxmail.com \n'))
        wx.MessageBox(messageText, "About", wx.OK | wx.ICON_INFORMATION)

1.5 啟用狀態(tài)欄

狀態(tài)欄也是一般串口調(diào)試助手的標配,用于顯示發(fā)送/接收數(shù)據(jù)統(tǒng)計信息以及串口開關狀態(tài),因此痞子衡為pzh-py-com也加上了狀態(tài)欄功能,狀態(tài)欄主要分為三欄:接收數(shù)據(jù)統(tǒng)計、發(fā)送數(shù)據(jù)統(tǒng)計、串口狀態(tài)。

s_recvStatusFieldIndex = 0
s_sendStatusFieldIndex = 1
s_infoStatusFieldIndex = 2

s_recvStatusStr = 'Recv: '
s_recvTotalBytes = 0
s_sendStatusStr = 'Send: '
s_sendTotalBytes = 0

class mainWin(win.com_win):

    def openClosePort( self, event ):
        if s_serialPort.isOpen():
            s_serialPort.close()
            self.m_button_openClose.SetLabel('Open')
            # 添加代碼開始
            self.statusBar.SetStatusText(s_serialPort.name + ' is closed', s_infoStatusFieldIndex)
            # 添加代碼結束
        else:
            # 添加代碼開始
            self.statusBar.SetFieldsCount(3)
            self.statusBar.SetStatusWidths([150, 150, 400])
            # 添加代碼結束
            self.setPort()
            # ...
            self.m_button_openClose.SetLabel('Close')
            # 添加代碼開始
            self.statusBar.SetStatusText(s_recvStatusStr + str(s_recvTotalBytes), s_recvStatusFieldIndex)
            self.statusBar.SetStatusText(s_sendStatusStr + str(s_sendTotalBytes), s_sendStatusFieldIndex)
            self.statusBar.SetStatusText(s_serialPort.name + ' is open, ' +
                                               str(s_serialPort.baudrate) + ', ' +
                                               str(s_serialPort.bytesizes) + ', ' +
                                               s_serialPort.parity + ', ' +
                                               str(s_serialPort.stopbits), s_infoStatusFieldIndex)
            # 添加代碼結束
            s_serialPort.reset_input_buffer()
            # ...

    def sendData( self, event ):
        if s_serialPort.isOpen():
            lines = self.m_textCtrl_send.GetNumberOfLines()
            if lines != 0:
                # ...
                s_serialPort.write(data)
                # 添加代碼開始
                global s_sendTotalBytes
                s_sendTotalBytes += len(data)
                self.statusBar.SetStatusText(s_sendStatusStr + str(s_sendTotalBytes), s_sendStatusFieldIndex)
                # 添加代碼結束
        else:
            self.statusBar.SetStatusText(s_serialPort.name + ' is not open !!!', s_infoStatusFieldIndex)

    def recvData( self ):
        if s_serialPort.isOpen():
            num = s_serialPort.inWaiting()
            if num != 0:
                # ...
                self.m_textCtrl_recv.write(data)
                # 添加代碼開始
                global s_recvTotalBytes
                s_recvTotalBytes += len(data)
                self.statusBar.SetStatusText(s_recvStatusStr + str(s_recvTotalBytes), s_recvStatusFieldIndex)
                # 添加代碼結束

狀態(tài)欄實測功能如下:

二、界面優(yōu)化

2.1 添加串口開關亮燈效果

界面優(yōu)化的地方有很多,痞子衡簡單做了一個與串口開關按鈕同步的小燈顯示效果,當串口打開時,小燈顯示綠色;當串口關閉時,小燈顯示黑色;代碼里的實現(xiàn)其實就是兩張圖片之間的切換。

class mainWin(win.com_win):

    def openClosePort( self, event ):
        if s_serialPort.isOpen():
            s_serialPort.close()
            self.m_button_openClose.SetLabel('Open')
            # 添加代碼開始
            self.m_bitmap_led.SetBitmap(wx.Bitmap( u"../img/led_black.png?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg==,t_20", wx.BITMAP_TYPE_ANY ))
            # 添加代碼結束
        else:
            # ...
            self.m_button_openClose.SetLabel('Close')
            # 添加代碼開始
            self.m_bitmap_led.SetBitmap(wx.Bitmap( u"../img/led_green.png?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg==,t_20", wx.BITMAP_TYPE_ANY ))
            # 添加代碼結束
            # ...

至此,串口調(diào)試工具pzh-py-com誕生之軟件優(yōu)化痞子衡便介紹完畢了,掌聲在哪里~~~

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉載。授權事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 1
收藏 3
關注 41
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧