Python3.5 tkinterGUI

来源:互联网 发布:中银通支付卡淘宝 编辑:程序博客网 时间:2024/06/06 01:58

由于最近需要做一个GUI的小项目,在tkinter和PyQt中来回纠结,最后选择了tkinter,主要是由于其grid布局方式简单,开发速度更快,并且有了ttk这个内置库以后界面也好看了很多。

界面介绍

这里写图片描述

首先主要是左边的接收和发送部分模块以及右边的功能区域了,采用了grid布局中相互嵌套的方法,如果你熟悉css布局,那这个更加小儿科了。

功能上呢能可以自动检测连接串口号,打开串口后自动接收数据,处理数据部分各自需求不一样我就不在这里细说了。外加上点击按钮发送数据,就构成这么一个实现基本功能的GUI界面了,当然串口连接使用的是Pyserial,虽然有点吐槽它内部的处理速度问题,下面介绍一下关键的接收发数据过程。

接收发数据

在这里建议大家先实现功能再进行布局,因为之前我就是布局完成后再去实现功能,发现接收发数据这里出现了问题,导致很多地方要改,而布局的内容又比较多,这样修改起来很慢,所以建议大家功能实现到哪儿,布局到哪儿,当然最开始要有一个整体的布局想法。

接收发数据这里呢,核心是要添加一个线程跟主线程并行,切记这里不能使用threading的join()方法,因为join()方法是阻塞主线程的一个方法,等待上一个线程执行完毕才能执行下一个,当然你还可以添加里面的timeout参数,表示多少s之后就不管这个线程继续下一个线程了,但是这样会造成程序使用过程中特别的卡顿,所以不建议使用join(),先来看一下代码。

def ReceiveData():    print("The receive_data threading is start")    while mySerial.isOpen():        wait = mySerial.inWaiting()        if wait and data:            res_data = mySerial.readline()            Text_get.insert(END, res_data + bytes('\n', encoding='utf8'))            mySerial.flushInput()def OpenPort():    if not mySerial.isOpen():        try:            mySerial.port = ComPort.get()            mySerial.baudrate = int(ComBaud.get())            mySerial.timeout = 0.1            mySerial.open()            Open.set('关闭串口')            if mySerial.isOpen():                t = threading.Thread(target=ReceiveData)                t.setDaemon(True)                t.start()        except:            messagebox.showinfo('错误提示', '出错啦,请检查!')    else:        mySerial.close()        Open.set('打开串口')

大家可以看到我是在打开串口的使用添加了获取数据的线程,然后实时显示在Text这个接收区显示框内的,值得注意的是Pyserial的inWaiting方法,该方法有点像java或者是C#中buffer.get()类似的方法,等待数据缓存获取完成后再进行读取数据,保证数据的完整性。

还有大家可能在很多其他GUI程序中发现大家用的是read_all()方法获取数据,我这里使用readline是因为硬件数据结构格式,这里大家可以因人而异;其次,如果使用readline,一定要设置serial的timeout属性,其意义是串口间隔多长时间读取一次串口的缓存获取数据,下面来看一下较为简单的发送数据代码。

def GetData(txt):    mySerial.write(bytes(txt.get(), encoding='utf8'))    wait = mySerial.inWaiting()    if wait:        res_data = mySerial.readline()        Text_get.insert(END, res_data + bytes('\n', encoding='utf8'))        mySerial.flushInput()def SendData():    if mySerial.isOpen():        t = threading.Thread(target=GetData, args=(Text_send, ))        t.setDaemon(True)        t.start()        t.join()

这里使用简单的write()方法将你想要发送的数据传到串口中,然后获取数据,值得注意的有两点。一是写入的使用注意是写入的是字符串string还是字节byte,二是建议大家单独增加一个线程,因为处理速度更快,这里就可以添加join()了,因为按钮发送只是单次行为,不存在一直需要获取数据的情况。

最后,我分享给大家我的程序源码的链接自行下载, 文件中的myGUI.py。其中包含了使用Pyinstaller打包的exe,至于如何打包大家自行百度一下较为简单,值得注意的是如果你想要打包windows32位的exe请使用32位的python版本和对应的Pyinstaller进行打包。

如果链接失效,可以在评论区留言,看到后更新下链接。

程序源码
程序exe

原创粉丝点击