Python使用Pyserial和wxpython进行高斯计读取界面设计——grid表格与按键结合

高斯计读取软件(未完成)

最近在用Python对高斯计进行数据读取,写着写着,就把界面也搞出来了,不过还是有点问题,没办法任意点开始,一旦出错就要重头再来,很~不人性化,后面把读取函数再改改。下面是代码,仅供参考,希望对大家有帮助:

# coding UTF-8
import glob
import os
import threading
import time
import serial
import wx
import xlwt
import wx.grid
from serial.tools import list_ports
from Output_excel import set_style


##############################################################
# 表格设置部分
##############################################################
class GridFrame(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1)

        # grid = wx.grid.Grid(self, -1)
        self.CreateGrid(14, 14)
        n = 0
        m = 0
        while n <= 13:
            self.SetColSize(col=n, width=80)
            n = n + 1
            # print(n)
        else:
            print('Finished col')
        while m <= 13:
            self.SetRowSize(m, 30)
            m = m + 1
            # print(m)
        else:
            print('Finished row')

        self.SetCellValue(0, 0, 'Data')
        self.SetCellTextColour(0, 0, wx.BLACK)
        self.SetCellBackgroundColour(0, 0, wx.LIGHT_GREY)

        a = 1
        b = 6
        while a <= 7:
            while b >= 0:
                self.SetCellValue(a, 0, 'Z' + str(b))
                self.SetCellTextColour(a, 0, wx.BLACK)
                self.SetCellBackgroundColour(a, 0, wx.LIGHT_GREY)
                b = b - 1
                a = a + 1
                # print('Z' + str(b))
                # print(a)
        c = 8
        d = 1
        while c <= 13:
            while d <= 6:
                self.SetCellValue(c, 0, '-Z' + str(d))
                self.SetCellTextColour(c, 0, wx.RED)
                self.SetCellBackgroundColour(c, 0, wx.LIGHT_GREY)
                d = d + 1
                c = c + 1
                # print('Z' + str(d))
                # print(c)
        e = 1
        p = 0
        while e <= 12:
            while p <= 11:
                self.SetCellValue(0, e, str(30 * p) + '°')
                self.SetCellTextColour(0, e, wx.BLUE)
                self.SetCellBackgroundColour(0, e, wx.LIGHT_GREY)
                e = e + 1
                p = p + 1
        self.SetCellValue(0, 13, 'B0')
        self.SetCellTextColour(0, 13, wx.RED)
        self.SetCellBackgroundColour(0, 13, wx.LIGHT_GREY)


############################################################
# 串口连接部分
############################################################

def SerialFrame(ComNum, BaudRate, Bytesize, Parity, Stopbits):
    try:
        ser = serial.Serial().__init__(port=ComNum, baudrate=int(BaudRate), bytesize=int(Bytesize),
                                            parity=Parity, stopbits=int(Stopbits))
        # print('open port success')
        ser.close()
    except :
        wx.MessageBox('open com fail', 'error')
        wx.App().OnExit()
        # wx.PyApp.OnExit()
        return
    # global ser


