【PySide6】Qt 实战-串口调试助手-给窗口添加控件和布局(3)

之前我们成功运行了一个空白的窗体,我们需要继续添加内容到这个窗口内,才能让程序和我们交互起来,才能得到一个图形用户界面(Graphic User Interface,GUI)

标签(QLabel)

标签通常用于显示一些只读的字符,当然也可以用来显示图片!

其实这些话说的都有些绝对,在 Qt 的世界了,控件可以变成任何样子,标签也可以改造成一个按钮,如果 Qt 中的控件只能按照固有的方式使用的话,那失去了很多灵活性。

首先我们建立一个窗体,设置好我们的窗体标题,然后添加标签到其中。

if __name__ == '__main__':  
    app = QApplication()  
  
    widget = QWidget()  
    widget.setWindowTitle("SerialTool")  
  
    lab_port = QLabel("串口", widget)  
    lab_baudrate = QLabel("波特率", widget)  
  
    widget.show()  
  
    app.exec()

![[Pasted image 20240810132809.png]]

可以看到,在主窗体中,两个标签都出现了,但是他们的位置好像有点问题,因为他们都传入了父对象,就是主窗体。

因此对他们来说,默认会设置自己的位置为父对象内部的左上角,也就是 Qt 中坐标系统的 (0, 0) 位置。

Qt 中,从左往右,x 逐渐增加,从上往下,y 逐渐增大

修改位置我们可以直接使用设置位置的函数,但是手动设置不利于维护,如果需要添加一个控件,或者屏幕的分辨率不一,修改起来极其麻烦。

因此,为了方便管理,Qt 提供了布局管理器

布局 (QLayout)

QLayout 是个基类,我们一般使用 QVBoxLayout QHboxLayout QGridLayout 来做布局管理,它们分别用于纵向布局、横向布局和网格布局。

我们先使用横向布局,修复之前的标签问题:

from PySide6.QtWidgets import (QApplication, QWidget, QLabel, QHBoxLayout)  # 修改
  
  
if __name__ == '__main__':  
    app = QApplication()  
  
    widget = QWidget()  
    widget.setWindowTitle("SerialTool")  
  
    layout = QHBoxLayout(widget)  # 修改
  
    lab_port = QLabel("串口")  
    lab_baudrate = QLabel("波特率")  
  
    layout.addWidget(lab_port)  # 修改
    layout.addWidget(lab_baudrate)  # 修改
  
    widget.show()  
    app.exec()

![[Pasted image 20240810133503.png]]

我们首先创建了一个横向布局管理器,注意我们直接将它的父类设置为主窗体,这代表主窗体的布局交给它管理。

我们也可以不传入父类,然后通过父类的 setLayout 来设置某个布局管理器作为窗体的布局管理器,注意一个窗体或控件只能设置一个 Layout

代码中还有两处修改,我们在创建标签的时候没有传入父类窗体,但是窗体中也显示了标签。

这是因为我们将标签控件添加到了布局管理器,而布局管理器又被设置为主窗体的布局管理器,即主窗体 widget 包含了 layoutlayout 又包含了两个 QLabel

因此,主窗体可以显示这两个 QLabel,并且主窗体的大小被设置为两个 QLabel 的大小,这就是 Layout 的作用。

如果我们在这个例子中创建 Layout 的时候,不传入父类 widget 为发生什么?上面说的包含链就不存在了,窗体就不会显示任何东西。

下拉框(QComboBox)

现在给串口和波特率添加下拉框用于选择不同的设置:

我们使用 QComboBox 创建两个下拉框,一个用于选择串口,一个用于选择波特率。

由于我们目前还没有拿到真实的串口数据,因此这里用假的端口做示例。

QComboBoxaddItems 接口可以为控件添加一个列表,这个列表会在下拉时显示出来。

我们按照顺序将控件添加到横向布局管理器中,然后运行这个示例,下拉框和我们设想的一样,出现了。

from PySide6.QtWidgets import (QApplication, QWidget, QLabel, QComboBox, QHBoxLayout)  # 修改
  
  
if __name__ == '__main__':  
    app = QApplication()  
  
    widget = QWidget()  
    widget.setWindowTitle("SerialTool")  
  
    layout = QHBoxLayout(widget)  
  
    lab_port = QLabel("串口")  
    lab_baudrate = QLabel("波特率")  
  
    cbox_port = QComboBox()  # 修改
    cbox_port.addItems(['COM3', 'COM4', 'COM5'])  # 修改
    cbox_baudrate = QComboBox()  # 修改
    cbox_baudrate.addItems(['9600', '38400', '115200', '921600'])  # 修改
  
    layout.addWidget(lab_port)  
    layout.addWidget(cbox_port)  
    layout.addWidget(lab_baudrate)  # 修改
    layout.addWidget(cbox_baudrate)  # 修改
  
    widget.show()  
    app.exec()

![[Pasted image 20240810150014.png]]

