
powershell展开代码pip install pyserial
python展开代码import tkinter as tk
from tkinter import ttk
import serial
import threading
class info_window:
    def __init__(self, in_str, parent):
        self.parent = parent  # 保存父窗口对象
        self.window = tk.Toplevel(parent)
        self.window.title("提示")
        self.window.iconbitmap('1.ico')
        self.window.geometry("220x60")
        label = tk.Label(self.window, text=in_str)
        buttonOK = tk.Button(self.window, text="OK", command=self.button_ok)
        label.pack(side=tk.TOP)
        buttonOK.pack(side=tk.BOTTOM)
        # 移动到parent屏幕中央
        self.window.update()
        x = self.parent.winfo_x() + (self.parent.winfo_width() - self.window.winfo_reqwidth()) / 2
        y = self.parent.winfo_y() + (self.parent.winfo_height() - self.window.winfo_reqheight()) / 2
        self.window.geometry("+%d+%d" % (x, y))
    def button_ok(self):
        self.window.destroy()
class main_gui:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("代做QQ742971636")
        self.window.iconbitmap('1.ico')
        self.uartState = False  # is uart open or not
        self.is_running = True
        # 帧布:1
        config_frame = tk.Frame(self.window)
        config_frame.grid(row=1, column=1)
        label_com = tk.Label(config_frame, text="COMx: ")
        self.COM = tk.StringVar(value="COM4")
        ertryCOM = tk.Entry(config_frame, textvariable=self.COM)
        label_com.grid(row=1, column=1, padx=5, pady=3)
        ertryCOM.grid(row=1, column=2, padx=5, pady=3)
        label_baudrate = tk.Label(config_frame, text="波特率: ")
        self.Baudrate = tk.IntVar(value=9600)
        ertryBaudrate = tk.Entry(config_frame, textvariable=self.Baudrate)
        label_baudrate.grid(row=1, column=3, padx=5, pady=3)
        ertryBaudrate.grid(row=1, column=4, padx=5, pady=3)
        labelParity = tk.Label(config_frame, text="校验位: ")
        self.Parity = tk.StringVar(value="NONE")
        comboParity = ttk.Combobox(config_frame, width=17, textvariable=self.Parity)
        comboParity["values"] = ("NONE", "ODD", "EVEN", "MARK", "SPACE")
        comboParity["state"] = "readonly"
        labelParity.grid(row=2, column=1, padx=5, pady=3)
        comboParity.grid(row=2, column=2, padx=5, pady=3)
        labelStopbits = tk.Label(config_frame, text="停止位: ")
        self.Stopbits = tk.StringVar(value="1")
        comboStopbits = ttk.Combobox(config_frame, width=17, textvariable=self.Stopbits)
        comboStopbits["values"] = ("1", "1.5", "2")
        comboStopbits["state"] = "readonly"
        labelStopbits.grid(row=2, column=3, padx=5, pady=3)
        comboStopbits.grid(row=2, column=4, padx=5, pady=3)
        labelDatabits = tk.Label(config_frame, text="数据位: ")
        self.Databits = tk.StringVar(value="8")
        comboDatabits = ttk.Combobox(config_frame, width=17, textvariable=self.Databits)
        comboDatabits["values"] = ("8", "7", "6", "5")
        comboDatabits["state"] = "readonly"
        labelDatabits.grid(row=3, column=1, padx=5, pady=3)
        comboDatabits.grid(row=3, column=2, padx=5, pady=3)
        # 帧布:2
        frame_open_serial = tk.Frame(self.window)
        frame_open_serial.grid(row=2, column=1)
        self.buttonSS = tk.Button(frame_open_serial, text="打开串口", command=self.open_serial)
        self.buttonSS.pack(side=tk.BOTTOM)
        # serial object
        self.ser = serial.Serial()
        self.read_data_from_serialThread = threading.Thread(target=self.read_data_from_serial)
        self.read_data_from_serialThread.start()
        # 帧布:3
        rev_frame = tk.Frame(self.window)
        rev_frame.grid(row=3, column=1)
        labelOutText = tk.Label(rev_frame, text="接收数据:")
        labelOutText.grid(row=1, column=1, padx=3, pady=2, sticky=tk.W)
        rev_frameSon = tk.Frame(rev_frame)
        rev_frameSon.grid(row=2, column=1)
        scrollbarRecv = tk.Scrollbar(rev_frameSon)
        scrollbarRecv.pack(side=tk.RIGHT, fill=tk.Y)
        self.OutputText = tk.Text(rev_frameSon, wrap=tk.WORD, width=60, height=20, yscrollcommand=scrollbarRecv.set)
        self.OutputText.pack()
        # 帧布:4
        clear_frame = tk.Frame(self.window)
        clear_frame.grid(row=4, column=1)
        self.buttonClear = tk.Button(clear_frame, text="清空", command=self.clear_received_data)
        self.buttonClear.pack(side=tk.BOTTOM)
        # 帧布:5
        transfer_frame = tk.Frame(self.window)
        transfer_frame.grid(row=5, column=1)
        labelInText = tk.Label(transfer_frame, text="发送数据:")
        labelInText.grid(row=1, column=1, padx=3, pady=2, sticky=tk.W)
        transfer_frameSon = tk.Frame(transfer_frame)
        transfer_frameSon.grid(row=2, column=1)
        scrollbarTrans = tk.Scrollbar(transfer_frameSon)
        scrollbarTrans.pack(side=tk.RIGHT, fill=tk.Y)
        self.InputText = tk.Text(transfer_frameSon, wrap=tk.WORD, width=60, height=5, yscrollcommand=scrollbarTrans.set)
        self.InputText.insert(tk.END, "qq742971636代码测试\r\n")
        self.InputText.pack()
        # 帧布:6
        send_frame = tk.Frame(self.window)
        send_frame.grid(row=6, column=1)
        self.buttonSend = tk.Button(send_frame, text="发送", command=self.send_data_to_serial)
        self.buttonSend.pack(side=tk.BOTTOM)
        self.window.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.window.mainloop()
    def clear_received_data(self):
        self.OutputText.delete('1.0', tk.END)
    def open_serial(self):
        if self.uartState:
            self.ser.close()
            self.buttonSS["text"] = "打开串口"
            self.uartState = False
        else:
            # restart serial port
            self.ser.port = self.COM.get()
            self.ser.baudrate = self.Baudrate.get()
            strParity = self.Parity.get()
            if strParity == "NONE":
                self.ser.parity = serial.PARITY_NONE
            elif strParity == "ODD":
                self.ser.parity = serial.PARITY_ODD
            elif strParity == "EVEN":
                self.ser.parity = serial.PARITY_EVEN
            elif strParity == "MARK":
                self.ser.parity = serial.PARITY_MARK
            elif strParity == "SPACE":
                self.ser.parity = serial.PARITY_SPACE
            strStopbits = self.Stopbits.get()
            if strStopbits == "1":
                self.ser.stopbits = serial.STOPBITS_ONE
            elif strStopbits == "1.5":
                self.ser.stopbits = serial.STOPBITS_ONE_POINT_FIVE
            elif strStopbits == "2":
                self.ser.stopbits = serial.STOPBITS_TWO
            # 数据位8位
            strDatabits = self.Databits.get()
            if strDatabits == "8":
                self.ser.bytesize = serial.EIGHTBITS
            elif strDatabits == "7":
                self.ser.bytesize = serial.SEVENBITS
            elif strDatabits == "6":
                self.ser.bytesize = serial.SIXBITS
            elif strDatabits == "5":
                self.ser.bytesize = serial.FIVEBITS
            try:
                self.ser.open()
            except:
                infromStr = "不能打开串口 " + self.ser.port
                info_window(infromStr, self.window)
            if self.ser.isOpen():  # open success
                self.buttonSS["text"] = "关闭串口"
                self.uartState = True