##############################################################
# 主窗口设置部分
##############################################################
class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, 'Guass_Measurement', size=(1250, 600),
                          style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
        panel = wx.Panel(self, -1)

        ############################################################
        # 按钮设置
        ############################################################
        self.v_sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.comlinkbutton = wx.ToggleButton(panel, -1, u'连接串口')
        self.Bind(wx.EVT_TOGGLEBUTTON, self.ComLink, self.comlinkbutton)
        self.ClearTabbutton = wx.Button(panel, -1, u'清空接收列表')
        self.Bind(wx.EVT_BUTTON, self.OnClearTableCH, self.ClearTabbutton)
        self.Receievebutton = wx.Button(panel, -1, u'开始采集')
        self.Bind(wx.EVT_BUTTON, self.OnReceieveCH, self.Receievebutton)
        self.Stopreceievebutton = wx.Button(panel, -1, u'停止采集')
        self.Bind(wx.EVT_BUTTON, self.OnStopreceieveCH, self.Stopreceievebutton)
        # self.Countbutton = wx.Button(panel, -1, u'计算数据')
        # self.Bind(wx.EVT_BUTTON, self.OnCountCH, Countbutton)
        self.outputdatabutton = wx.Button(panel, -1, u'导出Excel')
        self.Bind(wx.EVT_BUTTON, self.OnSaveAs, self.outputdatabutton)

        self.v_sizer.Add(self.comlinkbutton, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
        self.v_sizer.Add(self.ClearTabbutton, proportion=0, flag=wx.ALL, border=5)
        # v_sizer.Add(self.Countbutton, proportion=0, flag=wx.ALL, border=5)
        self.v_sizer.Add(self.Receievebutton, proportion=0, flag=wx.ALL, border=5)
        self.v_sizer.Add(self.Stopreceievebutton, proportion=0, flag=wx.ALL, border=5)
        self.v_sizer.Add(self.outputdatabutton, proportion=0, flag=wx.ALL, border=5)

        ############################################################
        # 静态文本框及下拉表单设置
        ############################################################
        self.h_sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.comtxt = wx.StaticText(panel, -1, u'  串口:  ')
        # 先识别系统再寻找可用串口形成表单
        if os.name == 'posix':
            comlist = glob.glob('/dev/cu.*')
        else:
            comlist = [port[0] for port in list_ports.comports()]  # 串口列表,先查找,后生成列表
        self.comlistctr = wx.Choice(panel, -1, choices=comlist)
        self.Bind(wx.EVT_CHOICE, self.OncomlistCH, self.comlistctr)  # 串口表单下拉响应函数

        self.baudratetxt = wx.StaticText(panel, -1, u'  波特率:  ')
        baudratelist = ['300', '600', '1200', '2400', '4800', '9600', '19200']
        self.baudratelistctr = wx.Choice(panel, -1, (70, 320), choices=baudratelist)
        self.Bind(wx.EVT_CHOICE, self.OnbaudrateCH, self.baudratelistctr)  # 波特率下拉列表响应函数

        self.bytesizetxt = wx.StaticText(panel, -1, u'  数据位:  ')
        bytesizelist = ['6', '7', '8']
        self.bytesizelistctr = wx.Choice(panel, -1, (70, 350), choices=bytesizelist)
        self.Bind(wx.EVT_CHOICE, self.OnBytesizeCH, self.bytesizelistctr)  # 数据位下拉列表响应函数

        self.paritytxt = wx.StaticText(panel, -1, u'  奇偶校验位:  ')
        paritylist = ['N', 'E', 'O']
        self.paritylistctr = wx.Choice(panel, -1, (250, 350), choices=paritylist)
        self.Bind(wx.EVT_CHOICE, self.OnParityCH, self.paritylistctr)  # 奇偶校验下拉列表响应函数

        self.stopbitstxt = wx.StaticText(panel, -1, u'  停止位:  ')
        stopbitslist = ['1', '2', '3', '4', '5']
        self.stopbitslistctr = wx.Choice(panel, -1, (70, 380), choices=stopbitslist)
        self.Bind(wx.EVT_CHOICE, self.OnStopbitsCH, self.stopbitslistctr)  # 停止位下拉列表响应函数

        # 下拉表单选择获取
        index = self.baudratelistctr.GetSelection()
        BaudRate = self.baudratelistctr.GetString(index)  # 获取波特率
        index = self.comlistctr.GetSelection()
        ComNum = self.comlistctr.GetString(index)  # 获取串口
        index = self.bytesizelistctr.GetSelection()
        Bytesize = self.bytesizelistctr.GetString(index)  # 获取数据位
        index = self.paritylistctr.GetSelection()
        Parity = self.paritylistctr.GetString(index)  # 获取奇偶校验位
        index = self.stopbitslistctr.GetSelection()
        Stopbits = self.stopbitslistctr.GetString(index)  # 获取停止位

        # 获取初始选择项
        self.baudratelistctr.SetSelection(3)
        self.comlistctr.SetSelection(0)
        self.bytesizelistctr.SetSelection(2)
        self.paritylistctr.SetSelection(0)
        self.stopbitslistctr.SetSelection(0)

        # 排版,按照“文字:下拉表单”格式
        self.h_sizer.Add(self.comtxt, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.comlistctr, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.baudratetxt, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.baudratelistctr, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.bytesizetxt, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.bytesizelistctr, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.paritytxt, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.paritylistctr, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.stopbitstxt, proportion=0, flag=wx.EXPAND, border=5)
        self.h_sizer.Add(self.stopbitslistctr, proportion=0, flag=wx.EXPAND, border=5)

        ############################################################
        # 加入表格后的整体布局设置
        ############################################################
        self.grid = GridFrame(panel)
        self.ser = SerialFrame(ComNum, BaudRate, Bytesize, Parity, Stopbits)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.v_sizer, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.h_sizer, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.grid, proportion=1, flag=wx.EXPAND, border=5)
        panel.SetSizer(sizer)

    ##################################################################
    # 响应函数部分
    ##################################################################
    def OncomlistCH(self, event):
        index = self.comlistctr.GetSelection()
        ComNum = self.comlistctr.GetString(index)  # 获取com口
        try:
            self.ser.setPort(ComNum)
        except:
            wx.MessageBox('change port fail', 'error')
            return None
        self.ser.inWaiting()

    def ComLink(self, event):
        global ComNum
        index = self.comlistctr.GetSelection()
        ComNum = self.comlistctr.GetString(index)  # 获取com口
        m = self.comlinkbutton.GetValue()
        if m:
            self.ser.open()
            self.comlinkbutton.SetLabel(u'断开串口')
        else:
            self.ser.close()
            self.comlinkbutton.SetLabel(u'连接串口')

    def OnbaudrateCH(self, event):
        global BaudRate
        if self.ser.isOpen():
            index = self.baudratelistctr.GetSelection()
            BaudRate = self.baudratelistctr.GetString(index)
            self.ser.baudrate.setter(BaudRate)
            self.ser.inWaiting()
        else:
            wx.MessageBox('Port is not open')
            return

    def OnBytesizeCH(self, event):
        global Bytesize
        if self.ser.isOpen():
            index = self.bytesizelistctr.GetSelection()
            Bytesize = self.bytesizelistctr.GetString(index)
            self.ser.bytesize.setter(Bytesize)
            self.ser.inWaiting()
        else:
            wx.MessageBox('Port is not open')
            return

    def OnParityCH(self, event):
        global Parity
        if self.ser.isOpen():
            index = self.paritylistctr.GetSelection()
            Parity = self.paritylistctr.GetString(index)
            self.ser.baudrate.setter(Parity)
            self.ser.inWaiting()
        else:
            wx.MessageBox('Port is not open')
            return

    def OnStopbitsCH(self, event):
        global Stopbits
        if self.ser.isOpen():
            index = self.stopbitslistctr.GetSelection()
            Stopbits = self.stopbitslistctr.GetString(index)
            self.ser.stopbits.setter(Stopbits)
            self.ser.inWaiting()
        else:
            wx.MessageBox('Port is not open')
            return

    def OnClearTableCH(self, event):
        for q in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
            for p in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
                self.grid.SetCellValue(q, p, ' ')
        else:
            wx.MessageBox('data had been cleared')

    # def OnCountCH(self,event):
    def readgrid(self, event):
        degree = 1
        if self.ser.isOpen():
            for z in [7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]:
                while degree <= 13:
                    time.sleep(5)   # 等待5秒
                    self.is_stoping = True
                    r = self.ser.inWaiting()
                    data = self.ser.read(r)
                    data = data.decode('utf8').split('\r\n')    #断句
                    record_data = list(filter(lambda x: len(x)>0, data))    # 筛选
                    r_d = list()
                    for store_data in record_data:
                        store_data = store_data.strip()
                        if store_data.startswith('L'):   # L开头的数据才是有效的,数据格式:L21.5977963F
                            r_d.append(store_data)
                        else:
                            wx.MessageBox('Data is invalid')
                    t1 = list(map(lambda x: float(x[1:-1]), r_d))   # 取数去字母
                    if len(t1) > 0:
                        d2 = sum(t1)/len(t1)
                        self.grid.GetCellValue(z, degree, d2)
                    else:
                        wx.MessageBox('Not enough data')
                    degree = degree + 1
                    print('\a')
                    if self.is_stoping:
                        break
            else:
                # print('Finished')
                wx.MessageBox('Finished')

    def OnReceieveCH(self, event):
        if self.ser.isOpen():
            threading.Timer(3, self.readgrid).start()
            # T = threading.Timer(3).cancel()
        else:
            wx.MessageBox('port is not open')

    def OnStopreceieveCH(self, event):
        if self.ser.isOpen():
            self.is_stoping = False
            wx.MessageBox('Stopping!')
        else:
            wx.MessageBox('port is not open')

    def OnB0receieveCH(self, event):
        # panel = wx.Panel(self, -1)
        if self.ser.isOpen():
            for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
                wx.MessageBox('开始采集B0点数据')
                y = self.ser.inWaiting()
                data1 = self.ser.read(y)
                self.grid.SetCellValue(x, 13, data1.decode('utf8'))
                x = x + 1
            else:
                wx.MessageBox('采集完成')
        else:
            wx.MessageBox('port is not open')

