二、PyQt常用控件、布局管理、菜单、工具栏和状态栏
PyQt常用控件、布局管理、菜单、工具栏和状态栏的介绍和使用
二、核心技术
(一)PyQt5常用控件的使用
控件是窗口程序的基本组成单位,通过使用控件可以高效地开发窗口应用程序。所以,熟练掌握控件是合理、有效地进行窗口程序开发的重要前提。
1. 控件概述
控件是用户可以用来输入或操作数据的对象,也就相当于汽车中的方向盘、油门、刹车、离合器等,它们都是对汽车进行操作的控件。在PyQt5中,控件的基类位于QFrame类,而QFrame类继承自QWidget类,QWidget类是所有用户界面对象的基类。
1. 认识控件
Qt Designer设计器中默认对控件进行了分组。控件名称 | 说明 | 控件名称 | 说明 |
---|---|---|---|
Layouts——布局管理 | |||
VerticalLayout | 垂直布局 | HorizontalLayout | 水平布局 |
GridLayout | 网格布局 | FormLayout | 表单布局 |
Spacers——弹簧 | |||
HorizontalSpacer | 水平弹簧 | VerticalSpacer | 垂直弹簧 |
Buttons——按钮类 | |||
PushButton | 按钮 | ToolButton | 工具按钮 |
RadioButton | 单选按钮 | CheckBox | 复选框 |
CommandLinkButton | 命令链接按钮 | DialogButtonBox | 对话框按钮盒 |
Item Views(Model-Based)——项目视图 | |||
ListView | 列表视图 | TreeView | 树视图 |
TableView | 表格视图 | ColumnView | 列视图 |
UndoView | 撤销命令显示视图 | ||
Item Widgets(Item-Based)——项目控件 | |||
ListWidget | 列表控件 | TreeWidget | 树控件 |
TableWidget | 表格控件 | ||
Containers——容器 | |||
GroupBox | 分组框 | ScrollArea | 滚动区域 |
ToolBox | 工具箱 | TabWidget | 选项卡 |
StackedWidget | 堆栈窗口 | Frame | 帧 |
Widget | 小部件 | MDIArea | MDI区域 |
DockWidget | 停靠窗口 | ||
Input——输入控件 | |||
ComboBox | 下拉组合框 | FontComboBox | 字体组合框 |
LineEdit | 单行文本框 | TextEdit | 多行文本框 |
PlainTextEdit | 纯文本编辑框 | SpinBox | 数字选择控件 |
DoubleSpinBox | 小数选择控件 | TimeEdit | 时间编辑控件 |
DateEdit | 日期编辑框 | DateTimeEdit | 日期时间编辑框 |
Dial | 旋钮 | HorizontalScrollBar | 横向滚动条 |
VerticalScrollBar | 垂直滚动条 | HorizontalSlider | 横向滑块 |
VerticalSlider | 垂直滑块 | KeySequenceEdit | 按键编辑框 |
Display Widgets——显示控件 | |||
Label | 标签控件 | TextBrowser | 文本浏览器 |
GraphicsView | 图形视图 | CalendarWidget | 日期控件 |
LCDNumber | 液晶数字显示 | ProgressBar | 进度条 |
HorizontalLine | 水平线 | VerticalLine | 垂直线 |
OpenGLWidget | 开放式图形库工具 |
2.控件的命名规范
在使用控件的过程中,可以通过控件默认的名称调用。如果自定义控件名称,建议按照下表所示命名规范对控件进行命名。控件名称 | 命名 | 控件名称 | 命名 |
---|---|---|---|
Label | lab | ListView | lv |
LineEdit | ledit | ListWidget | lw |
TextEdit | tedit | TreeView | tv |
PlainTextEdit | pedit | TreeWidget | tw |
TextBrowser | txt | TableView | tbv |
PushButton | pbtn | TableWidget | tbw |
ToolButton | tbtn | GroupBox | gbox |
CommandLinkButton | linbtn | SpinBox | sbox |
RadioButton | rbtn | TabWidget | tab |
CheckBox | ckbox | TimeEdit | time |
ComboBox | cbox | DateEdit | date |
... | ... |
注意,控件的命名并不是绝对的,可以根据个人的喜好习惯或企业要求灵活使用。
2. 文本类控件
文本类控件主要用来显示或者编辑文本信息,PyQt5中的文本类控件主要有Label、LineEdit、TextEdit、SpinBox、DoubleSpinBox、LCDNumber等。
1. Label:标签控件
- 主要用于显示用户不能编辑的文本,标识窗体上的对象(例如,给文本框、列表框添加描述信息等),它对应PyQt5中的QLabel类,Label控件本质上是QLabel类的一个对象。
1. 设置标签文本
有两种方式设置标签控件显示的文本,第一种是直接在Qt Designer设计器的属性编辑器在那个设置text属性,第二种是通过Python代码设置。
(1)通过Qt Designer的text属性设置
(2)通过Python代码设置标签控件的显示文本
# 设置标签控件
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(40, 40, 100, 41))
self.label.setText("我是一个标签")
运行结果:
将.ui文件转换为.py文件时,Lable控件所对应的类为QLabel,即在控件前面加了一个“Q”,表示它是Qt的控件,其他控件也是如此。
2. 设置标签文本的对齐方式
PyQt5中支持设置标签文本的对齐方式,用到alignment属性,在Qt Designer的属性编辑器中展开alignment属性,可以看到有两个值,分别是Horizontal和Vertical,用于设置标签文本水平对齐方式和垂直对齐方式,取值有4个。
Horizontal取值及说明
值 | 说明 | 效果图 |
---|---|---|
AlignLeft | 左对齐 | |
AlignHCenter | 水平居中对齐 | |
AlignRight | 右对齐 | |
AlignJustify | 两端对齐,效果同AlignLeft |
Vertical取值及说明
值 | 说明 | 效果图 |
---|---|---|
AlignTop | 顶部对齐 | |
AlignVCenter | 垂直居中对齐 | |
AlignBottom | 底部对齐 |
使用代码设置Label标签文本的对齐方式,需要用到QLabel类的setAlignment()方法。例如,将标签文本的对齐方式设置为水平左对齐、垂直居中对齐。
self.label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
3. 设置文本换行显示
假设将标签文本的text值设置为“每天编程1小时,从菜鸟到大牛”,在标签宽度不足的情况下,系统会默认只显示部分文字。
遇到这种情况,可以设置标签中的文本换行显示,只需要在Qt Designer设计器的属性编辑器中,将wordWrap属性后面的复选框选中即可。
使用代码设置Label标签文本换行显示,需要用到QLabel类的setWordWrap()方法。
self.label.setWordWrap(True)
运行结果:
4. 为标签设置超链接
为Label标签设置超链接时,可以直接在QLabel类的setText()方法中使用HTML中的<a>标签设置超链接文本,然后将Label标签的setOpenExternalLinks()设置为True,以便允许访问超链接。
self.label.setText("<a href='https://www.mingrisoft.com'>明日学院</a>")
self.label.setOpenExternalLinks(True) # 设置允许访问超链接
当单击“明日学院”时,即可使用浏览器打开<a>标签中指定的网址。
运行结果:
完整的代码示例:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(300, 250)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 300, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 设置标签控件
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(40, 40, 100, 201))
# self.label.setText("我是一个标签,我的只有很多,未设置WordWrap为True时,我是显示不完全的,现在您可以看到我的全部内容啦")
self.label.setText("<a href='https://www.mingrisoft.com'>明日学院</a>")
self.label.setOpenExternalLinks(True) # 设置允许访问超链接
self.label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
# self.label.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.label.setWordWrap(True)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# self.pushButton.clicked.connect(self.open)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
# self.pushButton.setText(_translate("MainWindow", "打开"))
import sys
# 程序入口,程序从此处启动PyQt设计的窗体
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体方法,窗体对象初始化设置
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
5. 为标签设置图片
为Label标签设置图片时,需要使用QLabel类的setPixmap()方法,该方法中需要有一个QPixmap对象,表示图标对象。
from PyQt5.QtGui import QPixmap # 导入QPixmap类
self.label.setPixmap(QPixmap('test.png')) # 为label设置图片
运行效果如图:
完整的代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap # 导入QPixmap类
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(600, 250)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 300, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 设置标签控件
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(40, 40, 506, 123))
# self.label.setText("我是一个标签,我的只有很多,未设置WordWrap为True时,我是显示不完全的,现在您可以看到我的全部内容啦")
# self.label.setText("<a href='https://www.mingrisoft.com'>明日学院</a>")
# self.label.setOpenExternalLinks(True) # 设置允许访问超链接
# self.label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
# self.label.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
# self.label.setWordWrap(True)
self.label.setPixmap(QPixmap("./image/test.png")) # 为label设置图片
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# self.pushButton.clicked.connect(self.open)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
# self.pushButton.setText(_translate("MainWindow", "打开"))
import sys
# 程序入口,程序从此处启动PyQt设计的窗体
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体方法,窗体对象初始化设置
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
6. 获取标签文本
获取Label标签中的文本需要使用QLabel类的text()方法。下面的代码实现在控制台中打印Label中的文本:
print(self.label.text())
运行结果:
2. LineEdit:单行文本框
LineEdit是单行文本框,该控件只能输入单行字符串。
LineEdit控件对应PyQt5中的QLineEdit类。
QLineEdit类的常用方法及说明
方法 | 说明 |
---|---|
setText() | 设置文本框内容 |
text() | 获取文本框内容 |
setPlaceholderText() | 设置文本框浮显文字 |
setMaxLength() | 设置允许文本框内输入字符的最大长度 |
setAlignment() | 设置文本对齐方式 |
setReadOnly() | 设置文本框只读 |
setFocus() | 使文本框得到焦点 |
setEchoMode() |
|
setValidator() |
|
setInputMask() |
|
clear() | 清除文本框内容 |
QLineEdit类的常用信号及说明
信号 | 说明 |
---|---|
textChanged | 当更改文本框中的内容时发射该信号; |
editingFinished | 当文本框中的内容编辑结束时发射该信号,以按下Enter为编辑结束标志。 |
示例:包括用户名和密码的登录窗口
使用LineEdit控件,并结合Label控件制作一个简单的登录窗口,其中包含用户名和密码输入框,密码要求是8位数字,并且以掩码形式显示,步骤如下:
(1)打开Qt Desinger设计器,从工具箱中向主窗口放入两个Label控件与两个LineEdit控件,然后分别将两个Label控件的text值修改为“用户名:”和“密码:”:
(2)设计完成后,保存为.ui文件,并使用PyUIC工具将其转换为.py文件,并在表示密码的LineEdit文本框下面使用setEchoMode()将其设置为密码文本,同时使用setValidator()方法为其设置验证器,控制只能输入8位数字。
# 设置文本框为密码框
self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password)
# 设置只能输入8位数字
self.lineEdit_2.setValidator(QtGui.QIntValidator(10000000, 99999999))
(3)为.py文件添加__main__主方法。
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计器的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体的方法对象进行初始化设置
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
运行程序的效果如下:
整体代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(393, 261)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(90, 60, 81, 21))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(90, 110, 81, 16))
self.label_2.setObjectName("label_2")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(150, 60, 200, 21))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(150, 110, 200, 21))
self.lineEdit_2.setObjectName("lineEdit_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 393, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 设置文本框为密码框
self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password)
# 设置只能输入8位数字
self.lineEdit_2.setValidator(QtGui.QIntValidator(10000000, 99999999))
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "用户名:"))
self.label_2.setText(_translate("MainWindow", "密 码:"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计器的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体的方法对象进行初始化设置
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
注意,在密码文本框中输入字母或者超过8位数字时,系统将自动控制其输入,文本框中不会显示任何内容。
textChanged信号在一些要求输入值时实时执行操作的场景下经常使用。例如,上网购物时,更改购买的商品数量或者价格,总价格都会实时变化,如果用PyQt5设计类似这样的功能,就可以通过LineEdit控件的textChanged信号实现。
3. TextEdit:多行文本框
TextEdit是多行文本框控件,主要用来显示多行的文本内容,当文本内容超出控件的显示范围时,该控件将显示垂直滚动条;另外,TextEdit控件不仅可以显示纯文本内容,还支持显示HTML网页。
TextEdit控件对应PyQt5中的QTextEdit类。
QTextEdit类的常用方法及说明
方法 | 描述 |
---|---|
setPlainText() | 设置文本内容; |
toPlainText() | 获取文本内容; |
setTextColor() | 设置文本颜色,例如。将文本设置为红色,可以将该方法的参数设置为QtGui.QColor(255, 0, 0); |
setTextBackgroundColor() | 设置文本的背景颜色,颜色参数与setTextColor()相同; |
setHtml() | 设置HTML文档内容; |
toHtml() | 获取HTML文档内容; |
wordWrapMode() | 设置自动换行; |
clear() | 清除所有内容。 |
示例:多行文本和HTML文本的对比显示
使用Qt Designer设计器创建一个MainWindow窗口,在其中添加两个TextEdit控件,然后保存为.ui文件,使用PyUIC工具将.ui文件转换为.py文件,然后分别使用setPlainText()方法和setHtml()方法为两个TextEdit控件设置要显示的文本内容。
# 设置纯文本显示
self.textEdit.setPlainText('与失败比起来,有人对乏味和平庸的恐惧要严重的多。对他们而言,很好的事要比糟糕的事好,而糟糕的事要比平庸的事好,因为糟糕的事至少为生活添加了滋味。对我而言,对任何事都想要处之泰然,平庸的事为生活增添乏味,糟糕的事为生活增添苦味,美好的事为生活增添甜味。品味人生,就要尝尽各种味道,这样也没什么不好的。')
# 设置HTML文本显示
self.textEdit_2.setHtml("与失败比起来,有人对乏味和平庸的恐惧要严重的多。对他们而言,很好的事要比糟糕的事好,而糟糕的事要比平庸的事好,因为糟糕的事至少为生活添加了滋味。<font color='red' size='12'>对我而言,对任何事都想要处之泰然,平庸的事为生活增添乏味,糟糕的事为生活增添苦味,美好的事为生活增添甜味。</font>品味人生,就要尝尽各种味道,这样也没什么不好的。")
为.py文件添加__main__主方法,然后运行程序。
运行结果如下:
整体代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(994, 525)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(110, 90, 331, 311))
self.textEdit.setObjectName("textEdit")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(250, 60, 72, 15))
self.label.setObjectName("label")
self.textEdit_2 = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit_2.setGeometry(QtCore.QRect(560, 90, 331, 311))
self.textEdit_2.setObjectName("textEdit_2")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(700, 60, 72, 15))
self.label_2.setObjectName("label_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 994, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 设置纯文本显示
self.textEdit.setPlainText('与失败比起来,有人对乏味和平庸的恐惧要严重的多。对他们而言,很好的事要比糟糕的事好,'
'而糟糕的事要比平庸的事好,因为糟糕的事至少为生活添加了滋味。对我而言,对任何事都想要处之泰然,'
'平庸的事为生活增添乏味,糟糕的事为生活增添苦味,美好的事为生活增添甜味。品味人生,'
'就要尝尽各种味道,这样也没什么不好的。')
# 设置HTML文本显示
self.textEdit_2.setHtml("与失败比起来,有人对乏味和平庸的恐惧要严重的多。对他们而言,很好的事要比糟糕的事好,"
"而糟糕的事要比平庸的事好,因为糟糕的事至少为生活添加了滋味。<font color='red' size='12'>对我而言,"
"对任何事都想要处之泰然,平庸的事为生活增添乏味,糟糕的事为生活增添苦味,美好的事为生活增添甜味。</font>品味人生,"
"就要尝尽各种味道,这样也没什么不好的。")
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TextEdit应用"))
self.label.setText(_translate("MainWindow", "纯文本"))
self.label_2.setText(_translate("MainWindow", "HTML"))
# ########### 需要添加的代码,添加后才可以运行(即添加主函数)
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计器的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体的方法对象进行初始化设置
MainWindow.setWindowFlags(QtCore.Qt.Dialog) # 显示一个有问号(?)和关闭按钮的对话框
MainWindow.setWindowFlags(QtCore.Qt.WindowCloseButtonHint) # 只显示关闭按钮
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
4. SpinBox:整数数字选择控件
SpinBox是一个整数数字选择控件,该控件提供一对上下箭头,用户可以单击上下箭头选择数值,也可以直接输入。如果输入的数值大于设置的最大值,或者小于设置的最小值,SpinBox将不会接受输入.
SpinBox控件对应PyQt5中的QSpinBox类。
QPinBox类的常用方法及说明
方法 | 描述 |
---|---|
setValue() | 设置控件的当前值; |
setMaximum() | 设置最大值; |
setMinmun() | 设置最小值; |
setRange() | 设置取值范围(包括最大值和最小值); |
setSingleStep() | 单击上下箭头时的步长值; |
value() | 获取控件中的值。 |
默认情况下,SpinBox控件的取值范围为0~99,步长值为1。
在单击SpinBox控件的上下箭头时,可以通过发射valueChanged信号获取控件中的当前值。
示例:获取SpinBox中选择的数字
使用Qt Designer设计器创建一个MainWindow窗口,在其中添加两个Label控件和一个SpinBox控件,然后保存为.ui文件,使用PyUIC工具将.ui文件转换为.py文件,在转换后的.py文件中,分别设置数字选择控件的最小值、最大值和步长值。
关于SpinBox控件的关键代码:
self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
self.spinBox.setGeometry(QtCore.QRect(20, 10, 101, 22))
self.spinBox.setObjectName("spinBox")
self.spinBox.setMinimum(0) # 设置最小值
self.spinBox.setMaximum(100) # 设置最大值
# 上面两行代码等同于下面使用setRange()设置上下限的这句代码
# self.spinBox.setRange(0,100)
self.spinBox.setSingleStep(2) # 设置步长值
自定义一个getvalue()方法,使用value()方法获取SpinBox控件中的当前值,并显示在Label控件中。
# 获取SpinBox的当前值,并显示在Label中
def getvalue(self):
self.label_2.setText(str(self.spinBox.value()))
将SpinBox控件的valueChanged信号与自定义的getvalue()槽函数相关联。
# 将valueChanged信号与自定义槽函数相关联
self.spinBox.valueChanged.connect(self.getvalue)
运行结果:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(391, 354)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
self.spinBox.setGeometry(QtCore.QRect(20, 10, 101, 22))
self.spinBox.setObjectName("spinBox")
self.spinBox.setMinimum(0) # 设置最小值
self.spinBox.setMaximum(100) # 设置最大值
# 上面两行代码等同于下面使用setRange()设置上下限的这句代码
# self.spinBox.setRange(0,100)
self.spinBox.setSingleStep(2) # 设置步长值
# 将valueChanged信号与自定义槽函数相关联
self.spinBox.valueChanged.connect(self.getvalue)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(20, 30, 161, 31))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(180, 35, 61, 21))
self.label_2.setText("")
self.label_2.setObjectName("label_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 391, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TextEdit应用"))
self.label.setText(_translate("MainWindow", "当前控件中显示的数值:"))
# 获取SpinBox的当前值,并显示在Label中
def getvalue(self):
self.label_2.setText(str(self.spinBox.value()))
# ########### 需要添加的代码,添加后才可以运行(即添加主函数)
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计器的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体的方法对象进行初始化设置
MainWindow.setWindowFlags(QtCore.Qt.Dialog) # 显示一个有问号(?)和关闭按钮的对话框
MainWindow.setWindowFlags(QtCore.Qt.WindowCloseButtonHint) # 只显示关闭按钮
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
5. DoubleSpinBox:小数数字选择控件
DoubleSpinBox与SpinBox控件类似,区别是,它用来选择小数数字,并且默认保留两位小数,它对应PyQt5中的QDoubleSpinBox类。
DoubleSpinBox控件的使用方法与SpinBox类似,但由于它处理的是小数数字,因此,该控件提供了一个setDecimals()方法,用来设置小数的位数。
示例:设置DoubleSpinBox中的小数位数并获取选择的数字
使用Qt Designer设计器创建一个MainWindow窗口,在其中添加两个Label控件和一个DoubleSpinBox控件,然后保存为.ui文件,使用PyUIC工具将.ui文件转换为.py文件,在转换后的.py文件中,分别设置小数数字选择控件的最小值、最大值、步长值,以及保留3位小数。有关DoubleSpinBox控件的关键代码如下:
self.doubleSpinBox = QtWidgets.QDoubleSpinBox(self.centralwidget)
self.doubleSpinBox.setGeometry(QtCore.QRect(20, 10, 101, 22))
self.doubleSpinBox.setObjectName("doubleSpinBox")
self.doubleSpinBox.setMinimum(0) # 设置最小值
self.doubleSpinBox.setMaximum(99.999) # 设置最大值
self.doubleSpinBox.setSingleStep(0.001) # 设置步长值
self.doubleSpinBox.setDecimals(3) # 设置保留3位小数
自定义一个getvalue()方法,使用value()方法获取DoubleSpinBox控件中的当前值,并显示在Label控件中。
# 获取SpinBox的当前值,并显示在Label中
# 实际上该方法需要改进,改进后的代码在后面
def getvalue(self):
self.label_2.setText(str(self.doubleSpinBox.value()))
将DoubleSpinBox控件的valueChanged信号与自定义的getvalue()槽函数相关联。
# 将valueChanged信号与自定义槽函数相关联
self.doubleSpinBox.valueChanged.connect(self.getvalue)
为.py文件添加__main__主方法,然后运行程序,单击小数数字选择控件的上下箭头时,在Label控件中实时显示小数数字选择控件中的数值。运行效果如下图所示:
但是会出现超长的小数问题:
解决办法参考:https://blog.csdn.net/qq_39951477/article/details/111264698
问题1:解决小数位数显示问题
需要改进原本自定义的槽方法getValue(): ```python # 改进后的方法: def getvalue(self): val = str(round(self.doubleSpinBox.value(), 3)) index = val.index(".") # 找到小数点在数字字符串中所在的下标 if len(val[index + 1:]) == 2: # 只有两位小数 val = val + "0" elif len(val[index + 1:]) == 1: # 只有一位小数 val = val + "00" else: val = val self.label_2.setText(val) ``` ![在这里插入图片描述](https://img-blog.csdnimg.cn/ccc5e4adb00942df857f7a01b84979f1.png)运行结果:(小数位始终只会是3)
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(391, 354)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(20, 40, 161, 31))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(190, 40, 100, 21))
self.label_2.setText("")
self.label_2.setObjectName("label_2")
self.doubleSpinBox = QtWidgets.QDoubleSpinBox(self.centralwidget)
self.doubleSpinBox.setGeometry(QtCore.QRect(20, 10, 101, 22))
self.doubleSpinBox.setObjectName("doubleSpinBox")
self.doubleSpinBox.setMinimum(0) # 设置最小值
self.doubleSpinBox.setMaximum(99.999) # 设置最大值
self.doubleSpinBox.setSingleStep(0.001) # 设置步长值
self.doubleSpinBox.setDecimals(3) # 设置保留3位小数
# 将valueChanged信号与自定义槽函数相关联
self.doubleSpinBox.valueChanged.connect(self.getvalue)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 391, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TextEdit应用"))
self.label.setText(_translate("MainWindow", "当前控件中显示的数值:"))
# 获取SpinBox的当前值,并显示在Label中
# 以下方式为原文的方式,会出现label上显示小数位数和预期不符
# def getvalue(self):
# self.label_2.setText(str(self.doubleSpinBox.value()))
# 从网上找的方法:https://blog.csdn.net/qq_39951477/article/details/111264698
# 改进后的方法:
def getvalue(self):
val = str(round(self.doubleSpinBox.value(), 3))
index = val.index(".") # 找到小数点在数字字符串中所在的下标
if len(val[index + 1:]) == 2: # 只有两位小数
val = val + "0"
elif len(val[index + 1:]) == 1: # 只有一位小数
val = val + "00"
else:
val = val
self.label_2.setText(val)
# ########### 需要添加的代码,添加后才可以运行(即添加主函数)
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计器的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体的方法对象进行初始化设置
MainWindow.setWindowFlags(QtCore.Qt.Dialog) # 显示一个有问号(?)和关闭按钮的对话框
MainWindow.setWindowFlags(QtCore.Qt.WindowCloseButtonHint) # 只显示关闭按钮
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
6. LCDNumber:液晶数字显示控件
LCDNumber控件主要用来显示液晶数字。
LCDNumber控件对应PyQt5中的QLCDNumber类。
QLCDNumber类的常用方法及说明
方法 | 描述 |
---|---|
setDigitCount() | 设置可以显示的数字数量; |
setProperty() | 设置属性功能; |
setMode() | 设置显示数字的模式,有4种模式:Bin(二进制)、Oct(八进制)、Dec(十进制)、Hex(十六进制); |
setSegementStyle() | 设置显示样式,有3种样式:OutLine、Filled和Flat,它们的效果分别如下表所示; |
value() | 获取显示的数值。 |
样式 | 效果 |
---|---|
OutLine | |
Filled | |
Flat |
示例:液晶显示屏中的数字显示
使用Qt Designer设计器创建一个MainWindow窗口,在其中添加一个Label控件、一个LineEdit控件和一个LCDNumber控件,其中,LineEdit控件用来输入数字,LCDNumber控件用来显示LineEdit控件中的数字,将设计完成的窗口保存为.ui文件,使用PyUIC工具将.ui文件转换为.py文件,在转换后的.py文件中,设置LCDNumber液晶显示控件的最大显示数字位数、显示样式及模式。有关LCDNumber控件的关键代码如下:
self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber.setGeometry(QtCore.QRect(20, 40, 161, 41))
self.lcdNumber.setDigitCount(7) # 设置最大显示7位数字
self.lcdNumber.setMode(QtWidgets.QLCDNumber.Dec) # 设置默认以十进制显示数字
self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Flat) # 设置数字显示屏的显示样式
self.lcdNumber.setObjectName("lcdNumber")
自定义一个setvalue()方法,使用setProperty()方法为LCDNumber控件设置要显示的数字为LineEdit文本框中输入的数字。
# 定义槽函数,用来在液晶显示屏中显示文本框中的数字
def setvalue(self):
self.lcdNumber.setProperty("value", self.lineEdit.text())
将LineEdit控件的editingFinished信号与自定义的setvalue()槽函数相关联,以便在文本框编辑结束后执行槽函数中定义的操作。
# 文本框编辑结束时,发射editingFinished信号,与自定义槽函数关联
self.lineEdit.editingFinished.connect(self.setvalue)
为.py文件添加__main__主方法,然后运行程序,在文本框中输入数字,按Enter键,即可将输入的数字显示在液晶显示控件中。当文本框中输入的数字大于7位时,则会在液晶显示控件中以科学计数法的形式进行显示。
运行结果:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(388, 354)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(40, 50, 91, 16))
self.label.setObjectName("label")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(130, 50, 121, 21))
self.lineEdit.setObjectName("lineEdit")
self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
self.lcdNumber.setGeometry(QtCore.QRect(40, 90, 211, 71))
self.lcdNumber.setDigitCount(7) # 设置最大显示7位数字
self.lcdNumber.setMode(QtWidgets.QLCDNumber.Dec) # 设置默认以十进制显示数字
self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Flat) # 设置数字显示屏的显示样式
self.lcdNumber.setObjectName("lcdNumber")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 388, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# 文本框编辑结束时,发射editingFinished信号,与自定义槽函数关联
self.lineEdit.editingFinished.connect(self.setvalue)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "LCDNumber的应用"))
self.label.setText(_translate("MainWindow", "请输入数字:"))
# 定义槽函数,用来在液晶显示屏中显示文本框中的数字
def setvalue(self):
self.lcdNumber.setProperty('value', self.lineEdit.text())
# self.lcdNumber.display(self.lineEdit.text())
# ########### 需要添加的代码,添加后才可以运行(即添加主函数)
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计器的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体的方法对象进行初始化设置
MainWindow.setWindowFlags(QtCore.Qt.Dialog) # 显示一个有问号(?)和关闭按钮的对话框
MainWindow.setWindowFlags(QtCore.Qt.WindowCloseButtonHint) # 只显示关闭按钮
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
3. 按钮类控件
该类控件主要用来执行一些命令操作,主要有PushButton、ToolButton、CommandLinkButton、RadioButton和CheckBox等。
1. PushButton:按钮
常用控件之一,允许单击执行操作。可显示文本,也可显示图像。被单击时会有按下和释放的视觉状态。
PushButton控件对应PyQt5中的QPushButton类。
QPushButton类的常用方法及说明
方法 | 说明 |
---|---|
setText() | 设置按钮所现实的文本 |
text() | 获取按钮所显示的文本 |
setIcon() | 设置按钮上的图标,可以将参数设置为QtGui.GIcon(‘图标路径’) |
setIconSize() | 设置按钮图标的大小,参数可以设置为QtCore.QSize(int width, int height) |
setEnabled() | 设置按钮是否可用,参数设置为False时,按钮为不可用状态。 |
setShortcut() | 设置按钮的快捷键,参数可以设置为键盘中的按键或快捷键,例如“Alt + 0” |
PushButton按钮最常用的信号是clicked,当按钮被单击时,会发射该信号,执行相应的操作。
示例:制作登录窗口
完善LineEdit中的示例,为系统登录窗口添加“登录”和“退出”按钮,当单击“登录”按钮时,弹出用户输入的用户名和密码;而当单击“退出”按钮时,关闭当前登录窗口。
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap, QIcon
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(317, 292)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(50, 50, 72, 15))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(50, 90, 72, 15))
self.label_2.setObjectName("label_2")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(110, 50, 141, 21))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(110, 90, 141, 21))
self.lineEdit_2.setObjectName("lineEdit_2")
# 设置文本框为密码
self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password)
# 设置只能输入8位数字
self.lineEdit_2.setValidator(QtGui.QIntValidator(10000000, 99999999))
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(70, 130, 61, 31))
self.pushButton.setObjectName("pushButton")
# 为登录按钮设置图标
self.pushButton.setIcon(QIcon(QPixmap("./image/login.ico")))
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(170, 130, 61, 31))
self.pushButton_2.setObjectName("pushButton_2")
# 为退出按钮设置图标
self.pushButton_2.setIcon(QIcon(QPixmap("./image/exit.ico")))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 317, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
# 为登录按钮的clicked信号绑定自定义槽函数
self.pushButton.clicked.connect(self.login)
# 为退出按钮的clicked信号绑定MainWindow窗口自带的close槽函数
self.pushButton_2.clicked.connect(MainWindow.close)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TextEdit应用"))
self.label.setText(_translate("MainWindow", "用户名:"))
self.label_2.setText(_translate("MainWindow", "密 码:"))
self.pushButton.setText(_translate("MainWindow", "登录"))
# (替换上面的一句)设置登录快捷键:Alt+L
# self.pushButton.setText(_translate("MainWindow", "登录(&L)"))
self.pushButton_2.setText(_translate("MainWindow", "退出"))
# (替换上面的一句)设置退出快捷键:Alt+Q
# self.pushButton_2.setText(_translate("MainWindow", "退出(&Q)"))
# 自定义登录的槽函数
def login(self):
from PyQt5.QtWidgets import QMessageBox
# 使用information()方法弹出信息提示框
QMessageBox.information(MainWindow, "登录信息", "用户名:" + self.lineEdit.text() + " 密码:" + self.lineEdit_2.text(), QMessageBox.Ok)
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
运行结果:
点击“登录”按钮:
点击退出即可终止程序运行。
设置按钮的快捷键
若想为PushButton按钮设置快捷键,可在创建对象时指定其文本,并在文本中包括&符号,&符号后的第一个字母默认作为快捷键。例如,设置上面登录和退出按钮的快捷键:
# 设置登录快捷键:Alt+L
self.pushButton.setText(_translate("MainWindow", "登录(&L)"))
# 设置退出快捷键:Alt+Q
self.pushButton_2.setText(_translate("MainWindow", "退出(&Q)"))
修改完后,按Alt + L即可执行与单击“登录”按钮相同的操作,按Alt + Q即可执行与单击“退出”按钮相同的操作。
2. ToolButton:工具按钮
ToolButton控件是一个工具按钮,它本质上是一个按钮,只是在按钮中提供了默认文本“…”和可选的箭头类型,它对应PyQt5中的QToolButton类。
ToolButton控件的使用方法与PushButton类似,不同的是,ToolButton控件可以设置工具按钮的显示样式和箭头类型,其中,工具按钮的显示样式通过QToolButton类的setToolButtonStyle()方法进行设置。
QToolButton的setToolButtonStyle()方法支持的样式
样式 | 说明 |
---|---|
Qt.ToolButtonIconOnly | 只显示图标 |
Qt.ToolButtonTextOnly | 只显示文本 |
Qt.ToolButtonTextBesideIcon | 文本显示在图标的旁边 |
Qt.ToolButtonTextUnderIcon | 文本显示在图标的下面 |
Qt.ToolButtonFollowStyle | 跟随系统样式 |
工具按钮的箭头类型通过QToolButton类的setArrowType()方法进行设置。
QToolButton的setArrowType()方法支持的箭头类型
箭头类型 | 说明 |
---|---|
Qt.NoArrow | 没有箭头 |
Qt.UpArrow | 向上的箭头 |
Qt.DownArrow | 向下的箭头 |
Qt.LeftArrow | 向左的箭头 |
Qt.RightArrow | 向右的箭头 |
示例:设计一个向上箭头的工具按钮
本实例用来对名称为toolButton的工具按钮进行设置,设置其箭头类型为向上箭头,并且文本显示在箭头的下面。
self.toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) # 设置显示样式
self.toolButton.setArrowType(QtCore.Qt.UpArrow) # 设置箭头类型
运行结果:
ToolButton控件中的箭头图标默认大小为16×16,如果想改变箭头图标的大小,可以使用setIconSize()方法。例如,下面代码将ToolButton按钮的箭头图标大小修改为32×32:
# 设置图标大小
self.toolButton.setIconSize(QtCore.QSize(32, 32))
运行结果:
完整代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(317, 292)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.toolButton = QtWidgets.QToolButton(self.centralwidget)
# self.toolButton.setGeometry(QtCore.QRect(110, 80, 100, 100))
self.toolButton.setObjectName("toolButton")
# 设置显示样式
self.toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
# 设置箭头类型
self.toolButton.setArrowType(QtCore.Qt.UpArrow)
# 设置图标大小
self.toolButton.setIconSize(QtCore.QSize(32, 32))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 317, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TextEdit应用"))
self.toolButton.setText(_translate("MainWindow", "..."))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
3. CommandaLinkButton:命令链接按钮
CommandLinkButton控件是一个命令链接按钮,它对应PyQt5中的QCommandLinkButton类,该类与PushButton按钮的用法类似,区别是,该按钮自定义一个向右的箭头图标。
示例:命令链接按钮的使用
使用Qt Designer设计器创建一个MainWindow窗口,其中添加一个CommandLinkButton控件,并设置其文本为“https://www.mingrisoft.com”,运行程序。
程序代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(373, 186)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.commandLinkButton = QtWidgets.QCommandLinkButton(self.centralwidget)
self.commandLinkButton.setGeometry(QtCore.QRect(31, 50, 291, 48))
self.commandLinkButton.setObjectName("commandLinkButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 373, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TextEdit应用"))
self.commandLinkButton.setText(_translate("MainWindow", "https://www.mingrisoft.com"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
CommandLinkButton控件的默认效果:
鼠标移动到CommandLinkButton控件上的效果:
4. RadioButton:单选按钮
RadioButton是单选按钮控件,它为用户提供由两个或多个互斥选项组成的选项集,当用户选中某单选按钮时,同一组中的其他单选按钮不能同时选定。
RadioButton控件对应PyQt5中的QRadioButton类。
QRadioButton类的常用方法及说明
方法 | 说明 |
---|---|
setText() | 设置单选按钮显示的文本 |
text() | 获取单选按钮显示的文本 |
setChecked()或者setCheckable() | 设置单选按钮是否为选中状态,True为选中状态,False为未选中状态 |
isChecked() | 返回单选按钮的状态,True为选中状态,False为未选中状态 |
RadioButton控件常用的信号有两个:clicked和toggled,其中,clicked信号在每次单击单选按钮时都会发射,而toggled信号则在单选按钮的状态改变时才会发射,因此,通常使用toggled信号监控单选按钮的选择状态。
示例:选择用户登录角色
修改登录窗口,在窗口中添加两个RadioButton控件,用来选择管理员登录和普通用户登录,它们的文本分别设置为“管理员”和“普通用户”,然后定义一个槽函数select(),用来判断“管理员”单选按钮和“普通用户”单选按钮分别选中时的弹出信息,最后将“管理员”单选按钮的toggled信号与自定义的select()槽函数关联。
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(310, 250)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# "用户名"标签
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(50, 40, 72, 15))
self.label.setObjectName("label")
# "密码"标签
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(50, 70, 72, 20))
self.label_2.setObjectName("label_2")
# “用户名”输入框
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(110, 40, 131, 21))
self.lineEdit.setObjectName("lineEdit")
# “密码”输入框
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(110, 70, 131, 21))
self.lineEdit_2.setObjectName("lineEdit_2")
self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password) # 设置文本框为密码
self.lineEdit_2.setValidator(QtGui.QIntValidator(10000000, 99999999))
# “登录”按钮
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(50, 140, 91, 28))
self.pushButton.setObjectName("pushButton")
# “重置”按钮
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(160, 140, 93, 28))
self.pushButton_2.setObjectName("pushButton_2")
# “管理员”单选框
self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
self.radioButton.setGeometry(QtCore.QRect(60, 110, 115, 19))
self.radioButton.setObjectName("radioButton")
self.radioButton.setChecked(True) # 设置管理员单选框默认选中
# “普通用户”单选框
self.radioButton_2 = QtWidgets.QRadioButton(self.centralwidget)
self.radioButton_2.setGeometry(QtCore.QRect(160, 110, 115, 19))
self.radioButton_2.setObjectName("radioButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 386, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 绑定槽函数
# 为登录按钮的clicked信号绑定自定义槽函数
self.pushButton.clicked.connect(self.login)
# 为退出按钮的clicked信号绑定MainWindow窗口自带的close槽函数
self.pushButton_2.clicked.connect(MainWindow.close)
# 为单选按钮的toggled信号绑定自定义槽函数
self.radioButton.toggled.connect(self.select)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "TextEdit应用"))
self.label.setText(_translate("MainWindow", "用户名:"))
self.label_2.setText(_translate("MainWindow", "密 码:"))
self.pushButton.setText(_translate("MainWindow", "登录"))
self.pushButton_2.setText(_translate("MainWindow", "退出"))
self.radioButton.setText(_translate("MainWindow", "管理员"))
self.radioButton_2.setText(_translate("MainWindow", "普通用户"))
def login(self):
# 使用information()方法弹出星系提示框
QMessageBox.information(MainWindow, "登录信息", "用户名:"+self.lineEdit.text() + " 密码:" + self.lineEdit_2.text(), QMessageBox.Ok)
def select(self):
if self.radioButton.isChecked(): # 判读是否为管理员登录
QMessageBox.information(MainWindow, "提示", "您选择的是 管理员 登录", QMessageBox.Ok)
elif self.radioButton_2.isChecked(): # 判断是否为普通用户登录
QMessageBox.information(MainWindow, "提示", "您选择的是 普通用户 登录", QMessageBox.Ok)
import sys
# 主方法,程序从此处启动PyQt设计的窗体
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建P有Q他设计的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体方法,对窗体对象初始化设置
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
运行效果:
5. CheckBox:复选框
CheckBox是复选框控件,它用来表示是否选取了某个选项条件,常用于为用户提供具有是/否或真/假值的选项,它对应PyQt5中的QCheckBox类。
CheckBox控件的使用与RadioButton控件类似,但它是为用户提供“多选多”的选择,另外,它除了选中和未选中两种状态之外,还提供了第三种状态:半选中。如果需要第三种状态,需要使用QCheckBox类的setTristate()方法使其生效,并且可以使用checkState()方法查询当前状态。
CheckBox控件的三种状态值及说明
方法 | 说明 |
---|---|
QT.Checked | 选中 |
QT.PartiallyChecked | 半选中 |
QT.Unchecked | 未选中 |
CheckBox控件最常用的信号是stateChanged,用来在复选框的状态发生改变时发射。 |
示例:设置用户权限
在Qt Designer设计器中创建一个窗口,实现通过复选框的选中状态设置用户权限的功能。在窗口中添加5个CheckBox控件,文本分别设置为“基本信息管理”“进货管理”“销售管理”“库存管理”和“系统管理”,主要用来表示要设置的权限;添加一个PushButtion控件,用来显示选择的权限。设计完成后保存为.ui文件,并使用PyUIC工具将其转换为.py代码文件。在.py代码文件中自定义一个getvalue()方法,用来根据CheckBox控件的选中状态记录相应的权限。
设置权限的代码:
# 自定义槽函数,用于记录选中的权限状态
def getvalue(self):
oper = "" # 记录用户权限
if self.checkBox.isChecked(): # 判断复选框是否选中
oper += self.checkedBox.text() # 记录选中的权限
if self.checkBox_2.isChecked():
oper += "\n" + self.checkedBox_2.text()
if self.checkedBox_3.isChecked():
oper += "\n" + self.checkedBox_3.text()
if self.checkedBox_4.isChecked():
oper += "\n" + self.checkedBox_4.text()
if self.checkedBox_5.isChecked():
oper += "\n" + self.checkedBox_5.text()
from PyQt5.QtWidgets import QMessageBox
# 使用information()方法弹出信息提示,显示所有选择的权限
QMessageBox.information(MainWindow, "提示", "您选择的权限如下: \n" + oper, QMessageBox.Ok)
将“设置”按钮的clicked信号与自定义的槽函数getvalue()相关联。
self.pushButton.clicked.connect(self.getvalue)
为.py文件添加__main__主方法,然后运行程序,选中相应权限的复选框,单击“设置”按钮,即可在弹出提示框中显示用户选择的权限。
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(333, 235)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.checkBox.setGeometry(QtCore.QRect(40, 40, 131, 21))
self.checkBox.setObjectName("checkBox")
self.checkBox_2 = QtWidgets.QCheckBox(self.centralwidget)
self.checkBox_2.setGeometry(QtCore.QRect(40, 80, 91, 19))
self.checkBox_2.setObjectName("checkBox_2")
self.checkBox_3 = QtWidgets.QCheckBox(self.centralwidget)
self.checkBox_3.setGeometry(QtCore.QRect(40, 120, 91, 19))
self.checkBox_3.setObjectName("checkBox_3")
self.checkBox_4 = QtWidgets.QCheckBox(self.centralwidget)
self.checkBox_4.setGeometry(QtCore.QRect(210, 40, 91, 19))
self.checkBox_4.setObjectName("checkBox_4")
self.checkBox_5 = QtWidgets.QCheckBox(self.centralwidget)
self.checkBox_5.setGeometry(QtCore.QRect(210, 80, 91, 19))
self.checkBox_5.setObjectName("checkBox_5")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(210, 120, 81, 31))
self.pushButton.setObjectName("pushButton")
# 设置按钮的clicked信号与自定义的槽函数getvalue()相关联。代码如下:
self.pushButton.clicked.connect(self.getvalue)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 333, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "设置用户权限"))
self.checkBox.setText(_translate("MainWindow", "基本信息管理"))
self.checkBox_2.setText(_translate("MainWindow", "进货管理"))
self.checkBox_3.setText(_translate("MainWindow", "销售管理"))
self.checkBox_4.setText(_translate("MainWindow", "库存管理"))
self.checkBox_5.setText(_translate("MainWindow", "系统管理"))
self.pushButton.setText(_translate("MainWindow", "设置"))
# 自定义槽函数,用于记录选中的权限状态
def getvalue(self):
oper = "" # 记录用户权限
if self.checkBox.isChecked(): # 判断复选框是否选中
oper += self.checkBox.text() # 记录选中的权限
if self.checkBox_2.isChecked():
oper += "\n" + self.checkBox_2.text()
if self.checkBox_3.isChecked():
oper += "\n" + self.checkBox_3.text()
if self.checkBox_4.isChecked():
oper += "\n" + self.checkBox_4.text()
if self.checkBox_5.isChecked():
oper += "\n" + self.checkBox_5.text()
from PyQt5.QtWidgets import QMessageBox
# 使用information()方法弹出信息提示,显示所有选择的权限
QMessageBox.information(MainWindow, "提示", "您选择的权限如下: \n" + oper, QMessageBox.Ok)
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
在设计用户权限,或者考试系统中的多选题答案等功能时,可以使用CheckBox控件来实现。
4. 选择列表类控件
选择列表类控件主要以列表形式为用户提供选择的项目,用户可从中选择项。该类控件包括ComboBox、FontComboBox和ListWidget等。
1. CimboBox:下拉组合框
ComboBox控件,又称为下拉组合框控件,它主要用于在下拉组合框中显示数据,用户可以从中选择项。
QComboBox类的常用方法及说明
方法 | 说明 |
---|---|
addItem() | 添加一个下拉列表项 |
addItems() | 从列表中添加下拉选项 |
currentText() | 获取选中项的文本 |
currentIndex() | 获取选中项的索引 |
itemText(index) | 获取索引为index的项的文本 |
setItemText(index) | 设置索引为index的项的文本 |
count() | 获取所有选项的数量 |
clear() | 删除所有选项 |
ComboBox控件常用的信号有两个:activated和currentIndexChanged,其中,activated信号在用户选中一个下拉选项时发射,而currentIndexChanged信号则在下拉选项的索引发生改变时发射。
示例:在下拉列表中选择职位
在Qt Designer设计器中创建一个窗口,实现通过ComboBox控件选择职位的功能。在窗口中添加两个Label控件和一个ComboBox,其中,第一个Label用来作为标识,将文本设置为“职位:”,第二个Label用来显示ComboBox中选择的职位;ComboBox控件用来作为职位的下拉列表。设计完成后保存为.ui文件,并使用PyUIC工具将其转换为.py代码文件。在.py代码文件中自定义一个showinfo()方法,用来将ComboBox下拉列表中选择的项显示在Label标签中。
槽方法如下:
# 设置槽方法
def showinfo(self):
self.label_2.setText("您选择的职位是:" + self.comboBox.currentText()) # 显示选择的职位
为ComboBox设置下拉列表项及信号与槽的关联。关联代码如下:
# 定义职位列表
list1 = ["总经理", "副总经理", "人事部经理", "财务部经理", "部门经理", "普通员工"]
self.comboBox.addItems(list1) # 将职位列表添加到ComboBox下拉列表中
# 将ComboBox控件的选项更改信号与自定义槽函数关联
self.comboBox.currentIndexChanged.connect(self.showinfo)
为.py文件添加__main__主方法,然后运行程序,当在职位列表中选中某个职位时,将会在下方的Label标签中显示选中的职位。
运行结果如下:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(333, 235)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(90, 50, 72, 15))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(80, 90, 200, 16))
self.label_2.setWordWrap(False)
self.label_2.setObjectName("label_2")
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setGeometry(QtCore.QRect(130, 50, 105, 22))
self.comboBox.setObjectName("comboBox")
# 定义职位列表
list1 = ["总经理", "副总经理", "人事部经理", "财务部经理", "部门经理", "普通员工"]
self.comboBox.addItems(list1) # 将职位列表添加到ComboBox下拉列表中
# 将ComboBox控件的选项更改信号与自定义槽函数关联
self.comboBox.currentIndexChanged.connect(self.showinfo)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 333, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "设置用户权限"))
self.label.setText(_translate("MainWindow", "职位:"))
# self.label_2.setText(_translate("MainWindow", "您选择的职位是:"))
# self.label_2.setText(_translate("MainWindow", ""))
# 设置槽方法
def showinfo(self):
self.label_2.setText("您选择的职位是:" + self.comboBox.currentText()) # 显示选择的职位
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
2. FontComboBox:字体组合框
FontComboBox控件又称为字体组合框控件,它主要用于在下拉组合框中显示并选择字体,它对应PyQt5中的QFontComboBox类。
FontComboBox控件的使用与ComboBox类似,但由于它的主要作用是选择字体,所以QFontComboBox类中提供了一个setFontFilters()方法,用来设置可以选择的字体。
QFontComboBox类的setFontFilters()方法的参数及说明
参数 | 说明 |
---|---|
QFontComboBox.AllFonts | 所有字体 |
QFontComboBox.ScalableFonts | 可以自动伸缩的字体 |
QFontComboBox.NonScalableFonts | 不自动伸缩的字体 |
QFontComboBox.MonospacedFonts | 等宽字体 |
QFontComboBox.ProportionalFonts | 比例字体 |
示例:动态改变标签的字体
在Qt Designer设计器中创建一个窗口,实现通过FontComboBox动态改变Label标签字体的功能。在窗口中添加一个Label控件和一个FontComboBox,其中,Label用来显示文本,而FontComboBox控件用来选择字体。设计完成后保存为.ui文件,并使用PyUIC工具将其转换为.py代码文件。在.py代码文件中自定义一个setfont()方法,用来将选择的字体设置为Label标签的字体。
槽函数的代码如下:
# 自定义槽函数,用来将选择的字体设置为Label标签的字体
def setfont(self):
print(self.fontComboBox.currentText()) # 控制台中输出选择的字体
# 为Label设置字体
self.label.setFont(QtGui.QFont(self.fontComboBox.currentText()))
为FontComboBox设置要显示的字体及信号与槽的关联。关联代码如下:
# 设置字体组合框中显示所有字体
self.fontComboBox.setFontFilters(QtWidgets.QFontComboBox.AllFonts)
# 当选择的字体改变时,发射currentIndexChanged信号,调用setfont槽函数
self.fontComboBox.currentIndexChanged.connect(self.setfont)
为.py文件添加__main__主方法,然后运行程序,在窗口中的字体下拉组合框中选择某种字体时,会在控制台中输出选择的字体,同时,Label标签中的字体也会更改为选择的字体。如图9.46和图9.47所示是在字体下拉组合框中分别选择“华文琥珀”字体和“楷体”字体时的效果。
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(333, 172)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.fontComboBox = QtWidgets.QFontComboBox(self.centralwidget)
self.fontComboBox.setGeometry(QtCore.QRect(30, 20, 279, 22))
self.fontComboBox.setObjectName("fontComboBox")
# 设置字体组合框中显示所有字体
self.fontComboBox.setFontFilters(QtWidgets.QFontComboBox.AllFonts)
# 当选择的字体改变时,发射currentIndexChanged信号,调用setfont槽函数
self.fontComboBox.currentIndexChanged.connect(self.setfont)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(50, 70, 251, 31))
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 333, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "设置用户权限"))
self.label.setText(_translate("MainWindow", "长风破浪会有时,直挂云帆济沧海。"))
# 自定义槽函数,用来将选择的字体设置为Label标签的字体
def setfont(self):
print(self.fontComboBox.currentText()) # 控制台中输出选择的字体
# 为Label设置字体
self.label.setFont(QtGui.QFont(self.fontComboBox.currentText()))
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
3. ListWidget:列表
PyQt5提供了两种列表,分别是ListWidget和ListView,其中,ListView是基于模型的,它是ListWidget的父类,使用ListView时,首先需要建立模型,然后再保存数据;而ListWidget是ListView的升级版本,它已经内置了一个数据存储模型QListWidgetItem,我们在使用时,不必自己建立模型,而直接使用addItem()或者addItems()方法即可添加列表项。所以在实际开发时,推荐使用ListWidget控件作为列表。
ListWidget控件对应PyQt5中的QListWidget类。
QListWidget类的常用方法及说明
方法 | 说明 |
---|---|
addItem() | 向列表中添加项。 |
addItems() | 一次向列表中添加多项。 |
insertItem() | 在指定索引处插入项。 |
setCurrentItem() | 设置当前选择项。 |
item.setToolTip() | 设置提示内容。 |
item.isSelected() | 判断项是否选中。 |
setSelectionMode() |
|
setSelectionBehavior() |
|
setWordWrap() | 设置是否自动换行,True表示自动换行,False表示不自动换行。 |
setViewMode() |
|
item.text() | 获取项的文本。 |
clear() | 删除所有列表项。 |
ListWidget控件常用的信号有两个:currentItemChanged和itemClicked,currentItemChanged信号在列表中的选择项发生改变时发射,而itemClicked信号在单击列表中的项时发射。
示例:用列表展示内地电影票房总排行榜
2019年,我国的年电影票房已经突破642亿元,较2018年同期增长5.4%,其中,国产电影总票房411.75亿元,同比增长8.65%,市场占比64.07%,从中可以看出,国产电影在内地票房中的占比变得越来越重要,这其中的一个关键因素是,国产电影的质量有了很大的飞跃。近几年,我们所熟知的《战狼2》《我和我的祖国》《流浪地球》等优质国产电影不断呈现在大荧幕上,而观众也用高票房回馈了这些优秀的国产电影。本实例将使用PyQt5中的ListWidget列表展示内地票房总排行榜的前10名,从中可以看到,其中的90%都是国产电影。
打开Qt Designer设计器,新建一个窗口,在窗口中添加一个ListWidget控件,设计完成后保存为.ui文件,并使用PyUIC工具将其转换为.py代码文件。在.py代码文件中,首先对ListWidget的显示数据及itemClicked信号进行设置。
# 设置列表中可以多选
self.listWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
# 设置选中方式为整行选中
self.listWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
# 设置以列表形式显示数据
self.listWidget.setViewMode(QtWidgets.QListView.ListMode)
# 设置自动换行
self.listWidget.setWordWrap(True)
from collections import OrderedDict
# 定义有序字典,作为List列表的数据源
dict = OrderedDict({'第1名': '战狼2,2017年上映,票房56.83亿', '第2名': '哪吒之魔童降世,2019年上映,票房50.12亿', '第3名': '流浪地球,2019年上映,票房46.86亿', '第4名': '复仇者联盟:终局之战,2019年上映,票房42.50亿', '第5名': '红海行动,2018年上映,票房36.51亿', '第6名': '唐人街探案2,2018年上映,票房33.98亿', '第7名': '美人鱼,2016年上映,票房33.86亿', '第8名': '我和我的祖国,2019年上映,票房31.71亿', '第9名': '我不是药神,2018年上映,票房31.00亿', '第10名': '中国机长,2019年上映,票房29.13亿'})
for key, value in dict.items(): # 遍历字典,并分别获取到键值
self.item = QtWidgets.QListWidgetItem(self.listWidget) # 创建列表项
self.item.setText(key + ":" + value) # 设置项文本
self.item.setToolTip(value) # 设置提示文字
self.listWidget.itemClicked.connect(self.gettext)
Python中的字典默认是无序的,可以借助collections模块的OrderedDict类来使字典有序。
编写槽函数如下:
def gettext(self, item): # 自定义槽函数,获取列表中项的值
if item.isSelected(): # 判断项是否选中
from PyQt5.QtWidgets import QMessageBox
QMessageBox.information(MainWindow, "提示", "您选择的是:" + item.text(), QMessageBox.Ok)
为.py文件添加__main__主方法,然后运行程序。当用户单击列表中的某项时,弹出提示框,提示选择了某一项。
运行结果如下:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(564, 391)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.listWidget = QtWidgets.QListWidget(self.centralwidget)
self.listWidget.setGeometry(QtCore.QRect(23, 30, 511, 311))
self.listWidget.setObjectName("listWidget")
# 设置列表中可以多选
self.listWidget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
# 设置选中方式为整行选中
self.listWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
# 设置以列表形式显示数据
self.listWidget.setViewMode(QtWidgets.QListView.ListMode)
# 设置自动换行
self.listWidget.setWordWrap(True)
from collections import OrderedDict
# 定义有序字典,作为List列表的数据源
dict = OrderedDict(
{'第1名': '战狼2,2017年上映,票房56.83亿', '第2名': '哪吒之魔童降世,2019年上映,票房50.12亿', '第3名': '流浪地球,2019年上映,票房46.86亿',
'第4名': '复仇者联盟:终局之战,2019年上映,票房42.50亿', '第5名': '红海行动,2018年上映,票房36.51亿', '第6名': '唐人街探案2,2018年上映,票房33.98亿',
'第7名': '美人鱼,2016年上映,票房33.86亿', '第8名': '我和我的祖国,2019年上映,票房31.71亿', '第9名': '我不是药神,2018年上映,票房31.00亿',
'第10名': '中国机长,2019年上映,票房29.13亿'})
for key, value in dict.items(): # 遍历字典,并分别获取到键值
self.item = QtWidgets.QListWidgetItem(self.listWidget) # 创建列表项
self.item.setText(key + ":" + value) # 设置项文本
self.item.setToolTip(value) # 设置提示文字
self.listWidget.itemClicked.connect(self.gettext)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 564, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "设置用户权限"))
def gettext(self, item): # 自定义槽函数,获取列表中项的值
if item.isSelected(): # 判断项是否选中
from PyQt5.QtWidgets import QMessageBox
QMessageBox.information(MainWindow, "提示", "您选择的是:" + item.text(), QMessageBox.Ok)
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
5. 容器控件
容器控件可以将窗口中的控件进行分组处理,使窗口的分类更清晰,常用的容器控件有GroupBox分组框、TabWidget选项卡和ToolBox工具盒。
1. GroupBox:分组框
Group控件又称为分组控件,主要为其他控件提供分组,并且按照控件的分组来细分窗口的功能。
GroupBox控件对应PyQt5中的QGroupBox类。
QGroupBox类的常用方法及说明
方法 | 说明 |
---|---|
setAlignment() | 设置对齐方式,包括水平对齐和垂直对齐两种。
|
setTitle() | 设置分组标题。 |
setFlat() | 设置是否以扁平样式显示。 |
QGroupBox类最常用的是setTitle()方法,用来设置分组框的标题。例如,下面代码用来为GroupBox控件设置标题“系统登录”:
self.groupBox.setTitle("系统登录")
2. TabWidget:选项卡
TabWidget控件又称选项卡控件,它主要为其他控件提供分组,并且按照控件的分组来细分窗口的功能。
TabWidget控件对应PyQt5中的QTabWidget类。
QTabWidget类的常用方法及说明
方法 | 说明 |
---|---|
addTab() | 添加选项卡 |
inserTab() | 插入选项卡 |
removeTab() | 删除选项卡 |
currentWidget() | 获取当前选项卡 |
currentIndex() | 获取当前选项卡的索引 |
setCurrentIndex() | 设置当前选项卡的索引 |
setCurrentWidget() | 设置当前选项卡 |
setTabPoistion() | 设置选项卡的标题位置,支持以下4个位置:
|
setTabsClosable() | 设置是否可以独立关闭选项卡,True表示可以关闭,在每个选项卡旁边会有个关闭按钮。 |
setTabText() | 设置选项卡标题文本。 |
tabText() | 获取指定选项卡的标题文本 |
setTabPoistion()方法中的4个位置参数效果
参数 | 效果图 |
---|---|
QTabWidget.North | |
QTabWidget.Sourth | |
QTabWidget.West | |
QTabWidget.East |
通过将setTabsClosable()方法设置为True可以单独关闭选项卡:
TabWidget在显示选项卡时,如果默认大小显示不下,会自动生成向前和向后的箭头,用户可以单击箭头查看未显示的选项卡。
TabWidget控件最常用的信号是currentChanged,该信号在切换选项卡时发射。
示例:选项卡的动态添加和删除
用QT Designer在窗口中添加一个TabWidget控件和两个PushButton控件,其中,TabWidget控件作为选项卡,两个PushButton控件分别执行添加和删除选项卡的操作。保存ui文件,转换为py代码文件。在py文件中定义3个函数,分别实现新增选项卡、删除选项卡和获取选中选项卡及索引的功能。
# 定义槽函数
# 新增选项卡
def addtab(self):
self.atab = QtWidgets.QWidget() # 创建选项卡对象
name = "tab_" + str(self.tabWidget.count() + 1) # 设置选项卡的对象名
self.atab.setObjectName(name) # 设置选项卡的对象名
self.tabWidget.addTab(self.atab, name) # 添加选项卡
# 删除选项卡
def deltab(self):
self.tabWidget.removeTab(self.tabWidget.currentIndex()) # 移除当前选项卡
# 获取选中的选项卡及索引
def gettab(self, currentIndex):
from PyQt5.QtWidgets import QMessageBox
QMessageBox.information(MainWindow, "提示", "您选择了 " + self.tabWidget.tabText(currentIndex) + " 选项卡,索引为:" + str(self.tabWidget.currentIndex()), QMessageBox.Ok)
分别为“添加”“删除”按钮,以及选项卡的currentChanged信号绑定自定义的槽函数。
# 将槽函数与信号绑定
self.pushButton.clicked.connect(self.addtab) # 为“添加”绑定单击信号
self.pushButton_2.clicked.connect(self.deltab) # 为“删除”按钮绑定单击信号
self.tabWidget.currentChanged.connect(self.gettab) # 为选项卡绑定页面切换信号
为.py文件添加__main__主方法,然后运行程序,窗口中默认有两个选项卡,单击“添加”按钮,可以按顺序添加选项卡,单击“删除”按钮,可以删除当前鼠标焦点所在的选项卡。当切换选项卡时,在弹出的提示框中将显示当前选择的选项卡及其索引。
当删除某个选项卡时,选项卡会自动切换到前一个,因此也会弹出相应的信息提示。
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(564, 391)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setGeometry(QtCore.QRect(0, 0, 561, 301))
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(110, 310, 93, 28))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(320, 310, 93, 28))
self.pushButton_2.setObjectName("pushButton_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 564, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 将槽函数与信号绑定
self.pushButton.clicked.connect(self.addtab) # 为“添加”绑定单击信号
self.pushButton_2.clicked.connect(self.deltab) # 为“删除”按钮绑定单击信号
self.tabWidget.currentChanged.connect(self.gettab) # 为选项卡绑定页面切换信号
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "设置用户权限"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
self.pushButton.setText(_translate("MainWindow", "添加"))
self.pushButton_2.setText(_translate("MainWindow", "删除"))
# 定义槽函数
# 新增选项卡
def addtab(self):
self.atab = QtWidgets.QWidget() # 创建选项卡对象
name = "tab_" + str(self.tabWidget.count() + 1) # 设置选项卡的对象名
self.atab.setObjectName(name) # 设置选项卡的对象名
self.tabWidget.addTab(self.atab, name) # 添加选项卡
# 删除选项卡
def deltab(self):
self.tabWidget.removeTab(self.tabWidget.currentIndex()) # 移除当前选项卡
# 获取选中的选项卡及索引
def gettab(self, currentIndex):
from PyQt5.QtWidgets import QMessageBox
QMessageBox.information(MainWindow, "提示", "您选择了 " + self.tabWidget.tabText(currentIndex) + " 选项卡,索引为:" + str(self.tabWidget.currentIndex()), QMessageBox.Ok)
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
3. ToolBox:工具盒
主要提供一种列状层叠选项卡。
QToolBox类的常用方法及说明
方法 | 说明 |
---|---|
addItem() | 添加选项卡 |
setCurrentIndex() | 设置当前选中的选项卡索引 |
setItemIcon() | 设置选项卡的图标 |
setItemText() | 设置选项卡的标题文本 |
setItemEnabled() | 设置选项卡是否可用 |
inserItem() | 插入新选项卡 |
removeItem() | 移除选项卡 |
itemText() | 获取选项卡的文本 |
currentIndex() | 获取当前选项卡的索引 |
ToolBox控件最常用的信号是currentChanged,该信号在切换选项卡时发射。
示例:仿QQ抽屉效果
打开Qt Designer设计器,使用ToolBox控件,并结合ToolButton工具按钮设计一个仿照QQ抽屉效果(一种常用的、能够在有限空间中动态直观地显示更多功能的效果)的窗口。
运行结果如下:
完整代码如下:
from PyQt5 import QtCore, QtWidgets
from PyQt5 import QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
# MainWindow.resize(142, 393)
MainWindow.resize(200, 393)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# 创建ToolBox工具盒
self.toolBox = QtWidgets.QToolBox(self.centralwidget)
self.toolBox.setGeometry(QtCore.QRect(0, 0, 199, 391))
self.toolBox.setObjectName("toolBox")
# 我的好友设置
self.page = QtWidgets.QWidget()
self.page.setGeometry(QtCore.QRect(0, 0, 200, 287))
self.page.setObjectName("page")
self.toolButton = QtWidgets.QToolButton(self.page)
self.toolButton.setGeometry(QtCore.QRect(0, 0, 199, 51))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("./image/01.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton.setIcon(icon)
self.toolButton.setIconSize(QtCore.QSize(96, 96))
self.toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton.setAutoRaise(True)
self.toolButton.setObjectName("toolButton")
self.toolButton_2 = QtWidgets.QToolButton(self.page)
self.toolButton_2.setGeometry(QtCore.QRect(0, 49, 199, 51))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("./image/02.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton_2.setIcon(icon1)
self.toolButton_2.setIconSize(QtCore.QSize(96, 96))
self.toolButton_2.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton_2.setAutoRaise(True)
self.toolButton_2.setObjectName("toolButton_2")
self.toolButton_3 = QtWidgets.QToolButton(self.page)
self.toolButton_3.setGeometry(QtCore.QRect(0, 103, 199, 51))
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap("./image/03.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton_3.setIcon(icon2)
self.toolButton_3.setIconSize(QtCore.QSize(96, 96))
self.toolButton_3.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton_3.setAutoRaise(True)
self.toolButton_3.setObjectName("toolButton_3")
self.toolBox.addItem(self.page, "")
# 同学设置
self.page_2 = QtWidgets.QWidget()
self.page_2.setGeometry(QtCore.QRect(0, 0, 200, 287))
self.page_2.setObjectName("page_2")
self.toolButton_4 = QtWidgets.QToolButton(self.page_2)
self.toolButton_4.setGeometry(QtCore.QRect(0, 0, 199, 51))
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap("./image/04.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton_4.setIcon(icon3)
self.toolButton_4.setIconSize(QtCore.QSize(96, 96))
self.toolButton_4.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton_4.setAutoRaise(True)
self.toolButton_4.setObjectName("toolButton_4")
self.toolBox.addItem(self.page_2, "")
# 同事设置
self.page_3 = QtWidgets.QWidget()
self.page_3.setObjectName("page_3")
self.toolButton_5 = QtWidgets.QToolButton(self.page_3)
self.toolButton_5.setGeometry(QtCore.QRect(0, 1, 199, 51))
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap("./image/05.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton_5.setIcon(icon4)
self.toolButton_5.setIconSize(QtCore.QSize(96, 96))
self.toolButton_5.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton_5.setAutoRaise(True)
self.toolButton_5.setObjectName("tooButton_5")
self.toolButton_6 = QtWidgets.QToolButton()
self.toolButton_6.setGeometry(QtCore.QRect(0, 50, 199, 51))
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap("./image/06.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton_6.setIcon(icon5)
self.toolButton_6.setIconSize(QtCore.QSize(96, 96))
self.toolButton_6.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton_6.setAutoRaise(True)
self.toolButton_6.setObjectName("toolButton_6")
self.toolBox.addItem(self.page_3, "")
# 陌生人设置
self.page_4 = QtWidgets.QWidget()
self.page_4.setObjectName("page_4")
self.toolButton_7 = QtWidgets.QToolButton(self.page_4)
self.toolButton_7.setGeometry(QtCore.QRect(0, 7, 199, 51))
icon6 = QtGui.QIcon()
icon6.addPixmap(QtGui.QPixmap("./image/07.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.toolButton_7.setIcon(icon6)
self.toolButton_7.setIconSize(QtCore.QSize(96, 96))
self.toolButton_7.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.toolButton_7.setAutoRaise(True)
self.toolButton_7.setObjectName("toolButton_7")
self.toolBox.addItem(self.page_4, "")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
self.toolBox.setCurrentIndex(0) # 默认选择第一个页面,即我的好友
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "我的QQ"))
self.toolButton.setText(_translate("MainWindow", "及时雨 宋江"))
self.toolButton_2.setText(_translate("MainWindow", "玉麒麟 卢俊义"))
self.toolButton_3.setText(_translate("MainWindow", "智多星 吴用"))
self.toolBox.setItemText(self.toolBox.indexOf(self.page), _translate("MainWindow", "我的好友"))
self.toolButton_4.setText(_translate("MainWindow", "豹子头 林冲"))
self.toolBox.setItemText(self.toolBox.indexOf(self.page_2), _translate("MainWindow", "同学"))
self.toolButton_5.setText(_translate("MainWindow", "花和尚 鲁智深"))
self.toolButton_6.setText(_translate("MainWindow", "行者 武松"))
self.toolBox.setItemText(self.toolBox.indexOf(self.page_3), _translate("MainWindow", "同事"))
self.toolButton_7.setText(_translate("MainWindow", "方腊"))
self.toolBox.setItemText(self.toolBox.indexOf(self.page_4), _translate("MainWindow", "陌生人"))
import sys
# 主方法,程序从此处启动PyQt窗体
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
6. 日期时间类控件
日期时间类控件主要是对日期、时间等信息进行编辑、选择或者显示,PyQt5中提供了Date/TimeEdit、DateEdit、TimeEdit和CalendarWidget 4个相关的控件。
1. 日期和(或)时间控件
PyQt5提供了3个日期时间控件,分别是Date/TimeEdit控件、DateEdit控件和TimeEdit控件。
Date/TimeEdit控件对应的类是QDateTimeEdit,该控件可以同时显示和编辑日期时间。DateEdit控件对应的类是QDateEdit,它是QDateTimeEdit子类,只能显示和编辑日期。TimeEdit控件对应的类是QTimeEdit,它是QDateTimeEdit子类,只能显示和编辑时间。
QDateTimeEdit类的常用方法及说明
方法 | 说明 |
---|---|
setTime() | 设置时间,默认为0:00:00 |
setMaximunTime() | 设置最大时间,默认为23:59:59 |
setMinimunTime() | 设置最小时间,默认为0:00:00 |
setTimeSpec() | 获取显示的时间标准,支持以下4种值:
|
setDateTime() | 设置日期时间,默认为2000/1/1 0:00:00 |
setDate() | 设置日期,默认为2000/1/1 |
setMaximunDate() | 设置最大日期,默认为9999/12/31 |
setMinimunDate() | 设置最小日期,默认为1752/9/14 |
setDisplayFormat() | 设置日期、时间的显示样式:
|
date() | 获取显示的日期,返回值为QDate类型,如QDate(2000, 1, 1) |
time() | 获取显示的时间,返回值为QTime类型,如QTime(0, 0) |
dateTime() | 获取显示的日期时间,返回值为QDateTime类型,如QDateTime(2000, 1, 1, 0, 0) |
由于QDateEdit和QTimeEdit都是从QDateTimeEdit继承而来的,因此,他们都拥有QDateTimeEdit类的所有公共方法。
QDateTimeEdit类的常用信号及说明
信号 | 说明 |
---|---|
timeChanged | 时间发生改变时发射 |
dateChanged | 日期发生改变时发射 |
dateTimeChanged | 日期或者时间发生改变时发射 |
在Qt Designer设计器的窗口中分别添加一个Date/TimeEdit控件、一个DateEdit控件和一个TimeEdit控件。
由于date()、time()和dateTime()方法的返回值分别是QDate类型、QTime类型和QDateTime类型,无法直接使用,因此如果想要获取日期时间控件中的具体日期和(或)时间值,可以使用text()方法获取。
self.dateTimeEdit.text()
示例:时间日期控件的使用
使用日期时间控件时,如果要改变日期时间,默认只能通过上下箭头来改变,如果想弹出日历控件,设置**setCalendarPoput(True)**即可。
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(352, 233)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.dateTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
self.dateTimeEdit.setGeometry(QtCore.QRect(40, 30, 194, 22))
self.dateTimeEdit.setObjectName("dateTimeEdit")
self.dateEdit = QtWidgets.QDateEdit(self.centralwidget)
self.dateEdit.setGeometry(QtCore.QRect(40, 70, 110, 22))
self.dateEdit.setObjectName("dateEdit")
self.timeEdit = QtWidgets.QTimeEdit(self.centralwidget)
self.timeEdit.setGeometry(QtCore.QRect(40, 110, 118, 22))
self.timeEdit.setObjectName("timeEdit")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 352, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
2. CalendarWidget:日历控件
CalendarWidget控件又称为日历控件,主要用来显示和选择日期。
CalendarWidget控件对应PyQt5中的QCalendarWidget类。
QcalendarWidget类的常用方法及说明
方法 | 说明 |
---|---|
setSelectDate() | 设置选中的日期,默认为当前日期 |
setMinimumDate() | 设置最小日期,默认为1752/9/14 |
setMaximumDate() | 设置最大日期,默认为9999/12/31 |
setFirstDayOfWeek() |
|
setGridVisible() | 设置是否显示网格线 |
setSelectionMode() |
|
setHorizontalHeaderFormat() |
|
setVerticalHeaderFormat() |
|
setNavigationBarVisible() | 设置是否显示导航栏 |
setDateEditEnabled() | 设置是否可以编辑日期 |
setDateEditAcceptDelay() | 设置编辑日期的最长间隔,默认为1500 |
selectedDate() | 获取选择的日期,返回值为Qdate类型 |
CalendarWidget控件最常用的信号是selectionChanged,该信号在选择的日期发生改变时发射。
示例:获取选中的日期
在Qt Designer设计器中创建一个窗口,在窗口中添加一个CalendarWidget控件,设计完成后保存为.ui文件,并使用PyUIC工具将其转换为.py代码文件。在.py代码文件中自定义一个getdate()方法,用来获取CalendarWidget控件中选中的日期,并转换为“年-月-日”形式,显示在弹出的提示框中。
def getdate(self):
from PyQt5.QtWidgets import QMessageBox
date = QtCore.QDate(self.calendarWidget.selectedDate()) # 获取当前选中日期的QDate对象
year = date.year() # 获取年份
month = date.month() # 获取月份
day = date.day() # 获取日
QMessageBox.information(MainWindow, "提示", str(year) + "-" + str(month) + "-" + str(day), QMessageBox.Ok)
对CalendarWidget控件进行设置,并为其selectionChanged信号绑定自定义的getdate()槽函数。
self.calendarWidget = QtWidgets.QCalendarWidget(self.centralwidget)
self.calendarWidget.setGeometry(QtCore.QRect(20, 10, 248, 197))
self.calendarWidget.setSelectedDate(QtCore.QDate(2020, 3, 23)) # 设置默认选中的日期
self.calendarWidget.setMinimumDate(QtCore.QDate(1752, 9, 14)) # 设置最小日期
self.calendarWidget.setMaxmumDate(QtCore.QDate(9999, 12, 31)) # 设置最大日期
self.calendarWidget.setFirstDayOfWeek(QtCore.Qt.Monday) # 设置每周第一天为星期一
self.calendarWidget.setGridVisible(True) # 设置网格线可见
# 设置可以选中单个日期
self.calendarWidget.setSelectionMode(QtWidgets.QCalendarWidget.SingleSelection)
# 设置水平表头为简短形式,即“周一”形式
self.calendarWidget.setHorizontalHeaderFormat(QtWidgets.QCalendarWidget.ShortDayNames)
# 设置垂直表头为周数
self.calendarWidget.setVerticalHeaderFormat(QtWidgets.QCalendarWidget.ISOWeekNumbers)
self.calendarWidget.setNavigationBarVisible(True) # 设置显示导航栏
self.calendarWidget.setDateEditEnabled(True) # 设置日期可以编辑
self.calendarWidget.setObjectName("calendarWidget")
# 选中日期变化时显示选择的日期
self.calendarWidget.selectionChanged.connect(self.getdate)
为.py文件添加__main__主方法,然后运行程序,日期控件在窗口中的显示效果如图9.70所示,单击某个日期时,可以弹出对话框进行显示。
运行结果如下:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(404, 325)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.calendarWidget = QtWidgets.QCalendarWidget(self.centralwidget)
self.calendarWidget.setGeometry(QtCore.QRect(50, 20, 296, 218))
self.calendarWidget.setObjectName("calendarWidget")
self.calendarWidget.setMaximumDate(QtCore.QDate(2020, 3, 23)) # 设置最小日期
self.calendarWidget.setMaximumDate(QtCore.QDate(9999, 12, 31)) # 设置最大日期
self.calendarWidget.setFirstDayOfWeek(QtCore.Qt.Monday) # 设置每周第一天为为星期一
self.calendarWidget.setGridVisible(True) # 设置网格线可见
# 设置可以选中单个日期
self.calendarWidget.setSelectionMode(QtWidgets.QCalendarWidget.SingleSelection)
# 设置水平表头为简短形式,即“周一”形式
self.calendarWidget.setHorizontalHeaderFormat(QtWidgets.QCalendarWidget.ShortDayNames)
# 设置垂直表头为周数
self.calendarWidget.setVerticalHeaderFormat(QtWidgets.QCalendarWidget.ISOWeekNumbers)
self.calendarWidget.setNavigationBarVisible(True) # 设置显示导航栏
self.calendarWidget.setDateEditEnabled(True) # 设置日期可以编辑
self.calendarWidget.setObjectName("calendarWidget")
# 选中日期变化时显示选择的日期
self.calendarWidget.selectionChanged.connect(self.getdate)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 404, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
datetime = QtCore.QDateTime.currentDateTime() # 获取当前系统日期时间
print("系统当前日期时间:", datetime)
date = QtCore.QDate.currentDate() # 获取当前日期
print("系统当前日期:", date)
time = QtCore.QTime.currentTime() # 获取当前时间
print("系统当前时间:", time)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
def getdate(self):
from PyQt5.QtWidgets import QMessageBox
date = QtCore.QDate(self.calendarWidget.selectedDate()) # 获取当前选中日期的QDate对象
year = date.year() # 获取年份
month = date.month() # 获取月份
day = date.day() # 获取日
QMessageBox.information(MainWindow, "提示", str(year) + "-" + str(month) + "-" + str(day), QMessageBox.Ok)
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
在PyQt5中,如果要获取当前系统的日期时间,可以借助QtCore模块下的QDateTime类、QDate类或者QTime类实现。其中,获取当前系统的日期时间可以使用QDateTime类的currentDateTime()方法,获取当前系统的日期可以使用QDate类的currentDate()方法,获取当前系统的时间可以使用QTime类的currentTime()方法。
datetime = QtCore.QDateTime.currentDateTime() # 获取当前系统日期时间
print("系统当前日期时间:", datetime)
date = QtCore.QDate.currentDate() # 获取当前日期
print("系统当前日期:", date)
time = QtCore.QTime.currentTime() # 获取当前时间
print("系统当前时间:", time)
(二)PyQt布局管理
前面设计的窗口程序都是绝对布局,即在Qt Designer窗口中,将控件放到窗口中的指定位置上,那么该控件的大小和位置就会固定在初始放置的位置。除了绝对布局,PyQt5还提供了一些常用的布局方式,如垂直布局、水平布局、网格布局、表单布局等。
1. 线性布局
线性布局是将放入其中的组件按照垂直或水平方向来布局,也就是控制放入其中的组件横向排列或纵向排列。
将纵向排列的称为垂直线性布局管理器,用VerticalLayout控件表示,其基类为QVBoxLayout。
垂直线性布局管理器:
将横向排列的称为水平线性布局管理器,用HorizontalLayout控件表示,其基类为QHBoxLayout。
水平线性布局管理器:
在垂直线性布局管理器中,每一行只能放一个组件;在水平线性布局管理器中,每一列只能放一个组件。
1. VerticalLayout:垂直布局
VerticalLayout控件表示垂直布局,其基类是QVBoxLayout,它的特点是:放入该布局管理器中的控件默认垂直排列。
示例:VerticalLayout控件的使用
在PyQt5的设计窗口中添加了一个VerticalLayout控件,并在其中添加4个PushButton控件。
# 垂直布局
vlayout = QVBoxLayout()
btn1 = QPushButton()
btn1.setText("按钮1")
btn2 = QPushButton()
btn2.setText("按钮2")
btn3 = QPushButton()
btn3.setText("按钮3")
btn4 = QPushButton()
btn4.setText("按钮4")
vlayout.addWidget(btn1)
vlayout.addWidget(btn2)
vlayout.addWidget(btn3)
vlayout.addWidget(btn4)
vlayout.addSpacing(10) # 设置两个控件之间的间距为10
self.setLayout(vlayout)
在向垂直布局管理器中添加控件时,用到了addWidget()方法,除此之外,垂直布局管理器中还有一个常用的方法——addSpacing(),用来设置控件的上下间距。
addSpacing(self, int) # 参数int表示要设置的间距值
运行效果对比:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(164, 274)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 0, 121, 241))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) # 定义垂直布局管理器
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.pushButton_2 = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.pushButton_2.setObjectName("pushButton_2")
self.verticalLayout.addWidget(self.pushButton_2) # 向垂直布局管理器添加按钮控件
# 设置控件上下间距
self.verticalLayout.addSpacing(20)
self.pushButton_3 = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.pushButton_3.setObjectName("pushButton_3")
self.verticalLayout.addWidget(self.pushButton_3)
self.pushButton_4 = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.pushButton_4.setObjectName("pushButton_4")
self.verticalLayout.addWidget(self.pushButton_4)
self.pushButton = QtWidgets.QPushButton(self.verticalLayoutWidget)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 164, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "垂直布局"))
self.pushButton_2.setText(_translate("MainWindow", "按钮1"))
self.pushButton_3.setText(_translate("MainWindow", "按钮2"))
self.pushButton_4.setText(_translate("MainWindow", "按钮3"))
self.pushButton.setText(_translate("MainWindow", "按钮4"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
在使用addWidget()方法向布局管理器中添加控件时,还可以指定控件的伸缩量和对其方式:
addWidget(self, QWidget, stretch, alignment)
# QWidget表示要添加的控件
# stretch表示控件的伸缩量,设置该伸缩量之后,控件会随着窗口的变化而变化
# alignment用来指定控件的对齐方式
控件对齐方式的取值及说明
值 | 说明 | 值 | 说明 |
---|---|---|---|
Qt.AlignLeft | 水平左对齐 | Qt.AlignTop | 垂直靠上对齐 |
Qt.AlignRight | 水平右对齐 | Qt.AlignBottom | 垂直靠下对齐 |
Qt.AlignCenter | 水平居中对齐 | Qt.AlignVCenter | 垂直居中对齐 |
Qt.AlignJustify | 水平两端对齐 |
例如,向垂直布局管理器中添加一个名称为btn1,伸缩量为1,对齐方式为垂直居中对齐的按钮:
vlayout.addWidget(btn1, 1, QtCore.Qt.AlignVCenter)
2. HorizontalLayout:水平布局
HorizontalLayout控件表示水平布局,其基类是QHBoxLayout,它的特点是:放入该布局管理器中的控件默认水平排列。
示例:HorizontalLayout控件的使用
PyQt5的设计窗口中添加了一个HorizontalLayout控件,并在其中添加了4个PushButton控件。
# 水平布局
hlayout = QHBoxLayout()
btn1 = QPushButton()
btn1.setText("按钮1")
btn1 = QPushButton()
btn1.setText("按钮2")
btn1 = QPushButton()
btn1.setText("按钮3")
btn1 = QPushButton()
btn1.setText("按钮4")
hlayout.addWidget(btn1)
hlayout.addWidget(btn2)
hlayout.addWidget(btn3)
hlayout.addWidget(btn4)
self.setLayout(hlayout)
水平布局管理器还有两个常用的方法:addSpacing()方法和addStretch()方法。
其中,addSpacing()方法用于设置控件的左右间距:
addSpacing(self, int) # 参数int表示要设置的间距值
例如,将第一个按钮和第二个按钮之间的间距设为20,:
hlayout.addSpacing(20) # 设置两个控件之间的间距
addStretch()方法用来增加一个可伸缩的控件,并且将伸缩量添加到布局末尾。
addStretch(self, stretch) # 参数stretch表示要均分的比例,默认值为0
例如,下面代码在水平布局管理器的第一个按钮之前增加一个水平伸缩量:
hlayout.addStretch(1)
运行效果对比:
在每个按钮之前添加一个伸缩量:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(457, 86)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 0, 441, 41))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
# # 在第一个按钮之前增加一个水平伸缩量
# self.horizontalLayout.addStretch(2)
# 在每一个按钮之前增加一个水平伸缩量
self.horizontalLayout.addStretch(2)
self.pushButton_2 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
# # 设置按钮1和按钮2之间的间距
# self.horizontalLayout.addSpacing(20)
# 在每一个按钮之前增加一个水平伸缩量
self.horizontalLayout.addStretch(2)
self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
# 在每一个按钮之前增加一个水平伸缩量
self.horizontalLayout.addStretch(2)
self.pushButton_4 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton_4.setObjectName("pushButton_4")
self.horizontalLayout.addWidget(self.pushButton_4)
# 在每一个按钮之前增加一个水平伸缩量
self.horizontalLayout.addStretch(2)
self.pushButton_3 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
self.pushButton_3.setObjectName("pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 457, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton_2.setText(_translate("MainWindow", "按钮1"))
self.pushButton.setText(_translate("MainWindow", "按钮2"))
self.pushButton_4.setText(_translate("MainWindow", "按钮3"))
self.pushButton_3.setText(_translate("MainWindow", "按钮4"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
2. GridLayout:网格布局
GridLayout被称为网格布局(多行多列),它将位于其中的控件放入一个网格中。GridLayout需要将提供给它的空间划分成行和列,并把每个控件插入正确的单元格中。
1. 网格布局的基本使用
网格控件的基类是QGridLayout。
网格控件的常用方法及说明
方法 | 说明 |
---|---|
addWidget(QWidget widget, int row, int column, QtAlignment alignment) |
|
addWidget(QWidget widget, int fromRow, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt.Alignment.alignment) |
|
setRowStretch() | 设置行比例 |
setColumnStretch() | 设置列比例 |
setSpacing() | 设置控件在水平和垂直方向上的间距 |
示例:使用网格布局登录窗口
创建一个.py文件,首先导入PyQt5窗口程序开发所需的模块,定义一个类,继承自QWidget,该类中定义一个initUI方法,用来使用GridLayout网格布局一个登录窗口;定义完成之后,在__init__方法中调用,对窗口进行初始化;最后在__main__方法中显示创建的登录窗口。
运行结果:
完整代码:
from PyQt5 import QtCore
from PyQt5.QtWidgets import *
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.initUi() # 初始化窗口
def initUi(self):
grid = QGridLayout() # 创建网格布局
# 创建并设置标签文本
label1 = QLabel()
label1.setText("用户名:")
# 创建输入文本框
text1 = QLineEdit()
# 创建并设置标签文本
label2 = QLabel()
label2.setText("密 码:")
# 创建输入文本框
text2 = QLineEdit()
# 创建“登录”和“取消”按钮
btn1 = QPushButton()
btn1.setText("登录")
btn2 = QPushButton()
btn2.setText("取消")
# 在第一行第一列添加标签控件,并设置左对齐
grid.addWidget(label1, 0, 0, QtCore.Qt.AlignLeft)
# 在第一行第二列添加输入文本框控件,并设置左对齐
grid.addWidget(text1, 0, 1, QtCore.Qt.AlignLeft)
# 在第二行第一列添加标签控件,并设置左对齐
grid.addWidget(label2, 1, 0, QtCore.Qt.AlignLeft)
# 在第二行第二列添加输入文本框控件,并设置左对齐
grid.addWidget(text2, 1, 1, QtCore.Qt.AlignLeft)
# 在第三行第一列添加按钮控件,并设置居中对齐
grid.addWidget(btn1, 2, 0, QtCore.Qt.AlignCenter)
# 在第三行第二列添加按钮控件,并设置居中对齐
grid.addWidget(btn2, 2, 1, QtCore.Qt.AlignCenter)
# 设置网格布局
self.setLayout(grid)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv) # 创建窗口程序
demo = Demo() # 创建窗口类对象
demo.show() # 显示窗口
sys.exit(app.exec_())
2. 跨越行和列的网格布局
使用网格布局时,除了普通的按行、列进行布局,还可以跨行、列进行布局,实现该功能,需要使用addWidget()方法的以下形式:
addWidget(QWidget widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt.Alignment alignment)
# widget:要添加的控件
# fromRow:添加控件的起始行数
# fromColumn:添加控件的起始列数
# rowSpan:控件跨越的行数
# columnSpan:控件跨越的列数
# alignment:控件的对齐方式
示例:跨行布局QQ登录窗口
创建一个.py文件,首先导入PyQt5窗口程序开发所需的模块,然后通过在网格布局中跨行和列布局一个QQ登录窗口。
完整代码如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.initUi() # 初始化窗口
def initUi(self):
self.setWindowTitle("QQ 登录窗口")
grid = QGridLayout() # 创建网格布局
# 创建顶部图片
label1 = QLabel()
label1.setPixmap(QtGui.QPixmap("image/top.png"))
# 创建并设置用户名标签文本
label2 = QLabel()
label2.setPixmap(QtGui.QPixmap("image/qq1.png"))
# 创建用户名输入文本框
text1 = QLineEdit()
# 创建并设置标签文本
label3 = QLabel()
label3.setPixmap(QtGui.QPixmap("image/qq2.png"))
# 创建输入文本框
text2 = QLineEdit()
# 创建“安全登录”按钮
btn1 = QPushButton()
btn1.setText("安全登录")
# 在第一行第一列到第三行第四列添加标签控件,并设置居中对齐
grid.addWidget(label1, 0, 0, 3, 4, QtCore.Qt.AlignCenter)
# 在第四行第二列添加标签控件,并设置右对齐
grid.addWidget(label2, 3, 1, QtCore.Qt.AlignRight)
# 在第四行第三列添加输入文本框控件,并设置左对齐
grid.addWidget(text1, 3, 2, QtCore.Qt.AlignLeft)
# 在第五行第二列添加标签控件,并设置右对齐
grid.addWidget(label3, 4, 1, QtCore.Qt.AlignRight)
# 在第五行第三列添加输入文本框控件,并设置左对齐
grid.addWidget(text2, 4, 2, QtCore.Qt.AlignLeft)
# 在第六行第二列到第三列添加按钮控件,并设置居中对齐
grid.addWidget(btn1, 5, 1, 1, 2, QtCore.Qt.AlignCenter)
self.setLayout(grid) # 设置网格布局
if __name__ == "__main__":
import sys
app = QApplication(sys.argv) # 创建窗口程序
demo = Demo() # 创建窗口类对象
demo.show() # 显示窗口
sys.exit(app.exec_())
运行结果如下:
当窗口中的控件布局比较复杂时,应该尽量使用网格布局,而不是使用水平和垂直布局的组合或者嵌套的形式,因为在多数情况下,后者往往会更加复杂而难以控制。网格布局使得窗口设计器能够以更大的自由度来排列组合控件,而仅仅带来了微小的复杂度开销。
3. FormatLayout:表单布局
FormLayout控件表示表单布局,它的基类是QFormLayout,该控件以表单方式进行布局。
表单是一种网页中常见的与用户交互的方式,其主要由两列组成,第一列用来显示信息,给用户提示,而第二列需要用户进行输入或者选择,下图所示的IT教育类网站——明日学院的登录窗口就是一种典型的表单布局。
表单布局最常用的方式是addRow()方法,该方法用来向表单布局中添加一行,在一行中可以添加两个控件,分别位于一行中的两列上。
addRow(self, __args)
# 参数__args表示要添加的控件,通常是两个控件对象。
示例:使用表单布局登录窗口
创建一个.py文件,使用表单布局实现前面网格布局登录窗口类似的功能,布局一个通用的登录窗口。
完整代码如下:
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import *
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.initUI() # 初始化窗口
def initUI(self):
form = QFormLayout() # 创建表单布局
# 创建并设置标签文本
label1 = QLabel()
label1.setText("用户名:")
# 创建输入文本框
text1 = QLineEdit()
# 创建并设置标签文本
label2 = QLabel()
label2.setText("密 码:")
# 创建输入文本框
text2 = QLineEdit()
# 创建“登录”和“取消”按钮
btn1 = QPushButton()
btn1.setText("登录")
btn2 = QPushButton()
btn2.setText("取消")
# 设置标签总在文本框的上方
form.setRowWrapPolicy(QtWidgets.QFormLayout.WrapAllRows)
# 将上面创建的6个控件分为3行添加到表单布局中
form.addRow(label1, text1)
form.addRow(label2, text2)
form.addRow(btn1, btn2)
# form.addRow(btn1)
# form.addRow(btn2)
self.setLayout(form) # 设置表单布局
if __name__ == "__main__":
import sys
app =QApplication(sys.argv) # 创建窗口程序
demo = Demo()
demo.show() # 显示窗口
sys.exit(app.exec_())
运行结果如下:
表单布局还提供了一个setRowWrapPolicy()方法,用来设置表单布局中的每一列的摆放方式:
setRowWrapPolicy(RowWrapPolicy policy)
setRowWrapPolicy(RowWrapPolicy policy)方法中参数policy的取值及说明
取值 | 说明 |
---|---|
QFormLayout.DontWrapRows | 文本框总是出现在标签的后面,其中标签被赋予足够的水平空间以适应表单中出现的最宽的标签,其余的空间被赋予文本框。 |
QFormLayout.DrapLongRows | 适用于小屏幕,当标签和文本在在屏幕的当前行显示不全时,文本框会显示在下一行,使得标签独占一行。 |
QFormLayout.WrapAllRows | 标签总是在文本框的上一行 |
如果在示例中加入如下代码:
# 设置标签总在文本框的上方
form.setRowWrapPolicy(QtWidgets.QFormLayout.WrapAllRows)
由于表单布局中的最后一行是两个按钮,但设置标签总在文本框上方后,默认第二列会作为一个文本框填充整个布局,所以就出现了“取消”按钮比“登录”按钮长的情况,想改变这种情况,可以在使用addRow()方法添加按钮时,一行只添加一个按钮控件。
# 原本的代码:
form.addRow(btn1, btn2)
# 改为如下的代码:
form.addRow(btn1)
form.addRow(btn2)
再次运行程序,效果如下:
当要设计的窗口是一种类似于两列和若干行组成的形式时,使用表单布局要比网格布局更方便。
4. 布局管理器的嵌套
在进行用户界面设计时,很多时候只通过一种布局管理器很难实现想要的界面效果,这时就需要将多种布局管理器混合使用,即布局管理器的嵌套。
1. 嵌套布局的基本使用
多种布局管理器之间可以互相嵌套。
实现布局管理器嵌套时需要记住的规则
- 在一个布局文件中,最多只能有一个顶层布局管理器。如果想要使用多个布局管理器,就需要使用一个根布局管理器将它们包括起来。
- 不能嵌套太深。如果嵌套太深,则会影响性能,主要会降低页面的加载速度。
示例:在登录界面中添加密码输入提示
在上一示例中使用表单布局制作了一个登录窗口,但表单布局的默认两列中只能添加一个控件,现在需要在“密码”文本框下方提示“密码只能输入8位”,这时单纯使用表单布局是无法实现的。我们可以在“密码”文本框的列中嵌套一个垂直布局管理器,在其中添加一个输入密码的文本框和一个用于提示的标签,这样就可以实现想要的功能。
完整代码如下:
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import *
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.initUI() # 初始化窗口
def initUI(self):
form = QFormLayout() # 创建表单布局
# 创建并设置标签文本
label1 = QLabel()
label1.setText("用户名:")
# 创建输入文本框
text1 = QLineEdit()
# 创建并设置标签文本
label2 = QLabel()
label2.setText("密 码:")
# 创建输入文本框
text2 = QLineEdit()
# 创建“登录”和“取消”按钮
btn1 = QPushButton()
btn1.setText("登录")
btn2 = QPushButton()
btn2.setText("取消")
# 将上面创建的6个控件分为3行添加到表单布局中
form.addRow(label1, text1)
vlayout = QVBoxLayout() # 创建垂直布局管理器
vlayout.addWidget(text2) # 向垂直布局中添加密码输入框
vlayout.addWidget(QLabel("密码只能输入8位")) # 向垂直布局中添加提示标签
form.addRow(label2, vlayout) # 将垂直布局嵌套进表单布局中
form.addRow(btn1, btn2)
self.setLayout(form) # 设置表单布局
if __name__ == "__main__":
import sys
app =QApplication(sys.argv) # 创建窗口程序
demo = Demo()
demo.show() # 显示窗口
sys.exit(app.exec_())
运行结果:
2. 通过嵌套布局设计一个微信聊天窗口
创建一个.py文件,通过在GirdLayout网格布局中嵌套垂直布局,设计一个微信聊天窗口,该窗口主要模拟两个人的对话,并且在窗口下方显示输入框及“发送”按钮。
完整代码如下:
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import *
class Demo(QWidget):
def __init__(self, parent=None):
super(Demo, self).__init__(parent)
self.initUi() # 初始化窗口
def initUi(self):
self.setWindowTitle("微信交流")
grid = QGridLayout() # 创建网格布局
# 创建顶部时间栏
label1 = QLabel()
# 显示当前日期时间
label1.setText(QtCore.QDateTime.currentDateTime().toString("yyyy-MM-dd HH:mm:ss"))
# 在第一行第一列到第一行第四列添加标签控件,并设置居中对齐
grid.addWidget(label1, 0, 0, 1, 4, QtCore.Qt.AlignCenter)
# 创建对方用户头像,昵称及信息,并在网格中嵌套垂直布局显示
label2 = QLabel()
label2.setPixmap(QtGui.QPixmap("image/head1.png"))
vlayout1 = QVBoxLayout()
vlayout1.addWidget(QLabel("老妈"))
vlayout1.addWidget(QLabel("儿子,在不在,最近还好吗?"))
grid.addWidget(label2, 1, 0, QtCore.Qt.AlignRight)
grid.addLayout(vlayout1, 1, 1)
# 创建自己的头像、昵称及信息,并在网格中嵌套垂直布局显示
label3 = QLabel()
label3.setPixmap(QtGui.QPixmap("image/head2.png"))
vlayout2 = QVBoxLayout()
vlayout2.addWidget(QLabel("儿子"))
vlayout2.addWidget(QLabel("很好呀,妈,你就别担心啦"))
grid.addWidget(label3, 2, 3, QtCore.Qt.AlignLeft)
grid.addLayout(vlayout2, 2, 2)
# 创建对方用户头像、昵称及第2条信息,并在网络中嵌套垂直布局显示
label4 = QLabel()
label4.setPixmap(QtGui.QPixmap("image/head1.png"))
label4.resize(24, 24)
vlayout3 = QVBoxLayout()
vlayout3.addWidget(QLabel("老妈"))
vlayout3.addWidget(QLabel("好吧,你照顾好自己啊"))
grid.addWidget(label4, 3, 0, QtCore.Qt.AlignRight)
grid.addLayout(vlayout3, 3, 1)
# 创建输入框,并设置宽度和高度,跨列添加到网格布局中
text = QTextEdit()
text.setFixedWidth(500)
text.setFixedHeight(80)
# 在第一行第一列到第一行第四列添加标签控件,并设置居中对齐
grid.addWidget(text, 4, 0, 1, 4, QtCore.Qt.AlignCenter)
# 添加“发送”按钮
grid.addWidget(QPushButton("发送"), 5, 3, QtCore.Qt.AlignRight)
self.setLayout(grid) # 设置网格布局
if __name__ == "__main__":
import sys
app = QApplication(sys.argv) # 创建窗口程序
demo = Demo() # 创建窗口类对象
demo.show() # 显示窗口
sys.exit(app.exec_())
运行结果:
5. MDIArea:MDI窗口设计
1. 认识MDI窗口
MDI窗口(Multiple-Document Interface)又称作多文档界面,它主要用于同时显示多个文档,每个文档显示在各自的窗口中。MDI窗口中通常有包含子菜单的窗口菜单,用于在窗口或文档之间进行切换,MDI窗口十分常见。
典型的MDI窗口示例:
MDI窗口的应用非常广泛,例如,如果某公司的库存系统需要实现自动化,则需要使用窗口来输入客户和货物的数据、发出订单以及跟踪订单。这些窗口必须链接或者从属于一个界面,并且必须能够同时处理多个文件。这样,就需要建立MDI窗口以解决这些需求。
2. 子窗口基础类
在PyQt5中使用MDIArea控件来设计MDI窗口,其基类是QMdiArea,而子窗口是一个QMdiSubWindow类的实例,我们可以将任何QWidget设置为子窗口的内部控件,子窗口默认在MDI区域是级联显示的。
QMdiArea类的常用方法及说明
方法 | 说明 |
---|---|
addSubWindow() | 添加子窗口 |
removeSubWindow() | 删除子窗口 |
setActiveSubWindow() | 激活子窗口 |
closeActiveSubWindow() | 关闭正在活动状态的子窗口 |
subWindowList() | 获取MDI区域的子窗口列表 |
cascadeSubWindows() | 级联排列显示子窗口 |
tileSubWindows() | 平铺排列显示子窗口 |
QMdiSubWindow类常用的方法为setWidget(),该方法用来向子窗口中添加PyQt5控件。
3. MDI子窗口的动态添加及排列
本节使用QMdiArea类和QMdiSubWindow类的相应方法设计一个可以动态添加子窗口,并能够对子窗口进行排列显示的实例。
示例:子窗口的动态添加及排列
在Qt Designer设计器中创建一个MainWindow窗口,删除默认的状态栏,然后添加一个MDIArea控件,适当调整大小,设计完成后,保存为.ui文件,并使用PyUIC工具将其转换为.py代码文件。在.py文件中自定义一个action()槽函数,用来根据单击的菜单项,执行相应的新建子窗口、平铺显示子窗口和级联显示子窗口操作;然后将自定义的action()槽函数与菜单的triggered信号相关联。最后为.py文件添加__main__主方法。
完整代码如下:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(481, 274) # 设置窗口大小
MainWindow.setWindowTitle("MDI窗口") # 设置窗口标题
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# 创建MDI窗口区域
self.mdiArea = QtWidgets.QMdiArea(self.centralwidget)
self.mdiArea.setGeometry(QtCore.QRect(0, 0, 481, 251))
self.mdiArea.setObjectName("mdiArea")
MainWindow.setCentralWidget(self.centralwidget)
# 创建菜单栏
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 481, 23))
self.menubar.setObjectName("menubar")
# 设置主菜单
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
self.menu.setTitle("子窗体操作")
MainWindow.setMenuBar(self.menubar)
# 设置新建菜单项
self.actionxinjian = QtWidgets.QAction(MainWindow)
self.actionxinjian.setObjectName("actionxinjian")
self.actionxinjian.setText("新建")
# 设置平铺菜单项
self.actionpingpu = QtWidgets.QAction(MainWindow)
self.actionpingpu.setObjectName("actionpingpu")
self.actionpingpu.setText("平铺显示")
# 设置级联菜单项
self.actionjilian = QtWidgets.QAction(MainWindow)
self.actionjilian.setObjectName("actionjilian")
self.actionjilian.setText("级联显示")
# 将新建的3个菜单项添加到主菜单中
self.menu.addAction(self.actionxinjian)
self.menu.addAction(self.actionpingpu)
self.menu.addAction(self.actionjilian)
# 将设置完成的主菜单添加到菜单栏中
self.menubar.addAction(self.menu.menuAction())
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# 为菜单项关联信号
self.menubar.triggered[QAction].connect(self.action)
count = 0 # 定义变量,用来表示新建的子窗口个数
# 自定义槽函数,根据选择的菜单执行相应操作
def action(self, m):
if m.text() == "新建":
sub = QMdiSubWindow() # 创建子窗口对象
self.count = self.count + 1 # 记录子窗口个数
# 设置子窗口标题
sub.setWindowTitle("子窗口" + str(self.count))
# 在子窗口中添加一个标签,并设置文本
sub.setWidget(QLabel("这是第 %d 个子窗口" % self.count))
self.mdiArea.addSubWindow(sub) # 将新建的子窗口添加到MDI区域
sub.show() # 显示子窗口
elif m.text() == "平铺显示":
self.mdiArea.tileSubWindows() # 对子窗口平铺排列
elif m.text() == "级联显示":
self.mdiArea.cascadeSubWindows() # 对子窗口级联排列
# 主方法
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
MainWindow = QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt5设计的窗体对象
ui.setupUi(MainWindow) # 调用PyQt5窗体的方法对窗体对象进行初始化设置
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
运行结果:
(三)菜单、工具栏和状态栏
菜单是窗口应用程序的主要用户界面要素,工具栏为应用程序提供了操作系统的界面,状态栏显示系统的一些状态信息,在PyQt5中,菜单、工具栏和状态栏都不以标准控件的形式体现,用QMenu、QToolBar和QStatusBar类表示菜单、工具栏和状态栏。菜单、工具栏和状态栏是一个项目中最常用到的3大部分。那么,如何使用菜单、工具栏和状态栏呢?
1. 菜单
在PyQt5中,菜单栏使用QMenuBar类表示,它分为两部分:主菜单和菜单项,其中,主菜单被显示为一个QMenu类,而菜单项则使用QAciton类表示。一个QMenu中可以包含任意多个QAction对象,也可以包含另外的QMenu,用来表示级联菜单。
1. 菜单基础类
在PyQt5窗口中创建菜单时,需要QMenuBar类、QMenu类和QAction类,创建一个菜单,基本上就是使用这3个类完成下图的3个步骤。
1. QMenuBar类
QMenuBar类是所有窗口的菜单栏,用户需要在此基础上添加不同的QMenu和QAction,创建菜单栏有两种方法,分别是QMenuBar类的构造方法或者MainWindow对象的menuBar()方法。
self.menuBar = QtWidgets.QMenuBar(MainWindow)
或
self.menuBar = MainWindow.menuBar()
创建完菜单栏之后,就可以使用QMenuBar类的相关方法进行菜单的设置。
QMenuBar类的常用方法及说明
方法 | 说明 |
---|---|
addAction() | 添加菜单项 |
addActions() | 添加多个菜单项 |
addMenu() | 添加菜单 |
addSeparator() | 添加分割线 |
2. QMenu类
QMenu类表示菜单栏中的菜单,可以显示文本和图标,但是并不负责执行操作,类似Label的作用。
QMenu类的常用方法及说明
方法 | 说明 |
---|---|
addAction() | 添加菜单项 |
addMenu() | 添加菜单 |
addSeparator() | 添加分割线 |
setTitle() | 设置菜单的文本 |
title() | 获取菜单的标题文本 |
3. QAction类
PyQt5将用户与界面进行交互的元素抽象为一种“动作”,使用QAction类表示。QAction才是真正负责执行操作的部件。
QAction类的常用方法及说明
方法 | 说明 |
---|---|
setIcon() | 设置菜单项图标 |
setIconVisibleInMenu() | 设置图标是否显示 |
setText() | 添加菜单项文本 |
setIconText() | 设置图标文本 |
setShortcut() | 设置快捷键 |
setToolTip() | 设置提示文本 |
setEnabled() | 设置菜单项是否可用 |
text() | 获取菜单项的文本 |
QAction类有一个常用的信号triggered,用来在单击菜单项时发射。
使用PyQt5中的菜单时,只有QAction菜单项可以执行操作,QMenuBar菜单栏和QMenu菜单都是不会执行任何操作的,这点一定要注意,这与其他语言的窗口编程有所不同。
2. 添加和删除菜单
在PyQt5中,使用Qt Designer设计器创建一个MainWindow窗口时,窗口中默认有一个菜单栏和一个状态栏。
由于一个窗口中只能有一个菜单栏,所以在默认的MainWindow窗口中单击右键,是无法添加菜单的。这时首先需要删除原有的菜单,删除菜单非常简单,在菜单上单击右键,选择“Remove Menu Bar”即可。
MainWindow窗口中的默认菜单栏和状态栏:
MainWindow窗口的默认右键菜单:
删除菜单:
添加菜单:
3. 设置菜单项
设置菜单项,即为菜单添加相应的菜单项,在默认的菜单上双击,即可将菜单项变成一个输入框。
输入完成后,按Enter键,即可在添加的菜单右侧和下方自动生成新的提示,根据自己的需求继续重复这个步骤添加菜单和菜单栏。
4. 为菜单设置快捷键
为菜单设置快捷键有两种方法,一种是在输入菜单文本时设置,一种使用setShortcut()方法设置。
1. 在输入菜单文本时设置快捷键
输入菜单文本时设置快捷键,只需要在文本中输入**“&+字母”**的形式即可。
例如,为“新建”菜单设置快捷键,则直接输入文本“(&N)”,这时就可以使用Alt+N快捷键来调用该菜单。
2. 使用setShorcut()方法设置快捷键
使用setShortcut()方法设置快捷键时,只需要输入相应的快捷组合键即可。
self.actionxinjian.setShortcut("Ctrl+N")
效果如下:
5. 为菜单设置图标
为菜单设置图标需要使用setIcon()方法,该方法要求有一个QIcon对象作为参数。
例如,下面的代码是为“新建”菜单设置图标:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("./image/nex.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionxinjian.setIcon(icon)
完整代码
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(828, 549)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 828, 26))
self.menuBar.setObjectName("menuBar")
self.menu = QtWidgets.QMenu(self.menuBar)
self.menu.setObjectName("menu")
self.menu_2 = QtWidgets.QMenu(self.menuBar)
self.menu_2.setObjectName("menu_2")
self.menu_3 = QtWidgets.QMenu(self.menuBar)
self.menu_3.setObjectName("menu_3")
MainWindow.setMenuBar(self.menuBar)
# 新建
self.action_N = QtWidgets.QAction(MainWindow)
self.action_N.setObjectName("action_N")
self.action_N.setShortcut("Ctrl+N")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("./image/xinjian.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.action_N.setIcon(icon1)
# 打开
self.actionshanchu = QtWidgets.QAction(MainWindow)
self.actionshanchu.setObjectName("actionshanchu")
self.actionshanchu.setShortcut("Ctrl+O")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap("./image/dakai.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionshanchu.setIcon(icon2)
# 关闭
self.action = QtWidgets.QAction(MainWindow)
self.action.setObjectName("action")
self.action.setShortcut("Ctrl+E")
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap("./image/guanbi.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.action.setIcon(icon3)
self.menu.addAction(self.action_N)
self.menu.addAction(self.actionshanchu)
self.menu.addAction(self.action)
self.menuBar.addAction(self.menu.menuAction())
self.menuBar.addAction(self.menu_2.menuAction())
self.menuBar.addAction(self.menu_3.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menu.setTitle(_translate("MainWindow", "文件"))
self.menu_2.setTitle(_translate("MainWindow", "选项"))
self.menu_3.setTitle(_translate("MainWindow", "编辑"))
self.action_N.setText(_translate("MainWindow", "新建(&N)"))
self.actionshanchu.setText(_translate("MainWindow", "打开(&O)"))
self.action.setText(_translate("MainWindow", "关闭(&E)"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
6. 菜单的功能实现
在单击菜单项时,可以触发其triggered信号,通过为该信号关联槽函数,可以实现相应的菜单项功能。
示例:点击菜单项弹出信息提示框
在前面设计的菜单栏基础上,为菜单项添加相应的事件,单击菜单项时,弹出信息提示框,提示选择了哪个菜单。
完整代码如下:
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(344, 115)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
# self.menuBar = MainWindow.menuBar()
# 添加菜单栏
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 344, 23))
self.menuBar.setObjectName("menuBar")
# 添加“文件”菜单
self.menu = QtWidgets.QMenu(self.menuBar)
self.menu.setObjectName("menu")
self.menu.setTitle("文件")
# 添加“编辑”菜单
self.menu_2 = QtWidgets.QMenu(self.menuBar)
self.menu_2.setObjectName("menu_2")
self.menu_2.setTitle("编辑")
MainWindow.setMenuBar(self.menuBar)
# 添加“新建”菜单
self.actionxinjian = QtWidgets.QAction(MainWindow)
self.actionxinjian.setEnabled(True) # 设置菜单可用
# 为菜单设置图标
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("./image/xinjian.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionxinjian.setIcon(icon)
# 设置菜单为Windows快捷键
self.actionxinjian.setShortcut(QtCore.Qt.WindowShortcut)
self.actionxinjian.setIconVisibleInMenu(True) # 设置图标可见
self.actionxinjian.setObjectName("actionxinjian")
self.actionxinjian.setText("新建(&N)") # 设置菜单文本
self.actionxinjian.setIconText("新建") # 设置图标文本
self.actionxinjian.setToolTip("新建") # 设置提示文本
self.actionxinjian.setShortcut("Ctrl+N") # 设置快捷键
# 添加“打开”菜单
self.actiondakai = QtWidgets.QAction(MainWindow)
# 为菜单设置图标
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("./image/dakai.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actiondakai.setIcon(icon1)
self.actiondakai.setObjectName("actiondakai")
self.actiondakai.setText("打开(&O)") # 设置菜单文本
self.actiondakai.setIconText("打开") # 设置图标文本
self.actiondakai.setToolTip("打开") # 设置提示文本
self.actiondakai.setShortcut("Ctrl+O") # 设置快捷键
# 添加“关闭”菜单
self.actionclose = QtWidgets.QAction(MainWindow)
# 为菜单设置图标
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap("image/guanbi.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionclose.setIcon(icon2)
self.actionclose.setObjectName("actionclose")
self.actionclose.setText("关闭(&C)") # 设置菜单文本
self.actionclose.setIconText("关闭") # 设置图标文本
self.actionclose.setToolTip("关闭") # 设置提示文本
self.actionclose.setShortcut("Ctrl+C") # 设置快捷键
self.menu.addAction(self.actionxinjian) # 在“文件”菜单中添加“新建”菜单项
self.menu.addAction(self.actiondakai) # 在“文件”菜单中添加“打开”菜单项
self.menu.addSeparator() # 添加分割线
self.menu.addAction(self.actionclose) # 在“文件”菜单中添加“关闭”菜单项
# 将“文件”菜单的菜单项添加到菜单栏中
self.menuBar.addAction(self.menu.menuAction())
# 将“编辑”菜单的菜单项添加到菜单栏中
self.menuBar.addAction(self.menu_2.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# 为菜单中的QAction绑定triggered信号
self.menu.triggered[QtWidgets.QAction].connect(self.getmenu)
def getmenu(self, m):
from PyQt5.QtWidgets import QMessageBox
# 使用information()方法弹出信息提示框
QMessageBox.information(MainWindow, "提示", "您选择的是"+m.text(), QMessageBox.Ok)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
运行结果:
以上代码为菜单项绑定triggered信号时,通过QMenu菜单进行了绑定:
self.menu.triggered[QtWidgets.QAction].connnect(self.getmenu)
实际上,如果每个菜单项实现的功能不同,还可以单独为每个菜单项绑定triggered信号。
# 单独为“新建”菜单绑定triggered信号
self.actionxinjian.triggered.connect(self.getmenu)
def getmenu(self):
from PyQt5.QtWidgets import QMessageBox
# 使用information()方法弹出信息提示框
QMessageBox.information(MainWindow, "提示", "您选择的是"+self.actionxinjian.text(), QMessageBox.Ok)
2. 工具栏
工具栏主要为窗口应用程序提供一些常用的快捷按钮、操作等。在PyQt5中,用QToolBar类表示工具栏。
1. 工具栏类:QToolBar
QToolBar类表示工具栏,它是一个由文本按钮、图标或者其他小控件组成的可移动面板,通常位于菜单栏下方。
QToolBar类的常用方法及说明
方法 | 说明 |
---|---|
addAction() | 添加具有多文本或图标的工具按钮 |
addActions() | 一次添加多个工具按钮 |
addWidget | 添加工具栏中按钮以外的控件 |
addSeparator() | 添加分割线 |
setIconSize() | 设置工具栏中图标的大小 |
setMovable() | 设置工具栏是否可以移动 |
setOrientation() |
|
setToolButtonStyle() |
|
单击工具栏中的按钮时,会发射actionTriggered信号,通过为该信号关联相应的槽函数,即可实现工具栏的相应功能。
2. 添加工具栏
在PyQt5的Qt Designer设计器中创建一个Main Window窗口,一个窗口中可以有多个工具栏,添加工具栏非常简单,单击右键,在弹出的快捷菜单中选择“Add Tool Bar”即可。
对应的添加工具栏的代码:
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
除了使用QToolBar类的构造函数创建工具栏之外,还可以直接使用MainWindow对象的addToolBar()方法进行添加,例如,上面的代码可以替换如下:
MainWindow.addToolBar("toolBar")
3. 为工具栏添加图标按钮
为工具栏添加图标按钮,需要用到addAction()方法,需要在该方法中传入一个QIcon对象,用来指定按钮的图标和文本;另外,工具栏中的按钮默认只显示图标,可以通过setToolButtonStyle()方法设置为既显示图标又显示文本。
例如,下面代码为在工具栏中添加一个“新建”按钮,并且同时显示图标和文本,图标和文本的组合方式为图标显示在文本上方。
# 设置工具栏中按钮的显示方式为:文字显示在图标的下方
self.tooBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.toolBar.addAction(QtGui.QIcon("image/xinjian.png")) # 为工具栏添加QAction
效果下图所示:
完整代码:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(828, 549)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 828, 26))
self.menuBar.setObjectName("menuBar")
self.menu = QtWidgets.QMenu(self.menuBar)
self.menu.setObjectName("menu")
self.menu_2 = QtWidgets.QMenu(self.menuBar)
self.menu_2.setObjectName("menu_2")
self.menu_3 = QtWidgets.QMenu(self.menuBar)
self.menu_3.setObjectName("menu_3")
MainWindow.setMenuBar(self.menuBar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.action_N = QtWidgets.QAction(MainWindow)
self.action_N.setObjectName("action_N")
self.actionshanchu = QtWidgets.QAction(MainWindow)
self.actionshanchu.setObjectName("actionshanchu")
self.action = QtWidgets.QAction(MainWindow)
self.action.setObjectName("action")
self.menu.addAction(self.action_N)
self.menu.addAction(self.actionshanchu)
self.menu.addAction(self.action)
self.menuBar.addAction(self.menu.menuAction())
self.menuBar.addAction(self.menu_2.menuAction())
self.menuBar.addAction(self.menu_3.menuAction())
self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.toolBar.addAction(QtGui.QIcon("image/xinjian.png"), "新建") # 为工具栏添加QAction
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menu.setTitle(_translate("MainWindow", "文件"))
self.menu_2.setTitle(_translate("MainWindow", "选项"))
self.menu_3.setTitle(_translate("MainWindow", "编辑"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.action_N.setText(_translate("MainWindow", "新建(&N)"))
self.actionshanchu.setText(_translate("MainWindow", "删除"))
self.action.setText(_translate("MainWindow", "设置"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
4. 一次为工具栏添加多个按钮图标
一次为工具栏添加多个图标按钮需要用到addActions()方法,需要在该方法中传入一个Iterable迭代器对象,对象中的元素必须是QAction对象。
例如,下面使用addActions()方法同时为工具栏添加“打开”和“关闭”两个图标按钮:
# 创建“打开”按钮对象
self.open = QtWidgets.QAction(QtGui.QIcon("image/dakai.png"), "打开")
# 创建“关闭”按钮对象
self.close = QtWidgets.QAction(QtGui.QIcon("image/guanbi.png", "关闭"))
# 将创建的两个QAction添加到工具栏中
self.toolBar.addActions([self.open, self.close])
效果如下:
5. 向工具栏中添加其他控件
除了使用QAction对象向工具栏中添加图标按钮之外,PyQt5还支持向工具栏中添加标准控件,如常用的Label、LineEdit、ComboBox、CheckBox等,这需要用到QToolBar对象的addWidget()方法。
例如,下面的代码是向工具栏中添加一个ComboBox下拉列表:
# 创建一个ComboBox下拉列表控件
self.combobox=QtWidgets.QComboBox()
# 定义职位列表
list = ["总经理", "副总经理", "人事部经理", "财务部经理", "部门经理", "普通员工"]
self.combobox.addItems(list) # 将职位列表添加到ComboBox下拉列表中
self.toolBar.addWidget(self.combobox) # 将下拉列表添加到工具栏中
运行结果:
6. 设置工具栏按钮的大小
工具栏中的图标按钮默认大小是24×24,但在使用时,根据实际的需要,对工具栏按钮大小的要求也会有所不同,这时可以使用setIconSize()方法改变工具栏按钮的大小。
例如,下面代码将工具栏中的图标按钮大小修改为16×16:
self.toolBar.setIconSize(QtCore.QSize(16, 16))
效果对比:
完整代码如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(828, 549)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 828, 26))
self.menuBar.setObjectName("menuBar")
self.menu = QtWidgets.QMenu(self.menuBar)
self.menu.setObjectName("menu")
self.menu_2 = QtWidgets.QMenu(self.menuBar)
self.menu_2.setObjectName("menu_2")
self.menu_3 = QtWidgets.QMenu(self.menuBar)
self.menu_3.setObjectName("menu_3")
MainWindow.setMenuBar(self.menuBar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.action_N = QtWidgets.QAction(MainWindow)
self.action_N.setObjectName("action_N")
self.actionshanchu = QtWidgets.QAction(MainWindow)
self.actionshanchu.setObjectName("actionshanchu")
self.action = QtWidgets.QAction(MainWindow)
self.action.setObjectName("action")
self.menu.addAction(self.action_N)
self.menu.addAction(self.actionshanchu)
self.menu.addAction(self.action)
self.menuBar.addAction(self.menu.menuAction())
self.menuBar.addAction(self.menu_2.menuAction())
self.menuBar.addAction(self.menu_3.menuAction())
# 设置工具栏中按钮的显示方式为:文字显示在图标的下方
self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
self.toolBar.addAction(QtGui.QIcon("image/xinjian.png"), "新建") # 为工具栏添加QAction
# 创建“打开”按钮对象
self.open = QtWidgets.QAction(QtGui.QIcon("image/dakai.png"), "打开")
# 创建“关闭”按钮对象
self.close = QtWidgets.QAction(QtGui.QIcon("image/guanbi.png"), "关闭")
# 将创建的两个QAction添加到工具栏中
self.toolBar.addActions([self.open, self.close])
# 创建一个ComboBox下拉列表控件
self.combobox = QtWidgets.QComboBox()
# 定义职位列表
list = ["总经理", "副总经理", "人事部经理", "部门经理", "普通员工"]
self.combobox.addItems(list)
self.toolBar.addWidget(self.combobox)
self.toolBar.setIconSize(QtCore.QSize(16, 16)) # 设置工具栏图标按钮的大小
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menu.setTitle(_translate("MainWindow", "文件"))
self.menu_2.setTitle(_translate("MainWindow", "选项"))
self.menu_3.setTitle(_translate("MainWindow", "编辑"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.action_N.setText(_translate("MainWindow", "新建(&N)"))
self.actionshanchu.setText(_translate("MainWindow", "删除"))
self.action.setText(_translate("MainWindow", "设置"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
7. 工具栏的单击功能实现
在单击工具栏中的按钮时,可以触发其actionTriggered信号,通过为该信号关联相应槽函数,可以实现工具栏的相应功能。
示例:获取单击的工具栏按钮
在前面设计的工具栏基础上,为工具栏按钮添加相应的事件,提示用户单击了哪个工具栏按钮。完整代码如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(309, 137)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
self.toolBar.setMovable(True) # 设置工具栏可移动
self.toolBar.setOrientation(QtCore.Qt.Horizontal) # 设置工具栏为水平工具栏
# 设置工具栏中按钮的显示方式为:文字显示在图标的下方
self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
# 为工具栏添加QAction
self.toolBar.addAction(QtGui.QIcon("image/xinjian.png"), "新建")
# 创建“打开”按钮对象
self.open = QtWidgets.QAction(QtGui.QIcon("image/dakai.png"), "打开")
# 创建“关闭”按钮对象
self.close = QtWidgets.QAction(QtGui.QIcon("image/guanbi.png"), "关闭")
# 将创建的两个QAction添加到工具栏中
self.toolBar.addActions([self.open, self.close])
# 设置工具栏图标按钮的大小
self.toolBar.setIconSize(QtCore.QSize(16, 16))
# 创建一个ComboBox下拉列表控件
self.combobox = QtWidgets.QComboBox()
# 定义职位列表
list = ["总经理", "副总经理", "人事部经理", "财务部经理", "部门经理", "普通员工"]
# 将职位列表添加到ComboBox下拉列表中
self.combobox.addItems(list)
# 将下拉列表添加到工具栏中
self.toolBar.addWidget(self.combobox)
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
# 将ComboBox控件的选项更改信号与自定义槽函数关联
self.combobox.currentIndexChanged.connect(self.showinfo)
# 为菜单中的QAction绑定triggered信号
self.toolBar.actionTriggered[QtWidgets.QAction].connect(self.getvalue)
def getvalue(self, m):
# 使用information()方法弹出信息提示框
QMessageBox.information(MainWindow, "提示", "您单击了 " + m.text(), QMessageBox.Ok)
def showinfo(self):
# 显示选择的职位
QMessageBox.information(MainWindow, "提示", "您选择的职位是:" + self.combobox.currentText(), QMessageBox.Ok)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
运行程序,单击工具栏中的某个图标按钮,提示您单击了哪个按钮:
当用户选择工具栏中下拉列表中的项时,提示选择了哪一项:
单击工具栏中的QAction对象默认会发射actionTriggered信号,但是,如果为工具栏添加了其他控件,并不会发射actionTriggered信号,而是会发射它们自己特有的信号。例如,在上面工具栏中添加的ComboBox下拉列表,在选择下拉列表中的项时,会发射其本身的currentIndexChanged信号。
3. 状态栏
状态栏通常放在窗口的最底部,用于显示窗口上的一些对象的相关信息或者程序信息,例如,显示当前登录用户、实时显示登录时间、显示任务执行进度等,在PyQt5中用QStatusBar类表示状态栏。
1. 状态栏类:QStatusBar
QStatusBar类表示状态栏,它是一个放置在窗口底部的水平条。
QStatusBar类的常用方法及说明
方法 | 说明 |
---|---|
addWidget() | 向状态栏中添加控件 |
addPermanentWidget() | 添加永久性控件,不会被临时消息掩盖,位于状态栏最右端 |
removeWidget() | 移除状态栏中的控件 |
showMessage() | 在状态栏中显示一条临时信息 |
clearMessage() | 删除正在显示的临时信息 |
QStatusBar类有一个常用的信号triggered,用来在单击菜单项时发射。
2. 添加状态栏
在PyQt5中,使用Qt Designer设计器创建一个MainWindow窗口时,窗口中默认有一个菜单栏和一个状态栏,由于一个窗口中只能有一个状态栏,所以首先需要删除原有的状态栏,删除状态栏非常简单,在窗口中单击右键,选择“Remove Status Bar”即可。
添加状态栏也非常简单,在一个空窗口上单击右键,在弹出的快捷菜单中选择“创建状态栏”即可:
对应的Python代码:
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
3. 向状态栏中添加控件
PyQt5支持向状态栏中添加标准控件,如常用的Label、ComboBox、CheckBox、ProgressBar等,这需要用到QStatusBar对象的addWidget()方法。
例如,向状态栏中添加一个Label控件,用来显示版权信息:
self.label=QtWidgets.QLabel() # 创建一个Label控件
self.label.setText("版权所有:某某科技有限公司") # 设置Label的文本
self.statusbar.addWidget(self.label) # 将label控件添加到状态栏中
4. 在状态栏中显示和删除临时信息
在状态栏中显示临时信息,需要使用QStatusBar对象的showMessage()方法,该方法中有两个参数,第一个参数为要显示的临时信息内容,第二个参数为要显示的时间,以毫秒为单位,但如果设置该参数为0,则表示一直显示。
例如,下面的代码为在状态栏中显示当前登录用户的信息:
self.statusbar.showMessage("当前登录用户:mr", 0) # 在状态栏中显示临时信息
运行效果:
注意,默认情况下,状态栏中的临时信息和添加的控件不能同时显示,否则会发生覆盖重合的情况。例如,将上面讲解的在状态栏中添加Label控件和显示临时信息的代码全部保留,即代码如下:
self.label = QtWidgets.QLabel() # 创建一个Label控件
self.label.setText("版权所有:某某科技有限公司") # 设置Label的文本
self.statusbar.addWidget(self.label) # 将Label控件添加到状态栏中
self.statusbar.showMessage("当前登录用户:mr", 0) # 在状态栏中显示临时信息
运行时,会出现如下的效果:
Label控件的文本和临时信息产生了重合。要解决该问题,可以用addPermanentWidget()方法向状态栏中添加控件。
self.statusbar.addPermanentWidget(self.label) # 将Label控件添加到状态栏中
效果如下:
删除临时信息使用QStatusBar对象的clearMessage()方法。
self.statusbar.clearMessage() # 清除状态栏的临时信息
完整代码如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(309, 137)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
self.toolBar.setMovable(True) # 设置工具栏可移动
self.toolBar.setOrientation(QtCore.Qt.Horizontal) # 设置工具栏为水平工具栏
# 设置工具栏中按钮的显示方式为:文字显示在图标的下方
self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
# 为工具栏添加QAction
self.toolBar.addAction(QtGui.QIcon("image/xinjian.png"), "新建")
# 创建“打开”按钮对象
self.open = QtWidgets.QAction(QtGui.QIcon("image/dakai.png"), "打开")
# 创建“关闭”按钮对象
self.close = QtWidgets.QAction(QtGui.QIcon("image/guanbi.png"), "关闭")
# 将创建的两个QAction添加到工具栏中
self.toolBar.addActions([self.open, self.close])
# 设置工具栏图标按钮的大小
self.toolBar.setIconSize(QtCore.QSize(16, 16))
# 创建一个ComboBox下拉列表控件
self.combobox = QtWidgets.QComboBox()
# 定义职位列表
list = ["总经理", "副总经理", "人事部经理", "财务部经理", "部门经理", "普通员工"]
# 将职位列表添加到ComboBox下拉列表中
self.combobox.addItems(list)
# 将下拉列表添加到工具栏中
self.toolBar.addWidget(self.combobox)
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
# 将ComboBox控件的选项更改信号与自定义槽函数关联
self.combobox.currentIndexChanged.connect(self.showinfo)
# 为菜单中的QAction绑定triggered信号
self.toolBar.actionTriggered[QtWidgets.QAction].connect(self.getvalue)
# 窗口底部的设置状态栏
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.label = QtWidgets.QLabel() # 创建一个Label控件
self.label.setText("版权所有:某某科技有限公司") # 设置Label的文本
# self.statusbar.addWidget(self.label) # 将Label控件添加到状态栏中
self.statusbar.addPermanentWidget(self.label) # 将Label控件添加到状态栏中
# 解决Label文本和临时信息重合的问题:
self.statusbar.showMessage("当前登录用户:mr", 0) # 在状态栏中显示临时信息
# 删除状态栏中的临时信息:
self.statusbar.clearMessage()
def getvalue(self, m):
# 使用information()方法弹出信息提示框
QMessageBox.information(MainWindow, "提示", "您单击了 " + m.text(), QMessageBox.Ok)
def showinfo(self):
# 显示选择的职位
QMessageBox.information(MainWindow, "提示", "您选择的职位是:" + self.combobox.currentText(), QMessageBox.Ok)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
import sys
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
5. 在状态栏中实时显示当前时间
示例:在状态栏中实时显示当前时间
在PyQt5的Qt Designer设计器中创建一个MainWindow窗口,删除默认的菜单栏,保留状态栏,然后调整窗口的大小,并保存为.ui文件,将.ui文件转换为.py文件,在.py文件中使用QTimer计时器实时获取当前的日期时间,并使用QStatusBar对象的showMessage()方法显示在状态栏上。
完整代码如下:
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(433, 381)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
# 添加一个状态栏
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 创建一个QTimer计时器对象
timer = QtCore.QTimer(MainWindow)
# 发射timeout信号,与自定义槽函数关联
timer.timeout.connect(self.showtime)
# 启动计时器
timer.start()
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
# 自定义槽函数,用来在状态栏中显示当前日期时间
def showtime(self):
# 获取当前日期时间
datetime = QtCore.QDateTime.currentDateTime()
# 对日期时间进行格式化
text = datetime.toString("yyyy-MM-dd HH:mm:ss")
# 在状态栏中显示日期时间
self.statusbar.showMessage("当前日期时间:" + text, 0)
import sys
# 主方法,程序从此处启动PyQt设计的窗体
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow() # 创建窗体对象
ui = Ui_MainWindow() # 创建PyQt设计的窗体对象
ui.setupUi(MainWindow) # 调用PyQt窗体的方法对窗体对象进行初始化设置
MainWindow.show() # 显示窗体
sys.exit(app.exec_()) # 程序关闭时退出进程
运行程序,在窗口中的状态栏中会实时显示系统当前的日期时间:
QTimer类的简单说明
上面代码中用到了PyQt5中的QTimer类,该类是一个计时器类,它最常用的两个方法时start()和stop()方法,其中,start()方法用来启动计时器,参数以秒为单位,默认为1秒;stop()方法用来停止计时器。另外,QTimer类还提供了一个timeout信号,在执行定时操作时发射该信号。
更多推荐
所有评论(0)