## 实验报告:串口通信图形用户界面设计与实现
### 背景
本实验旨在设计和实现一个基于Python的图形用户界面(GUI),用于通过串口进行数据传输和接收。该界面允许用户配置串口参数,如端口号、波特率、校验位、停止位和数据位,并实现数据的发送与接收。串口通信在嵌入式系统、物联网设备以及工业控制等领域中广泛应用,能够实现不同设备之间的可靠通信。
### 器件与工具
1. 计算机
2. Python 3.x
3. Tkinter库(用于GUI开发)
4. PySerial库(用于串口通信)
5. 串口设备(如开发板、传感器等)
### 硬件连接
1. 将计算机通过USB连接到串口设备。
2. 确认串口设备的端口号(如COM4)。
3. 根据设备的规格设置合适的波特率、校验位、停止位和数据位。
### 设计原理
本实验通过Tkinter库创建一个图形用户界面,用户可以在界面中配置串口参数并进行数据的发送和接收。PySerial库用于实现串口通信。界面包括以下功能模块:
1. 串口配置模块:用户可以选择端口号、波特率、校验位、停止位和数据位。
2. 串口控制模块:打开和关闭串口。
3. 数据接收模块:显示接收到的数据。
4. 数据发送模块:用户输入要发送的数据并发送到串口。
### 电路原理
电路连接较为简单,计算机通过USB接口与串口设备相连。串口设备的TX(发送)引脚连接到计算机的RX(接收)引脚,RX引脚连接到计算机的TX引脚,GND引脚连接到计算机的GND引脚。
### 程序原理
程序使用Tkinter库创建主窗口和各个子窗口,使用PySerial库实现串口的打开、关闭、读写操作。程序包括以下几个主要部分:
#### 串口配置
串口配置部分通过创建文本框和下拉菜单,供用户输入和选择端口号、波特率、校验位、停止位和数据位。以下代码片段展示了如何创建这些配置选项:
```python
config_frame = tk.Frame(self.window)
config_frame.grid(row=1, column=1)
label_com = tk.Label(config_frame, text="COMx: ")
self.COM = tk.StringVar(value="COM4")
ertryCOM = tk.Entry(config_frame, textvariable=self.COM)
label_com.grid(row=1, column=1, padx=5, pady=3)
ertryCOM.grid(row=1, column=2, padx=5, pady=3)
label_baudrate = tk.Label(config_frame, text="波特率: ")
self.Baudrate = tk.IntVar(value=9600)
ertryBaudrate = tk.Entry(config_frame, textvariable=self.Baudrate)
label_baudrate.grid(row=1, column=3, padx=5, pady=3)
ertryBaudrate.grid(row=1, column=4, padx=5, pady=3)
串口控制部分包括打开和关闭串口的功能,通过点击按钮触发相应的事件。以下代码展示了如何实现串口的打开和关闭:
python展开代码
def open_serial(self):
    if self.uartState:
        self.ser.close()
        self.buttonSS["text"] = "打开串口"
        self.uartState = False
    else:
        self.ser.port = self.COM.get()
        self.ser.baudrate = self.Baudrate.get()
        self.ser.open()
        if self.ser.isOpen():
            self.buttonSS["text"] = "关闭串口"
            self.uartState = True
数据接收部分通过创建一个线程不断读取串口数据,并将数据显示在文本框中:
python展开代码
self.read_data_from_serialThread = threading.Thread(target=self.read_data_from_serial)
self.read_data_from_serialThread.start()
def read_data_from_serial(self):
    while self.is_running:
        if self.ser.isOpen():
            data = self.ser.read_all()
            if data:
                self.OutputText.insert(tk.END, data.decode('utf-8'))
                self.OutputText.see(tk.END)
数据发送部分允许用户在文本框中输入要发送的数据,并通过点击按钮发送数据到串口:
python展开代码
def send_data_to_serial(self):
    if self.ser.isOpen():
        data = self.InputText.get("1.0", tk.END).strip()
        self.ser.write(data.encode('utf-8'))
通过上述设计和实现,成功开发了一个功能完整的串口通信图形用户界面。用户可以方便地配置串口参数,打开和关闭串口,发送和接收数据。该界面运行稳定,能够满足基本的串口通信需求。
本实验通过使用Tkinter和PySerial库,实现了一个简单但功能强大的串口通信图形用户界面。该界面为用户提供了友好的操作方式,便于进行串口通信的配置和数据传输。未来可以在此基础上扩展更多功能,如增加日志记录、数据分析等。
Python官方文档
Tkinter库使用手册
PySerial库使用手册
资源


本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!