# 保存文件函数
    def SaveFile(self):
        if self.filename:
            q = open(self.filename, 'w')
            # 写excel
            global f, sheet1
            f = xlwt.Workbook()  # 创建工作簿

# 创建一个sheet表格
            sheet1 = f.add_sheet(u'sheet1', cell_overwrite_ok=True)  # 创建sheet
            row0 = [u'Data', u'30°', u'60°', u'90°', u'120°', u'150°', u'180°',
                    u'210°', u'240°', u'270°', u'300°', u'330°', u'B0']
            column0 = [u'Z6', u'Z5', u'Z4', u'Z3', u'Z2', u'Z1', u'Z0', u'-Z1',
                       u'-Z2', u'-Z3', u'-Z4', u'-Z5', u'-Z6']
            title = [u'Gauss_Measurement_Data']

            # 生成标题
            sheet1.write_merge(0, 0, 0, 12, title, set_style('Times New Roman', 300, True))

            # 生成第一行
            for i in range(0, len(row0)):
                sheet1.write(1, i, row0[i], set_style('Times New Roman', 220, True))

            # 生成第一列
            i = 1
            j = 0
            while i <= 13:
                while j <= 12:
                    sheet1.write(i, 0, column0[j], set_style('Times New Roman', 220, True))
                    j = j + 1
                    i = i + 1
            else:
                print('Finished')

            # # f.save('demo1.xlsx')
            # # panel = wx.Panel(self)

            for k in [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]:
                for l in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]:
                    w = self.grid.GetCellValue(k, l)
                    sheet1.write(k, l, w, set_style('Times New Roman', 220, True))
                    l = l + 1
                k = k + 1
                f.save(self.filename)  # 保存文件
                q.close()
            else:
                wx.MessageBox('已导出Excel')

    def OnSave(self, event):

        if not self.filename:
            self.OnSaveAs(event)
        else:
            self.SaveFile()

