第3章 PyQt5基础入门:Qt Designer界面设计、信号与槽机制、常用控件

说实话,很多初学者一上来就手写界面代码,结果布局调了半天,心态崩了。我个人习惯是——先用Qt Designer拖出界面,再写逻辑。这样效率高,还不会把自己搞晕。

这一章,我们就来聊聊PyQt5最核心的几个东西:Qt Designer怎么用、信号与槽到底是个啥、以及那几个天天见的常用控件。嗯,都是干货,咱们一个一个来。

3.1 Qt Designer:拖出来的界面,不香吗?

Qt Designer是PyQt5自带的可视化界面设计工具。说白了,就是让你像搭积木一样,把按钮、标签、输入框拖到窗口上,然后保存成一个.ui文件。

怎么启动?

如果你装了PyQt5,在命令行敲这个就行:

designer

或者你可以在Python代码里这样调用:

import os
os.system("designer")

界面出来后,左边是控件面板,中间是画布,右边是属性编辑器。你从左边拖一个QPushButton到画布上,双击改文字,搞定。

我的小习惯:每次拖完控件,我都会在属性编辑器里把objectName改掉。比如按钮叫btn_start,输入框叫edit_ip。别偷懒,后面写代码你就知道多省事了。

怎么把.ui文件变成Python代码?

有两种方式:

  • 方式一:用pyuic5工具转换。命令行执行:pyuic5 -o mainwindow.py mainwindow.ui。这样会生成一个Python类,你直接继承它就行。
  • 方式二:在代码里动态加载.ui文件。用uic.loadUi()函数,适合小项目,改界面不用重新生成代码。

我个人更推荐方式一,尤其是项目大了以后,代码结构更清晰。

3.2 信号与槽机制:Qt的灵魂

信号与槽,说白了就是事件驱动。你点一下按钮,按钮发出一个“clicked”信号,然后连接到一个槽函数,槽函数执行你写的逻辑。

举个例子:

self.btn_start.clicked.connect(self.on_start)

这行代码的意思是:当btn_start被点击时,自动调用on_start这个函数。

信号可以带参数吗?当然可以。比如QLineEdit的textChanged信号,会传递当前文本内容:

self.edit_ip.textChanged.connect(self.on_ip_changed)

我在项目中遇到过一个问题:多个按钮连接同一个槽函数,怎么区分是哪个按钮触发的?用sender()方法:

def on_click(self):
    btn = self.sender()
    print(btn.text())
我曾经踩过的坑:信号连接了槽函数,但槽函数里用了耗时操作(比如读取大文件),界面直接卡死。记住,耗时操作要放到线程里,别在主线程里搞。

3.3 常用控件:天天见的几个老朋友

PyQt5的控件很多,但做上位机监控,最常用的就这几个。我一个个说。

3.4.1 QWidget:所有控件的爸爸

QWidget是所有可视控件的基类。你创建的窗口、面板、标签页,本质上都是QWidget。它提供了最基本的功能:设置大小、位置、样式、背景色等。

你想想看,如果你要做一个自定义的仪表盘,直接继承QWidget,重写paintEvent,想画什么画什么。

3.4.2 QPushButton:点一下,世界就变了

按钮嘛,谁都用过。但有几个属性值得注意:

  • setEnabled(False):禁用按钮,灰色不可点。我经常在设备未连接时禁用“启动”按钮,防止误操作。
  • setCheckable(True):让按钮变成开关模式,按一下按下去,再按弹起来。适合做“启动/停止”切换。
  • setStyleSheet():用CSS改样式。比如改背景色、圆角、字体大小。
self.btn_start = QPushButton("启动")
self.btn_start.setCheckable(True)
self.btn_start.setStyleSheet("background-color: #4CAF50; color: white; font-size: 14px;")

3.4.3 QLabel:显示文字和图片

QLabel主要用来显示静态文本、数值、图片。做监控界面时,我常用它来显示电压、电流、温度等实时数据。

更新文本很简单:

self.label_voltage.setText(f"{voltage:.2f} V")

还可以显示图片:

pixmap = QPixmap("status_ok.png")
self.label_status.setPixmap(pixmap)
避坑指南:QLabel默认不会自动缩放图片。如果你要自适应,记得调用setScaledContents(True)

3.4.4 QLineEdit:用户输入的好帮手

QLineEdit是单行文本输入框。在光伏监控里,我常用它来输入IP地址、端口号、设备ID等。

常用方法:

  • text():获取当前输入的内容
  • setText():设置内容
  • setPlaceholderText():设置提示文字(灰色水印)
  • setEchoMode():设置回显模式。比如密码框用QLineEdit.Password
self.edit_ip = QLineEdit()
self.edit_ip.setPlaceholderText("请输入IP地址,如192.168.1.100")
self.edit_ip.setText("192.168.1.100")

我还经常用textChanged信号做实时校验。比如输入IP时,检查格式是否正确,不对就标红:

self.edit_ip.textChanged.connect(self.validate_ip)

3.5 知识体系总览

下面这张图,是我自己梳理的本章知识结构。你看一眼,心里就有数了。

PyQt5 基础入门 Qt Designer 拖拽设计界面 生成 .ui 文件 pyuic5 转 Python 信号与槽 事件驱动机制 connect() 连接 sender() 区分来源 常用控件 QWidget QPushButton QLabel QLineEdit 核心:界面设计 + 事件驱动 + 控件使用 三者结合,快速搭建上位机监控界面

3.6 实战小例子:一个简单的登录界面

光说不练假把式。咱们用Qt Designer拖一个登录界面出来,然后写代码实现点击按钮打印输入内容。

步骤1:打开Qt Designer,拖一个QWidget作为主窗口。再拖两个QLabel(用户名、密码)、两个QLineEdit、一个QPushButton(登录)。

步骤2:保存为login.ui,然后用pyuic5转成login.py。

步骤3:写主程序:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from login import Ui_MainWindow

class LoginWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.btn_login.clicked.connect(self.on_login)
    
    def on_login(self):
        username = self.edit_username.text()
        password = self.edit_password.text()
        print(f"用户名:{username},密码:{password}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = LoginWindow()
    window.show()
    sys.exit(app.exec_())

运行后,输入内容,点登录,控制台就打印出来了。是不是很简单?

核心要点:Qt Designer负责界面,信号与槽负责交互,控件负责展示和输入。这三者配合好,上位机界面开发就成功了一半。

好了,这一章的内容就到这儿。记住,多动手拖一拖、连一连,比看十遍书都管用。