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_())
3、使用如下命令,将 .ui 文件转换为 .py 文件
python -m PyQt5.uic.pyuic first.ui -o first_ui.py
4、(效果同3)使用 pyuic5 转换 .ui 为 .py,安装完 pyqt5 后会有对应的 exe 程序在 Scripts 目录下生成
使用命令
注:不要直接修改由 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_())
期望尺寸:是每个部件在进行布局时,自动调整到的一个尺寸大小。大多数部件的期望尺寸不可改,所有部件的期望尺寸在 QtDesigner 中不可见,但是可用代码进行查询
查询方法:
1、将 ui 转为 py 代码
2、在 py 代码中找到对应部件的名称
3、使用类似 self.部件名.sizeHint().width()、 self.部件名.sizeHint().height() 来查看
4、期望尺寸中还有一类是最小期望尺寸,使用 self.部件名.minimumSizeHint().width()、 self.部件名.minimumSizeHint().height() 来查看
>
常用的几种尺寸策略:
含义:设置多个控件间的互操作关系,通过 edit —> 编辑伙伴 来完成
下例通过绑定 label(已绑定热键) 和 text 来添加快捷键 focus 到 text 控件的功能
含义:修改按下键盘 tab 键时,focus 在不同控件间的切换顺序,通过 QtDesigner 进行调整
实例:
如下图,当程序运行时,默认 focus on 第三行的 line edit,当按下 tab 键时 跳转到第一个 line edit 上,再按下 tab 键时 跳转到第二行
修改时可以通过点击数字进行切换,也可在空白处右键选择制表符顺序列表调整
含义:
- 信号 —— 由对象或者控件发射出去的消息,即事件
- 槽 —— 接收对象发送消息的代码,即事件函数
使用方式:
1、Edit —> 编辑信号 / 槽
2、选择部件,此处将信号拉出指向主窗体
3、在弹出的配置连接框中,左侧选择该部件的事件,右侧选择指向部件(或者主程序)的对应事件
4、添加成功后,效果如下。当程序运行时,点击按钮则程序关闭
2、在 UIDesigner 空白处右键,打开 “动作编辑器”,
动作编辑器,默认在右边栏,需要手动点开。里面两个已存在的动作就对应 第1步中,手动添加的两个菜单栏的选项
双击对应的动作,可以对其属性进行编辑(包含显示文本、提示、图标、快捷键、是否为对勾选中形式等)
工具栏中添加按钮,其实质就是从 “动作编辑器” 中将某个动作,拖拽到工具栏上使其显示
功能:用于显示文本信息
主要方法如下:
方法 | 含义 |
---|---|
setAlignment() | 设置文本的对齐方式 |
setIndent() | 设置文本缩进 |
text() | 获取文本内容 |
setBuddy() | 设置伙伴关系 |
setText() | 设置文本内容 |
selectedText() | 设置所选择的字符 |
setWordWrap() | 设置是否允许换行 |
setPixmap(QPixmap()) | 图片标签 |
setToolTip() | 设置鼠标悬停的提示 |
.setOpenExternalLinks(True) | 当鼠标点击时,跳转到指定链接(label需要是个 a 标签,并且有有效的地址) |
setPalette() | 设置调色板(如背景颜色) |
常用事件(信号)
信号 | 含义 |
---|---|
linkHovered | 鼠标滑过 |
linkActivated | 鼠标点击 |
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("这是label1")
# 设置自动填充背景色
label1.setAutoFillBackground(True)
# 设置调色板
palette = QPalette()
palette.setColor(QPalette.Window, Qt.blue)
label1.setPalette(palette)
# 设置居中对齐
label1.setAlignment(Qt.AlignCenter)
label2.setText("欢迎")
label3.setAlignment(Qt.AlignCenter)
label3.setToolTip("这是一个图片标签")
label3.setPixmap(QPixmap("../static/img/pikaqiu2.jpeg"))
# 控制是否可以
label4.setOpenExternalLinks(True)
label4.setText("跳转到百度")
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 时,同时激活(通常是光标激活到)伙伴控件上
绑定方式: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_())
常用方法
方法 | 含义 |
---|---|
.setMaxLength(n) | 设置输入的最大字符数 |
.setReadOnly(True) | 是否设置内容为只读 |
.setEchoMode() | 设置其中的文本的回显模式 |
.setInputMask() | 掩码校验模式 |
.setValidator() | 校验器校验模式 |
.setAlignment() | 设置文本对齐方式 |
.setFont() | 设置文本格式 |
常用槽
槽 | 含义 |
---|---|
.textChanged | 文本变化事件 |
editingFinished | 编辑结束事件 |
四种回显模式:
- 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_())
含义:用于对输入数据类型进行或者格式进行限制,如仅允许输入数值、字母或者符合正则规范的格式等
常用类型(位于 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("这是HTML文本")
# 获取普通文本
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 —— 复选框
方法 | 含义 |
---|---|
.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_())
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_())
复选框具有三种状态
- 未选中 —— .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_())
常用方法
方法 | 含义 |
---|---|
.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_())
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_())
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_())
主要的对话框有以下几类
- 关于对话框
- 错误对话框
- 警告对话框
- 提问对话框
- 消息对话框
不同对话框的区别
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_())
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_())
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_())
输入框
主要方法
方法 | 功能 |
---|---|
.getItem() | 传入列表或元组,显示 QCombox |
.getText() | 录入普通文本 |
.getInt() | 录入整数 |
功能:用于弹出文件选择框
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_())
作用:用于完成栅格布局
主要方法如下
方法 | 含义 |
---|---|
addWidget() | 添加控件 |
参数按顺序含义如下:
1、QMainWindow —— 可以包含菜单栏、工具栏、状态栏和标题栏,是最常见的窗口形式
2、QDialog —— 是对话窗口的基类,以弹出窗口的形式来完成一个暂时的功能
3、QWidget —— 不确定窗口的用户,就使用QWidget
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_())
小窗口,常用于主程序的弹出框
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_())
方法 | 含义 |
---|---|
.x() | 窗口的 x 坐标(包含标题栏,距离屏幕最左侧的像素值) |
.y() | 窗口的 y 坐标(包含标题栏,距离屏幕最上方的像素值) |
.width() | 窗口的宽度值(包含标题栏,像素值) |
.height() | 窗口的高度值(包含标题栏,像素值) |
.geometry().x() | 窗口的 x 坐标(不包含标题栏,距离屏幕最左侧的像素值) |
.geometry().y() | 窗口的 y 坐标(不包含标题栏,距离屏幕最上方的像素值) |
.geometry().width() | 窗口的宽度值(包含标题栏,像素值) |
.geometry()height() | 窗口的高度值(包含标题栏,像素值) |
注:
PyQt5-stubs —— 强化 PyQt 在 Pycharm 中的自动补全