# 弹出保存对话框
    def OnSaveAs(self, event):

        file_wildcard = "Excel files(*.xls)|*.xls|All files(*.*)|*.*"
        dlg = wx.FileDialog(self,
                            "Save files as ...",
                            os.getcwd(),
                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
                            wildcard=file_wildcard)
        if dlg.ShowModal() == wx.ID_OK:
            filename = dlg.GetPath()
            if not os.path.splitext(filename)[1]:  # 如果没有文件名后缀
                filename = filename + '.xls'
            self.filename = filename
            self.SaveFile()
        dlg.Destroy()


class MyApp(wx.App):
    def OnInit(self):
        print("MyApp OnInit")
        self.frame = TestFrame(None)
        id = self.frame.GetId()
        self.frame.Show(True)
        return True

    def OnExit(self):
        print("MyApp OnExit")
        self.frame.ser.close()
        time.sleep(2)


if __name__ == "__main__":
    "Main Start"
    app = MyApp()
    "Before MainLoop"

    app.MainLoop()
    "After MainLoop"

效果图如下:
高斯计效果图
生成Excel参考:https://www.cnblogs.com/linyfeng/p/7123423.html
wxpython使用参考:https://wiki.woodpecker.org.cn/moin/WxPythonInAction
保存文件参考:https://blog.csdn.net/letv0907/article/details/38854427

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值