pyqt5

 
 
 
 
 
 
 
 

基础


 
 
 
 

第一个GUI程序

import sys
from PyQt5 import QtWidgets

# 整个程序的底层实例
app = QtWidgets.QApplication(sys.argv)
# 程序的窗口
widget = QtWidgets.QWidget()

# 控制窗口尺寸
widget.resize(400, 100)
# 调整窗口位置
widget.move(300, 300)
# 显示窗口标题
widget.setWindowTitle('My first pyqt application')

# 显示窗口
widget.show()
# 进入程序的主循环,并且当窗口结束时,保证资源可以安全的释放
exit(app.exec_())

 
 
 
 
 
 
 
 

功能性部件


 
 
 
 

pydesigner

 
 

将窗口 ui 转换为 python 代码

1、使用 pydesigner 设计一个窗口
在这里插入图片描述

2、将窗口保存为 .ui 文件
在这里插入图片描述

3、使用如下命令,将 .ui 文件转换为 .py 文件

python -m PyQt5.uic.pyuic first.ui -o first_ui.py

在这里插入图片描述

4、(效果同3)使用 pyuic5 转换 .ui 为 .py,安装完 pyqt5 后会有对应的 exe 程序在 Scripts 目录下生成

在这里插入图片描述

使用命令

pyuic5 first.ui -o f.py
在这里插入图片描述
在这里插入图片描述

 
 

调用 ui 的 .py 文件

注:不要直接修改由 ui 转出的 .py 文件,因为 ui 发生变化时 .py 文件需要重新生成,则所作的修改都需要重做。所以新建一个 python 文件,专门用来调用 ui 的 .py 文件

 

基本代码如下

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

if __name__ == '__main__':
    app = QApplication(sys.argv)

    main_window = QMainWindow()

    # 从 ui 转出的 py 文件中载入相关代码
    ui = Ui_MainWindow()
    # 配置主窗口的 ui
    ui.setupUi(main_window)

    main_window.show()
    
    sys.exit(app.exec_())

在这里插入图片描述

 
 

四种基本的布局格式

在这里插入图片描述

 
 

Spacers

功能:用于在布局中精确的给定一定的距离
在这里插入图片描述
在这里插入图片描述

 
 

尺寸策略

期望尺寸:是每个部件在进行布局时,自动调整到的一个尺寸大小。大多数部件的期望尺寸不可改,所有部件的期望尺寸在 QtDesigner 中不可见,但是可用代码进行查询
 
查询方法:
1、将 ui 转为 py 代码
2、在 py 代码中找到对应部件的名称
3、使用类似 self.部件名.sizeHint().width()、 self.部件名.sizeHint().height() 来查看
4、期望尺寸中还有一类是最小期望尺寸,使用 self.部件名.minimumSizeHint().width()、 self.部件名.minimumSizeHint().height() 来查看
在这里插入图片描述>在这里插入图片描述

 
常用的几种尺寸策略:

  • Fixed —— 固定大小(依照输入的尺寸值)\
  • Minimum —— 按照最小期望尺寸配置
  • Maximum —— 按照最大(期望尺寸)配置
  • Expanding —— 用于同一布局中多个控件间,按照固定比例划分
     
    在这里插入图片描述

 
 

绑定热键(仅 windows)

添加方式:通过在控件名称中添加特殊标识符来绑定快捷键,如 (&a) 表示 alt + a 时触发该部件
在这里插入图片描述

 
 

伙伴关系

含义:设置多个控件间的互操作关系,通过 edit —> 编辑伙伴 来完成
 
在这里插入图片描述
 
下例通过绑定 label(已绑定热键) 和 text 来添加快捷键 focus 到 text 控件的功能
在这里插入图片描述

 
 

修改控件的 tab 顺序

含义:修改按下键盘 tab 键时,focus 在不同控件间的切换顺序,通过 QtDesigner 进行调整
 
实例:
如下图,当程序运行时,默认 focus on 第三行的 line edit,当按下 tab 键时 跳转到第一个 line edit 上,再按下 tab 键时 跳转到第二行
在这里插入图片描述
修改时可以通过点击数字进行切换,也可在空白处右键选择制表符顺序列表调整
在这里插入图片描述
在这里插入图片描述

 
 

信号与槽

含义:

  • 信号 —— 由对象或者控件发射出去的消息,即事件
  • 槽 —— 接收对象发送消息的代码,即事件函数
     

使用方式:
1、Edit —> 编辑信号 / 槽
在这里插入图片描述
2、选择部件,此处将信号拉出指向主窗体
在这里插入图片描述
3、在弹出的配置连接框中,左侧选择该部件的事件,右侧选择指向部件(或者主程序)的对应事件
在这里插入图片描述
4、添加成功后,效果如下。当程序运行时,点击按钮则程序关闭
在这里插入图片描述

 
 
 
 

创建菜单栏

1、菜单栏中添加相应选项
在这里插入图片描述

 

2、在 UIDesigner 空白处右键,打开 “动作编辑器”,
在这里插入图片描述

动作编辑器,默认在右边栏,需要手动点开。里面两个已存在的动作就对应 第1步中,手动添加的两个菜单栏的选项
在这里插入图片描述
双击对应的动作,可以对其属性进行编辑(包含显示文本、提示、图标、快捷键、是否为对勾选中形式等)
在这里插入图片描述