![[Pasted image 20240810150030.png]]

按钮(QPushButton)

按钮是非常常见的交互控件,下面我们添加一个按钮用于连接和断开串口。

本节我们只搭建图形界面,并不建立任何用户使用的逻辑,因此按钮点击并没有作用。

from PySide6.QtWidgets import (QApplication, QWidget, QLabel, QComboBox, QPushButton, QHBoxLayout)  # 修改
  
  
if __name__ == '__main__':  
    app = QApplication()  
  
    widget = QWidget()  
    widget.setWindowTitle("SerialTool")  
  
    layout = QHBoxLayout(widget)  
  
    lab_port = QLabel("串口")  
    lab_baudrate = QLabel("波特率")  
  
    cbox_port = QComboBox()  
    cbox_port.addItems(['COM3', 'COM4', 'COM5'])  
    cbox_baudrate = QComboBox()  
    cbox_baudrate.addItems(['9600', '38400', '115200', '921600'])  
  
    btn_conn = QPushButton("连接")  # 修改
  
    layout.addWidget(lab_port)  
    layout.addWidget(cbox_port)  
    layout.addWidget(lab_baudrate)  
    layout.addWidget(cbox_baudrate)  
    layout.addWidget(btn_conn)  # 修改
  
    widget.show()  
    app.exec()

![[Pasted image 20240810153239.png]]

文本框(QLineEdit、QTextEdit 和 QPlainTextEdit)

文本框一般用于展示或输入文字,在串口通讯时,我们需要一个接收窗用来显示收到的数据,一个发送窗用于发送数据。

Qt 提供了三种常用的文本框,他们的区别是:

  • QLineEdit
    • 单行文本输入,一般用于用户名、密码等少量文本交互地方
  • QTextEdit
    • 用于多行文本,也可以显示HTML格式文本。QTextEdit多用于显示
  • QPlainTextEdit
    • 与 QTextEdit 类似,但相比于 QTextEdit 少了富文本显示,因此在处理大量字符时,会少一些开销

由于发送时基本用不到多行,因此我们选择 QLineEdit,接收时基本是纯文本,而且可能出现大量滚屏,因此选择 QPlainTextEdit。

实际上没有太多规则,都可以使用,当然可以选择 QTextEdit 作为发送窗,根据需要选择合适的即可。

from PySide6.QtWidgets import (QApplication, QWidget, QLabel, QComboBox, QPushButton, QLineEdit,  # 修改
                               QPlainTextEdit, QVBoxLayout, QHBoxLayout)  # 修改
  
  
if __name__ == '__main__':  
    app = QApplication()  
  
    widget = QWidget()  
    widget.setWindowTitle("SerialTool")  
  
    layout_main = QVBoxLayout(widget)  # 修改
    layout = QHBoxLayout()  # 修改
  
    lab_port = QLabel("串口")  
    lab_baudrate = QLabel("波特率")  
  
    cbox_port = QComboBox()  
    cbox_port.addItems(['COM3', 'COM4', 'COM5'])  
    cbox_baudrate = QComboBox()  
    cbox_baudrate.addItems(['9600', '38400', '115200', '921600'])  
  
    btn_conn = QPushButton("连接")  
  
    lab_rx = QLabel("接收:")  # 修改
    text_rx = QPlainTextEdit()  # 修改
    lab_tx = QLabel("发送:")  # 修改
    text_tx = QLineEdit()  # 修改  
  
	btn_clear = QPushButton("清空")  
	btn_send = QPushButton("发送")
	  
    layout.addWidget(lab_port)  
    layout.addWidget(cbox_port)  
    layout.addWidget(lab_baudrate)  
    layout.addWidget(cbox_baudrate)  
    layout.addWidget(btn_conn)  
  
    layout_main.addLayout(layout)  # 修改
    layout_main.addWidget(lab_rx)  # 修改
    layout_main.addWidget(text_rx)  # 修改  
	layout_main.addWidget(btn_clear)  # 修改
    layout_main.addWidget(lab_tx)  # 修改
    layout_main.addWidget(text_tx)  # 修改  
	layout_main.addWidget(btn_send)  # 修改
  
    widget.show()  
    app.exec()

![[Pasted image 20240810154228.png]]

为发送和接收增加了按键,一个用于发送字符出去,一个用于清空接收窗口。

这里将原来主窗体的横向布局修改为了纵向布局,因为总体上,主窗体内的布局是上下结构的,只是在串口的配置区域,是左右结构。

因此我们给主窗体创建了一个纵向布局,然后将原来的横向布局添加到纵向布局中,然后添加其他控件到纵向布局中,这样就得到了上图所示的界面。

到这里我们基本上有了雏形,界面没有多好看,慢慢优化。

我们目前使用了横向布局、纵向布局和一些必要的控件,发送和接收按钮的显示略微有些别扭。

下一节我们先介绍实际的串口逻辑,界面等功能实现后再来优化。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值