设置图标后,菜单栏中既会有图标进行显示
在这里插入图片描述

 
 
 
 

工具栏中添加按钮

工具栏中添加按钮,其实质就是从 “动作编辑器” 中将某个动作,拖拽到工具栏上使其显示
在这里插入图片描述

设置图标后,按钮即可以图标的形式显示
在这里插入图片描述

 
 
 
 

常用控件

 

QLable

功能:用于显示文本信息

 

主要方法如下:

方法含义
setAlignment()设置文本的对齐方式
setIndent()设置文本缩进
text()获取文本内容
setBuddy()设置伙伴关系
setText()设置文本内容
selectedText()设置所选择的字符
setWordWrap()设置是否允许换行
setPixmap(QPixmap())图片标签
setToolTip()设置鼠标悬停的提示
.setOpenExternalLinks(True)当鼠标点击时,跳转到指定链接(label需要是个 a 标签,并且有有效的地址)
setPalette()设置调色板(如背景颜色)

 

常用事件(信号)

信号含义
linkHovered鼠标滑过
linkActivated鼠标点击

 
 
 
 

实例一 —— 简单的 label

在这里插入图片描述

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QVBoxLayout, QLabel, QWidget
from PyQt5.QtGui import QPalette, QPixmap
from PyQt5.QtCore import Qt

class QLabelDemo(QWidget):
    def __init__(self):
        super().__init__()

        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("QLabel Demo 1")
        self.setGeometry(300, 300, 600, 600)

        # 创建label控件
        label1 = QLabel(self)
        label2 = QLabel(self)
        label3 = QLabel(self)
        label4 = QLabel(self)

        # 设置内容
        label1.setText("<font color=yellow>这是label1</font>")
        # 设置自动填充背景色
        label1.setAutoFillBackground(True)
        # 设置调色板
        palette = QPalette()
        palette.setColor(QPalette.Window, Qt.blue)
        label1.setPalette(palette)
        # 设置居中对齐
        label1.setAlignment(Qt.AlignCenter)

        label2.setText("<a href='#'>欢迎</a>")

        label3.setAlignment(Qt.AlignCenter)
        label3.setToolTip("这是一个图片标签")
        label3.setPixmap(QPixmap("../static/img/pikaqiu2.jpeg"))

        # 控制是否可以
        label4.setOpenExternalLinks(True)
        label4.setText("<a href='www.baidu.com'>跳转到百度</a>")
        label4.setAlignment(Qt.AlignCenter)

        # 设置布局
        vbox = QVBoxLayout()
        vbox.addWidget(label1)
        vbox.addWidget(label2)
        vbox.addWidget(label3)
        vbox.addWidget(label4)

        # 绑定信号与槽
        label2.linkHovered.connect(self.link_hovered)
        label4.linkActivated.connect(self.link_clicked)

        self.setLayout(vbox)

    def link_hovered(self):
        print("鼠标滑过 label2 时触发")

    def link_clicked(self):
        print("鼠标点击 label4 时触发")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QLabelDemo()
    main.show()

    sys.exit(app.exec_())

 
 
 
 

QLabel与伙伴控件

含义:激活(通常是使用热键)QLabel 时,同时激活(通常是光标激活到)伙伴控件上
 
绑定方式:QLabelObj.setBuddy(nameLineEdit)

 

from PyQt5.QtWidgets import *
import sys


# 设置一个没有菜单栏的对话框
class QLabelBubby(QDialog):
    def __init__(self):
        super(QLabelBubby, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QLabel与伙伴控件")

        # 提示此处输入用户名,设置热键(alt + n)
        nameLabel = QLabel("&Name", self)
        # 用户名输入框
        nameLineEdit = QLineEdit(self)
        # 设置伙伴控件
        nameLabel.setBuddy(nameLineEdit)

        # 提示此处输入密码,设置热键(alt + p)
        passwdLabel = QLabel("&Password", self)
        # 密码输入框
        passwdLineEdit = QLineEdit(self)
        # 设置伙伴关系
        passwdLabel.setBuddy(passwdLineEdit)

        # 确定按钮
        btnOK = QPushButton("&OK")
        btnCancel = QPushButton("&Cancel")

        # 使用栅格布局
        mainLayout = QGridLayout(self)
        # 第一行第一列放置 用户名 提示,占用空间自动调整
        mainLayout.addWidget(nameLabel, 0, 0)
        # 用户名输入框,放置到第一行第二列,并且占用一行两列
        mainLayout.addWidget(nameLineEdit, 0, 1, 1, 2)

        # 将 密码 提示控件放置到第二行第一列,占用控件自动调整
        mainLayout.addWidget(passwdLabel, 1, 0)
        # 输入框放置到第二行第二列,并且占用一行两列
        mainLayout.addWidget(passwdLineEdit, 1, 1, 1, 2)

        # 添加按钮
        mainLayout.addWidget(btnOK, 2, 1)
        mainLayout.addWidget(btnCancel, 2, 2)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QLabelBubby()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QLineEdit

常用方法

方法含义
.setMaxLength(n)设置输入的最大字符数
.setReadOnly(True)是否设置内容为只读
.setEchoMode()设置其中的文本的回显模式
.setInputMask()掩码校验模式
.setValidator()校验器校验模式
.setAlignment()设置文本对齐方式
.setFont()设置文本格式

常用槽

含义
.textChanged文本变化事件
editingFinished编辑结束事件

 
 

QLineEdit 的回显模式(EchoMode)

四种回显模式:

  • Normal —— 正常的模式,输入什么就显示什么
  • NoEcho —— 无回显,即输入任何都不会显示出来
  • Password ——输入一个显示一个,但是显示的全是 * 字符
  • PasswordEchoOnEdit —— 输入时显示字符,输入完毕后过一会用 * 代替。再次输入会删除之前输入的内容

 

如:

from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit
import sys


class QLineEditEchoMode(QWidget):
    def __init__(self):
        super(QLineEditEchoMode, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("文本输入框的回显模式")

        # 正常回显模式
        lEditNormal = QLineEdit()
        # 无回显模式
        lEditNoEcho = QLineEdit()
        # 密码回显模式
        lEditPass = QLineEdit()
        # 密码输入回显模式
        lEditPassEchoOnEdit = QLineEdit()

        # 设置四种模式
        lEditNormal.setEchoMode(QLineEdit.Normal)
        lEditNoEcho.setEchoMode(QLineEdit.NoEcho)
        lEditPass.setEchoMode(QLineEdit.Password)
        lEditPassEchoOnEdit.setEchoMode(QLineEdit.PasswordEchoOnEdit)

        # 设置 place hold text
        lEditNormal.setPlaceholderText("Normal Mode")
        lEditNoEcho.setPlaceholderText("NoEcho Mode")
        lEditPass.setPlaceholderText("Password Mode")
        lEditPassEchoOnEdit.setPlaceholderText("Password Echo On Edit")

        # 使用表单布局
        formLayout = QFormLayout()
        # 添加控件
        formLayout.addRow("Normal", lEditNormal)
        formLayout.addRow("NoEcho", lEditNoEcho)
        formLayout.addRow("Password", lEditPass)
        formLayout.addRow("PasswordEchoOnEdit", lEditPassEchoOnEdit)

        self.setLayout(formLayout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QLineEditEchoMode()
    main.show()
    sys.exit(app.exec_())

在这里插入图片描述

 
 

Validator ——校验器(输入验证)

含义:用于对输入数据类型进行或者格式进行限制,如仅允许输入数值、字母或者符合正则规范的格式等
 
常用类型(位于 PyQt5.QtGui 中):

  • 整数验证 —— QIntValidator
  • 浮点数验证 —— QDoubleValidator
  • 正则验证 —— QRegExpValidator (需要匹配 QRegExp 来使用,from PyQt5.QtCore import QRegExp)

 

from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit
from PyQt5.QtGui import QIntValidator, QDoubleValidator, QRegExpValidator
from PyQt5.QtCore import QRegExp
import sys


class QLineEditValidator(QWidget):
    def __init__(self):
        super(QLineEditValidator, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("输入校验器")

        intLineEdit = QLineEdit()
        doubleLineEdit = QLineEdit()
        regLineEdit = QLineEdit()

        # 创建校验器
        # 整数校验器
        intValidator = QIntValidator(self)
        # 取值范围 1 ~ 9999
        intValidator.setRange(1, 9999)

        # 浮点数校验器
        doubleValidator = QDoubleValidator(self)
        # 数值范围
        doubleValidator.setRange(-360, 360)
        # 浮点数的显示方法,使用标准显示法
        doubleValidator.setNotation(QDoubleValidator.StandardNotation)
        # 设置精度
        doubleValidator.setDecimals(2)

        # 创建正则规则
        reg = QRegExp(r'\d{3}-\d{3}-\d{3}')
        # 创建正则检验其
        regValidator = QRegExpValidator(self)
        # 绑定正则规则
        regValidator.setRegExp(reg)

        # 创建表单布局
        formLayout = QFormLayout()

        lEdits = (intLineEdit, doubleLineEdit, regLineEdit)
        validators = (intValidator, doubleValidator, regValidator)
        pHolderTexts = ("整数", "浮点数", "正则匹配")

        for i, eachEdit in enumerate(lEdits):
            # 控件添加到布局中
            formLayout.addRow(pHolderTexts[i], eachEdit)
            # 设置 line edit 中的占位字符
            eachEdit.setPlaceholderText(pHolderTexts[i])
            # 绑定 line edit 和校验器
            eachEdit.setValidator(validators[i])

        # 设置布局
        self.setLayout(formLayout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QLineEditValidator()
    main.show()
    sys.exit(app.exec_())

在这里插入图片描述

 
 

通过掩码限制输入

PyQt支持的所有掩码如下

掩码功能
A只允许输入(A-Z, a-z)
a可以输入(A-Z, a-z),但不必须
N只允许输入(A-Z, a-z, 0-9)
n可以输入(A-Z, a-z, 0-9),但不必须
X必须输入任意字符
x可以输入任意字符
9只允许输入(0-9)
0可以输入(0-9)
D只允许输入(1-9)
d可以输入(1-9)
#可以输入(数字、加减)
H必须输入十六进制字符(A-F,a-f,-0-9)
h允许输入十六进制字符(A-F,a-f,-0-9)
B必须输入二进制格式字符(0,1)
b允许输入二进制格式字符(0,1)
>所有字幕字符都大写
<所有字幕字符都小写
!关闭大小写转换
\转移字符
from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit
import sys


class QLineEditMask(QWidget):
    def __init__(self):
        super(QLineEditMask, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("用掩码限制QLineEdit的输入")

        # 限制输入 ip
        ipLineEdit = QLineEdit()
        # 限制输入 mac 地址
        macLineEdit = QLineEdit()
        # 限制输入日期
        dateLineEdit = QLineEdit()
        # 限制输入 license
        licenseLineEdit = QLineEdit()

        # ip 掩码设置,没有输入的用 _ 代替(类似 place holder)
        ipLineEdit.setInputMask("000.000.000.000;_")
        # mac 地址掩码设置
        macLineEdit.setInputMask("HH:HH:HH:HH:HH:HH;_")
        # 日期地址掩码
        dateLineEdit.setInputMask("0000-00-00")
        # license 掩码设置
        licenseLineEdit.setInputMask("AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#")

        # form 布局
        formLayout = QFormLayout()
        formLayout.addRow("ip掩码", ipLineEdit)
        formLayout.addRow("Mac掩码", macLineEdit)
        formLayout.addRow("日期掩码", dateLineEdit)
        formLayout.addRow("license掩码", licenseLineEdit)

        self.setLayout(formLayout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QLineEditMask()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

综合案例

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIntValidator, QFont, QDoubleValidator
from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLineEdit
import sys


class QLineEditDemo(QWidget):
    def __init__(self):
        super(QLineEditDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QLineEdit综合案例")

        # 整数输入框
        lEdit = QLineEdit()
        # 设置输入校验器,仅允许输入整数
        lEdit.setValidator(QIntValidator())
        # 最大输入长度为 4 个字符
        lEdit.setMaxLength(4)
        # 设置对齐模式为左对齐
        lEdit.setAlignment(Qt.AlignRight)
        # 设置字体
        lEdit.setFont(QFont("Arial", 20))

        # 浮点数输入框
        lEditFloat = QLineEdit()
        lEditFloat.setValidator(QDoubleValidator(0.99, 99.99, 2))

        lEditMask = QLineEdit()
        lEditMask.setInputMask("99_9999_999999;#")

        # 文本改变事件
        lEditSlot = QLineEdit()
        lEditSlot.textChanged.connect(self.textChange)

        # 编辑结束事件
        lEditSlot3 = QLineEdit()
        lEditSlot3.editingFinished.connect(self.enterPress)

        lEditSlot2 = QLineEdit()
        lEditSlot2.setEchoMode(QLineEdit.Password)

        formLayout = QFormLayout()
        formLayout.addRow("整数校验", lEdit)
        formLayout.addRow("浮点数校验", lEditFloat)
        formLayout.addRow("掩码校验", lEditMask)
        formLayout.addRow("文本变化事件", lEditSlot)
        formLayout.addRow("密码回显", lEditSlot2)
        formLayout.addRow("编辑完成事件", lEditSlot3)

        self.setLayout(formLayout)

    # 设置文字改变的槽
    def textChange(self, text):
        print("输入的内容: ", text)

    def enterPress(self):
        print("已输入值")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QLineEditDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

设置多行文本

借助控件,QTextEdit 实现多行文本、HTML文本的显示和获取

常用方法

方法含义
.setPlainText(“content”)设置文本框中的内容
.setHtml(“html content”)设置文本框中的内容为 HTML
.toPlainText()获取输入框中的文本,作为字符串
.toHtml()获取输入框中的文本,作为 html(整个页面,即使你只输入了几个简单的字)

 
 
 
 

基本使用

from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QTextEdit, QPushButton
import sys


class QTextEditMultiline(QWidget):
    def __init__(self):
        super(QTextEditMultiline, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("设置多行输入")
        self.resize(300, 200)

        self.textEdit = QTextEdit()
        self.btnText = QPushButton("显示文本")
        self.btnHtml = QPushButton("显示HTML")
        self.btnGetText = QPushButton("获取文本")
        self.btnGetHtml = QPushButton("获取HTML")

        # 绑定事件,添加普通文本
        self.btnText.clicked.connect(self.setCommonText)
        # 绑定事件,添加 HTML 文本
        self.btnHtml.clicked.connect(self.setHtmlText)

        self.btnGetText.clicked.connect(self.getCommonText)
        self.btnGetHtml.clicked.connect(self.getHtmlText)

        formLayout = QFormLayout()
        formLayout.addWidget(self.textEdit)
        formLayout.addWidget(self.btnText)
        formLayout.addWidget(self.btnHtml)
        formLayout.addWidget(self.btnGetText)
        formLayout.addWidget(self.btnGetHtml)

        self.setLayout(formLayout)

    # 设置普通文本
    def setCommonText(self):
        self.textEdit.setPlainText("这是普通文本")

    # 设置 HTML 文本
    def setHtmlText(self):
        self.textEdit.setHtml("<font color=red>这是HTML文本</font>")

    # 获取普通文本
    def getCommonText(self):
        print(self.textEdit.toPlainText())

    # 获取 html
    def getHtmlText(self):
        print(self.textEdit.toHtml())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QTextEditMultiline()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

按钮控件


 

所有按钮控件都有基类,QAbstractButton。常用的按钮控件有:

  • QPushButton —— 按键
  • AToolButton —— 工具条
  • QRadioButton —— 单选按钮
  • QCheckBox —— 复选框

 
 
 
 

QPushButton

方法含义
.setText()设置按钮的文本
.setCheckable(True)设置按钮是否是点击按下,再点击弹起的状态
.toggle()切换按钮被按下的状态,要配合 setCheckable 使用
.setIcon(QIcon(QPixmap()))将图片放到按钮上
.setEnabled()设置按钮是否可用
.setDefault()设置按钮是否为默认选中状态(就是刚被点完那样)

 

from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QApplication, QDialog, QPushButton, QVBoxLayout
import sys


class QPushButtonDemo(QDialog):
    def __init__(self):
        super(QPushButtonDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("按钮案例")

        self.btn1 = QPushButton("第一个按钮")
        # 设置按钮按下不弹起
        self.btn1.setCheckable(True)
        self.btn1.toggle()
        # 事件被调用时,只传值到 self,此处通过 lambda 来给槽添加参数
        self.btn1.clicked.connect(lambda: self.whichButton(self.btn1))
        self.btn1.clicked.connect(lambda: self.btnState(self.btn1))

        # 在按钮上显示图像
        self.btn2 = QPushButton("按钮2")
        self.btn2.setIcon(QIcon(QPixmap("../static/hs.jpg")))

        # 不可用的按钮
        self.btn3 = QPushButton("不可用的按钮")
        self.btn3.setEnabled(False)

        # 默认按钮,默认按钮一个窗口只能有一个
        self.btn4 = QPushButton("&MyButton")
        self.btn4.setDefault(True)
        self.btn4.clicked.connect(lambda: self.whichButton(self.btn4))

        layout = QVBoxLayout()
        layout.addWidget(self.btn1)
        layout.addWidget(self.btn2)
        layout.addWidget(self.btn3)
        layout.addWidget(self.btn4)
        self.setLayout(layout)

    def btnState(self, btn):
        if btn.isChecked():
            print("被选中了")
        else:
            print("没有被选中")

    def whichButton(self, btn):
        print("被单击的按钮是:", btn.text())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QPushButtonDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QRadioButton

from PyQt5.QtWidgets import QApplication, QDialog, QRadioButton, QVBoxLayout
import sys


class QRadioButtonDemo(QDialog):
    def __init__(self):
        super(QRadioButtonDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("单选按钮")

        self.btn1 = QRadioButton("单选框1")
        self.btn1.setChecked(True)
        self.btn1.toggled.connect(self.btnState)

        self.btn2 = QRadioButton("单选框2")
        self.btn2.toggled.connect(self.btnState)

        layout = QVBoxLayout()
        layout.addWidget(self.btn1)
        layout.addWidget(self.btn2)

        self.setLayout(layout)

    def btnState(self):
        radioBtn = self.sender()
        if radioBtn.text() == "单选框1":
            print(radioBtn.text(), "被选中")
        else:
            print(radioBtn.text(), "没有被选中")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QRadioButtonDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QCheckBox

复选框具有三种状态

  • 未选中 —— .0,表现为选中框为空
  • 半选中 —— 1,表现为选中框为实心矩形
  • 选中 —— 2,表现为选中框为对勾形

 

常用方法

方法含义
.text()获取 check box 的名字
.isChecked()获取是否选装,布尔值,选中为 True
.checkState()获取选中状态的值,(0, 1, 2)
.setTristate(False)设置是否允许半选中状态
.setChecked()设置复选框是否是被选中的状态

 

常用事件

方法含义
.stateChanged()状态改变时触发
from PyQt5.QtWidgets import QApplication, QDialog, QHBoxLayout, QCheckBox
import sys


class QCheckBoxDemo(QDialog):
    def __init__(self):
        super(QCheckBoxDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("复选框")

        self.checkBox1 = QCheckBox("复选框1")
        self.checkBox1.setChecked(True)
        self.checkBox1.stateChanged.connect(lambda: self.checkboxState(self.checkBox1))

        self.checkBox2 = QCheckBox("复选框2")
        self.checkBox2.stateChanged.connect(lambda: self.checkboxState(self.checkBox2))

        self.checkBox3 = QCheckBox("复选框3")
        # 允许半选中的状态
        self.checkBox3.setTristate(True)
        self.checkBox3.stateChanged.connect(lambda: self.checkboxState(self.checkBox3))

        layout = QHBoxLayout()
        layout.addWidget(self.checkBox1)
        layout.addWidget(self.checkBox2)
        layout.addWidget(self.checkBox3)

        self.setLayout(layout)


    def checkboxState(self, cb):
        print(f"{cb.text()}, isChecked={cb.isChecked()}. checkState={cb.checkState()}")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QCheckBoxDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QComboBox(下拉列表)

常用方法

方法含义
.addItem()(设置)添加下拉条的内容
.addItems()(设置)批量添加下拉条的内容
.itemText(n)获取下拉条中第 n 条的内容
.currentText()获取当前选中的文本

 

常用事件

事件
.currentIndexChanged()下拉条选中内容改变

 

设置下拉框不可写入

.setEditable(False)

 

from PyQt5.QtWidgets import QApplication, QComboBox, QWidget, QVBoxLayout, QLabel
import sys


class QComboBoxDemo(QWidget):
    def __init__(self):
        super(QComboBoxDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("下拉条控件")

        self.cb = QComboBox()
        # 添加下拉条内容
        self.cb.addItem("c++")
        self.cb.addItems(["python", "java", "c#", "javascript"])
        # 下拉条选中改变事件
        self.cb.currentIndexChanged.connect(self.selChange)

        self.label = QLabel("请选择编程语言")

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(self.cb)

        self.setLayout(layout)

    def selChange(self, index):
        # 获取被选中的内容,并显示在标注框中
        self.label.setText(self.cb.currentText())
        self.label.adjustSize()

        for count in range(self.cb.count()):
            print(f"item {count} = {self.cb.itemText(count)}")

        print(f"current index {index} select changed {self.cb.currentText()}")
        print("*" * 30)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QComboBoxDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QSlider(滑块)

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QApplication, QWidget, QSlider, QVBoxLayout, QLabel
import sys


class QSliderDemo(QWidget):
    def __init__(self):
        super(QSliderDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("滑块案例")
        self.resize(300, 100)

        self.label = QLabel("你好")
        self.label.setAlignment(Qt.AlignCenter)

        # 设置水平滑块
        self.slider = QSlider(Qt.Vertical)
        # 设置最小值
        self.slider.setMinimum(12)
        # 设置最大值
        self.slider.setSingleStep(48)
        # 设置当前值
        self.slider.setValue(18)
        # 设置刻度的位置
        self.slider.setTickPosition(QSlider.TicksBelow)
        # 设置刻度的间隔
        self.slider.setTickInterval(6)

        self.slider.valueChanged.connect(self.valueChange)

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(self.slider)

        self.setLayout(layout)

    def valueChange(self):
        print(f"当前值:{self.slider.value()}")
        size = self.slider.value()
        self.label.setFont(QFont("Arial", size))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QSliderDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QSpinBox(计数器控件)

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QSpinBox
import sys


class QSpinBoxDemo(QWidget):
    def __init__(self):
        super(QSpinBoxDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("计数器控件")
        self.resize(600, 400)

        self.label = QLabel("当前值")
        self.label.setAlignment(Qt.AlignCenter)
        
        # 计数器控件
        self.sb = QSpinBox()
        # 设置默认值
        self.sb.setValue(18)
        # 设置取值范围
        self.sb.setRange(10, 20)
        # 绑定自定义槽
        self.sb.valueChanged.connect(self.valueChange)

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(self.sb)
        self.setLayout(layout)

    def valueChange(self):
        self.label.setText(f"当前值:{self.sb.value()}")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QSpinBoxDemo()
    main.show()
    sys.exit(app.exec_())

 

在这里插入图片描述

 
 
 
 

QMessageBox

主要的对话框有以下几类

  • 关于对话框
  • 错误对话框
  • 警告对话框
  • 提问对话框
  • 消息对话框
     

不同对话框的区别
 
1、显示的图标不同
 
2、显示的按钮不一样

 

import sys
from PyQt5.QtWidgets import QApplication, QMessageBox, QVBoxLayout, QPushButton, QWidget


class QMessageBoxDemo(QWidget):
    def __init__(self):
        super(QMessageBoxDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("消息对话框样例")
        self.resize(600, 400)

        self.btn1 = QPushButton("显示关于对话框", self)
        self.btn2 = QPushButton("显示错误对话框", self)
        self.btn3 = QPushButton("显示警告对话框", self)
        self.btn4 = QPushButton("显示提问对话框", self)
        self.btn5 = QPushButton("显示消息对话框", self)
        self.btn1.clicked.connect(self.showDialog)
        self.btn2.clicked.connect(self.showDialog)
        self.btn3.clicked.connect(self.showDialog)
        self.btn4.clicked.connect(self.showDialog)
        self.btn5.clicked.connect(self.showDialog)

        layout = QVBoxLayout()
        layout.addWidget(self.btn1)
        layout.addWidget(self.btn2)
        layout.addWidget(self.btn3)
        layout.addWidget(self.btn4)
        layout.addWidget(self.btn5)

        self.setLayout(layout)

    def showDialog(self):
        text = self.sender().text()
        if text == "显示关于对话框":
            QMessageBox.about(self, "关于", "这是一个关于对话框")
        elif text == "显示错误对话框":
            QMessageBox.critical(self, "错误", "这个一个错误对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        elif text == "显示消息对话框":
            reply = QMessageBox.information(self, "消息", "这是一个消息对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            print(reply)
        elif text == "显示警告对话框":
            QMessageBox.warning(self, "警告", "这是一个警告对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        elif text == "显示提问对话框":
            QMessageBox.question(self, "提问", "这是一个提问对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QMessageBoxDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QColorDialog

弹出颜色选择框
在这里插入图片描述

from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QWidget, QApplication, QColorDialog, QVBoxLayout, QLabel, QPushButton
import sys


class QColorDilogDemo(QWidget):
    def __init__(self):
        super(QColorDilogDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("颜色选择对话框")

        self.label = QLabel("颜色变了")

        self.btn = QPushButton("设置颜色")
        self.btn.clicked.connect(self.chooseColor)

        self.btn1 = QPushButton("设置背景色")
        self.btn1.clicked.connect(self.setBackground)

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(self.btn)
        layout.addWidget(self.btn1)

        self.setLayout(layout)

    def chooseColor(self):
        color = QColorDialog.getColor()
        p = QPalette()
        p.setColor(QPalette.WindowText, color)
        self.label.setPalette(p)

    def setBackground(self):
        color = QColorDialog.getColor()
        p = QPalette()
        p.setColor(QPalette.Window, color)
        self.label.setAutoFillBackground(True)
        self.label.setPalette(p)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QColorDilogDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QFontDialog

弹出选择字体的对话框
在这里插入图片描述

from PyQt5.QtWidgets import QApplication, QWidget, QFontDialog, QPushButton, QVBoxLayout, QLabel
import sys


class QFontDialogDemo(QWidget):
    def __init__(self):
        super(QFontDialogDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("字体选择对话框")

        self.fontLabel = QLabel("字体变化啦")
        self.btn = QPushButton("选择字体")
        self.btn.clicked.connect(self.getFont)

        layout = QVBoxLayout()

        layout.addWidget(self.fontLabel)
        layout.addWidget(self.btn)

        self.setLayout(layout)

    def getFont(self):
        font, ok = QFontDialog.getFont()
        if ok:
            self.fontLabel.setFont(font)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QFontDialogDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QInputDialog

输入框

 

主要方法

方法功能
.getItem()传入列表或元组,显示 QCombox
.getText()录入普通文本
.getInt()录入整数

 
 
 
 

QFileDialog

功能:用于弹出文件选择框

import sys

from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QFileDialog, QVBoxLayout, QPushButton, QLineEdit, QFormLayout, \
    QLabel, QTextEdit


class QFileDialogDemo(QWidget):
    def __init__(self):
        super(QFileDialogDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("文件对话框")

        self.btn = QPushButton("打开文件")
        self.lEdit = QLineEdit()
        self.btn.clicked.connect(self.openFile)

        # 读取图片并显示
        self.imgLabel = QLabel()
        self.btn1 = QPushButton("打开图片")
        self.btn1.clicked.connect(self.openImgFile)

        # 打开文本并显示
        self.txtEdit = QTextEdit()
        self.btn2 = QPushButton("打开图片")
        self.btn2.clicked.connect(self.openTxtFile)

        layout = QVBoxLayout()
        formLayout = QFormLayout()
        formLayout.addRow("文件", self.lEdit)
        formLayout.addRow("打开", self.btn)
        formLayout.addRow("图像", self.imgLabel)
        formLayout.addRow("打开图片", self.btn1)
        formLayout.addRow("编辑文本", self.txtEdit)
        formLayout.addRow("打开图片", self.btn2)
        layout.addLayout(formLayout)

        self.setLayout(layout)

    def openFile(self):
        dialog = QFileDialog()
        dialog.setAcceptMode(QFileDialog.AcceptSave)
        if dialog.exec():
            file = dialog.selectedFiles()
            print(file)

    def openImgFile(self):
        dialog = QFileDialog()
        dialog.setAcceptMode(QFileDialog.AcceptOpen)
        dialog.setNameFilter("*.jpg *.png *.tif")
        if dialog.exec():
            file = dialog.selectedFiles()[0]
            self.imgLabel.setPixmap(QPixmap(file))

    def openTxtFile(self):
        dialog = QFileDialog()
        dialog.setAcceptMode(QFileDialog.AcceptOpen)
        dialog.setNameFilter("*.py;;*.txt")
        if dialog.exec():
            file = dialog.selectedFiles()[0]
            with open(file, "r", encoding="utf-8") as f:
                content = f.read()

            self.txtEdit.setText(content)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QFileDialogDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 

QGridLayout

作用:用于完成栅格布局

 

主要方法如下

方法含义
addWidget()添加控件

 

.addWidget()

参数按顺序含义如下:

  • 控件 —— 各类要放置到栅格布局中的控件
  • 放置位置行 —— 将控件放置到格网布局中的哪行
  • 放置位置列 —— 将控件放置到格网布局中的哪列
  • 占用行数 —— 该控件要占用几行
  • 占用列数 —— 该控件要占用几列

 
 
 
 
 
 
 
 

代码创建UI界面


 

几种主要的窗口形式

1、QMainWindow —— 可以包含菜单栏、工具栏、状态栏和标题栏,是最常见的窗口形式

2、QDialog —— 是对话窗口的基类,以弹出窗口的形式来完成一个暂时的功能

3、QWidget —— 不确定窗口的用户,就使用QWidget

 

QMainWindow

 

基本的 GUI 程序

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QIcon


class FirstMainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        # 设置窗口标题
        self.setWindowTitle("第一个主窗口应用")

        # 设置窗口尺寸
        self.resize(800, 600)

        # 添加状态栏
        self.status = self.statusBar()
        # 设置一个临时的提示信息
        self.status.showMessage("只存在5秒的消息", 5000)


if __name__ == '__main__':
    # 实例化应用程序对象,并设置图标等信息
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon("../static/hs.jpg"))

    # 实例化窗口主程序
    main = FirstMainWindow()
    main.show()

    # 进入程序的主循环
    sys.exit(app.exec_())

在这里插入图片描述

 
 
 
 

窗口居中

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QDesktopWidget
from PyQt5.QtGui import QIcon


class CenterForm(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # 设置窗口标题
        self.setWindowTitle("窗口居中")
        # 设置窗口尺寸
        self.resize(800, 600)
        self.center()

    def center(self):
        # 获取屏幕坐标系
        screen_o = QDesktopWidget().screenGeometry()
        # 获取屏幕坐标
        app_size_o = self.geometry()
        # 计算剧中的位置
        left = (screen_o.width() - app_size_o.width()) / 2
        top = (screen_o.height() - app_size_o.height()) / 2
        # 移动窗口
        self.move(left, top)


if __name__ == '__main__':
    # 实例化应用程序对象,并设置图标等信息
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon("../static/hs.jpg"))
    # 实例化窗口主程序
    main = CenterForm()
    main.show()
    # 进入程序的主循环
    sys.exit(app.exec_())

 
 
 
 

退出程序按钮

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QHBoxLayout, QWidget, QPushButton
from PyQt5.QtGui import QIcon


class ExitForm(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("退出应用程序")

        self.resize(800, 600)

        # 设置按钮
        self.button1 = QPushButton("退出应用程序")
        # 将信号与槽关联
        self.button1.clicked.connect(self.on_click_button)

        # 创建布局
        layout = QHBoxLayout()
        # 将按钮添加到布局中
        layout.addWidget(self.button1)

        # 实例化一个框架
        main_frame = QWidget()
        # 将布局放置到框架上
        main_frame.setLayout(layout)

        # 充满屏幕
        self.setCentralWidget(main_frame)

    # 按钮的单击事件方法
    def on_click_button(self):
        sender = self.sender()
        print(sender.text() + " 按钮被按下")

        # 获取应用程序
        app = QApplication.instance()
        # 退出应用程序
        app.quit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = ExitForm()
    main.show()

    sys.exit(app.exec_())

 
 
 
 

设置窗口图标

import os.path
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtGui import QIcon


class SetIcon(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("更换图标")
        self.resize(800, 600)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon("../static/icon/hispatial.ico"))
    main = SetIcon()
    main.show()

    sys.exit(app.exec_())

或者

class SetIcon(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("更换图标")
        self.resize(800, 600)
        self.setWindowIcon(QIcon("../static/icon/hispatial.ico"))

 
 
 
 

添加提示信息

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QToolTip, QWidget, QPushButton, QHBoxLayout
from PyQt5.QtGui import QFont


class ToolTipForm(QMainWindow):
    def __init__(self):
        super().__init__()

        self.init_ui()

    def init_ui(self):
        # 设置标题
        self.setWindowTitle("设置控件提示信息")
        # 设置提示信息字体
        QToolTip.setFont(QFont("arial", 12))
        # 设置提示信息文本
        self.setToolTip("显示提示信息")
        # 设置窗体尺寸
        self.setGeometry(300, 300, 400, 400)

        self.button = QPushButton("我的按钮")
        self.button.setToolTip("这是一个按钮")

        layout = QHBoxLayout()
        layout.addWidget(self.button)

        main_frame = QWidget()
        main_frame.setLayout(layout)

        self.setCentralWidget(main_frame)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = ToolTipForm()
    main.show()

    # 当程序退出时,进入应用主循环
    sys.exit(app.exec_())

 
 
 
 

QDialog

小窗口,常用于主程序的弹出框

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog
import sys


class QDialogDemo(QMainWindow):
    def __init__(self):
        super(QDialogDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QDialog样例")
        self.resize(600, 400)

        self.btn = QPushButton(self)
        self.btn.setText("弹出对话框")
        self.btn.move(50, 50)
        self.btn.clicked.connect(self.showDialog)

    def showDialog(self):
        # 创建窗口实例
        dialog = QDialog()
        # 将按钮放置到窗口上
        btn = QPushButton("确定", dialog)
        btn.clicked.connect(dialog.close)
        btn.move(50, 50)

        # 设置窗口的名称
        dialog.setWindowTitle("对话框")
        # 使窗口挡住主程序
        dialog.setWindowModality(Qt.ApplicationModal)
        # 显示窗体
        dialog.exec()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = QDialogDemo()
    main.show()
    sys.exit(app.exec_())

 
 
 
 
 
 
 
 

各类控件属性及方法


 

widget

方法含义
.x()窗口的 x 坐标(包含标题栏,距离屏幕最左侧的像素值)
.y()窗口的 y 坐标(包含标题栏,距离屏幕最上方的像素值)
.width()窗口的宽度值(包含标题栏,像素值)
.height()窗口的高度值(包含标题栏,像素值)
.geometry().x()窗口的 x 坐标(不包含标题栏,距离屏幕最左侧的像素值)
.geometry().y()窗口的 y 坐标(不包含标题栏,距离屏幕最上方的像素值)
.geometry().width()窗口的宽度值(包含标题栏,像素值)
.geometry()height()窗口的高度值(包含标题栏,像素值)

注:

  • widget.frameGeometry().x()、.y()、.width()、.height() 与 widget.x()、.y()、.width()、.height() 是相同的,均为整个窗口整体(包含标题栏)的相对位置和宽高
  • widget、widget.geometry()、widget.frameGeometry() 的 .width() .height() 均为窗口整体(包含标题栏)的尺寸

 
 
 
 
 
 
 
 

必装插件


PyQt5-stubs —— 强化 PyQt 在 Pycharm 中的自动补全

posted @ 2022-06-05 20:49  阿伦alun  阅读(281)  评论(0编辑  收藏  举报