(四)PyQt5高级控件的使用

PyQt5中包含了很多用于简化窗口设计的可视化控件,除了常用控件外,还有一些关于进度、展示数据等的高级控件。

本章重点讲解PyQt5程序开发中用到的一些高级控件,主要包括ProgressBar进度条控件、QSlider滑块控件、树控件、分割线控件、弹簧控件、Dial旋钮控件和QScrollBar滚动条控件,另外,还对如何在程序中自定义等待提示框进行了介绍。学习本章内容时,重点需要掌握ProgressBar进度条控件、QSlider滑块控件和TreeWidget树控件的使用方法。

1. 进度条类控件

进度条类控件主要显示任务的执行进度,PyQt5提供了进度条控件滑块控件这两种类型的进度条控件。其中,进度条控件是我们通常所看到的进度条,用ProgressBar控件表示,而滑块控件是以刻度线的形式出现。

1. ProgressBar:进度条

ProgressBar控件表示进度条,通常在执行长时间任务时,用进度条告诉用户当前的进展情况。

      ProgressBar控件对应PyQt5中的QProgressBar类,它其实就是QProgressBar类的一个对象。

QProgressBar类的常用方法及说明

方法 说明
setMinimun() 设置进度条的最小值,默认值为0。
setMaximun() 设置进度条的最大值,默认值为99。
setRange() 设置进度条的取值范围,相当于setMinimum()和settMaximum()的结合。
setValue() 设置进度条的当前值。
setFormat()
  • 设置进度条的文字显示格式,有以下三种格式:
  • %p%:显示完成的百分比,默认格式;
  • %v%:显示当前的进度值;
  • %m%:显示总的步长值。
setLayoutDirection()
  • 设置进度条的布局方向,支持以下3个方向值:
  • Qt.LeftToRight:从左至右;
  • Qt.AlignHCenter:水平居中对齐;
  • Qt.LayoutDirectionAuto:跟随布局方向自动调整。
setAlignment() 设置对齐方式,有水平和垂直两种,分别如下:

  • 水平对齐方式:
  • Qt.AlignLeft:左对齐;
  • Qt.AlignHCenter:水平居中对齐;
  • Qt.AlignRight:右对齐;
  • Qt.AlignJustify:两端对齐;
  • 垂直对齐方式:
  • Qt.AlignTop:顶部对齐;
  • Qt.AlignVCenter:垂直居中;
  • Qt.AlignBottom:底部对齐。
setOrientation()
  • 设置进度条的显示方向,有以下两个方向:
  • Qt.Horizontal:水平方向;
  • Qt.Vertical:垂直方向。
setInvertedAppearance() 设置进度条是否以反方向显示进度。
setTextDirection()
  • 设置进度条的文本显示方向,有以下两个方向:
  • QProgressBar.TopToBottom:从上到下;
  • QProgressBar.BottomToTop:从下到上。
setProperty() 对进度条的属性进行设置,可以是任何属性,如self.progressBar.setProperty("value", 24)。
minimum() 获取进度条的最小值。
maximum() 获取进度条的最大值。
value() 获取进度条的当前值。

ProgressBar控件最常用的信号是valueChanged,在进度条的值发生改变时发射。

通过对ProgressBar控件的显示方向、对齐方式、布局方向等进行设置,该控件可以支持4种水平进度条显示方式2种垂直进度条显示方式,用户可以根据自身需要选择适合自己的显示方式。

      如果将最小值和最大值都设置为0,那么进度条会显示为一个不断循环滚动的繁忙进度,而不是步骤的百分比。

示例:模拟一个跑马灯效果

打开Qt Designer设计器,创建一个窗口,并向窗口中添加4个ProgressBar控件和一个PushButton控件,然后将该窗口转换为.py文件,在.py文件中对进度条和PushButton按钮的clicked信号进行绑定。
完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(305, 259)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.progressBar = QtWidgets.QProgressBar(self.centralwidget)self.progressBar.setGeometry(QtCore.QRect(50, 10, 201, 31))self.progressBar.setLayoutDirection(QtCore.Qt.LeftToRight)self.progressBar.setProperty("value", -1)self.progressBar.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop)self.progressBar.setTextVisible(True)self.progressBar.setOrientation(QtCore.Qt.Horizontal)self.progressBar.setTextDirection(QtWidgets.QProgressBar.TopToBottom)self.progressBar.setFormat("")self.progressBar.setObjectName("progressBar")self.progressBar_2 = QtWidgets.QProgressBar(self.centralwidget)self.progressBar_2.setGeometry(QtCore.QRect(50, 180, 201, 31))self.progressBar_2.setLayoutDirection(QtCore.Qt.RightToLeft)self.progressBar_2.setProperty("value", -1)self.progressBar_2.setAlignment(QtCore.Qt.AlignBottom | QtCore.Qt.AlignHCenter)self.progressBar_2.setTextVisible(True)self.progressBar_2.setOrientation(QtCore.Qt.Horizontal)self.progressBar_2.setTextDirection(QtWidgets.QProgressBar.TopToBottom)self.progressBar_2.setObjectName("progressBar_2")self.progressBar_3 = QtWidgets.QProgressBar(self.centralwidget)self.progressBar_3.setGeometry(QtCore.QRect(20, 10, 31, 201))self.progressBar_3.setLayoutDirection(QtCore.Qt.LeftToRight)self.progressBar_3.setProperty("value", -1)self.progressBar_3.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignTop)self.progressBar_3.setTextVisible(True)self.progressBar_3.setOrientation(QtCore.Qt.Vertical)self.progressBar_3.setTextDirection(QtWidgets.QProgressBar.TopToBottom)self.progressBar_3.setObjectName("progressBar_3")self.progressBar_1 = QtWidgets.QProgressBar(self.centralwidget)self.progressBar_1.setGeometry(QtCore.QRect(250, 10, 31, 201))self.progressBar_1.setLayoutDirection(QtCore.Qt.LeftToRight)self.progressBar_1.setProperty("value", -1)self.progressBar_1.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)self.progressBar_1.setTextVisible(True)self.progressBar_1.setOrientation(QtCore.Qt.Vertical)self.progressBar_1.setTextDirection(QtWidgets.QProgressBar.TopToBottom)self.progressBar_1.setObjectName("progressBar_1")self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setGeometry(QtCore.QRect(90, 220, 101, 31))self.pushButton.setObjectName("pushButton")MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)self.timer = QtCore.QBasicTimer()     # 创建计时器对象# 为按钮绑定单击信号self.pushButton.clicked.connect(self.running)# 控制进度条的滚动效果def running(self):if self.timer.isActive():              # 判断计时器是否开启self.timer.stop()             # 停止计时器self.pushButton.setText("开始")     # 设置按钮的文本# 设置4个进度条的最大值为100self.progressBar.setMaximum(100)self.progressBar_1.setMaximum(100)self.progressBar_2.setMaximum(100)self.progressBar_3.setMaximum(100)else:self.timer.start(100, MainWindow)       # 启动计时器self.pushButton.setText("停止")      # 设置按钮的文本# 将4个进度条的最大值和最小值都设置为0, 以便显示循环滚动的效果self.progressBar.setMinimum(0)self.progressBar.setMaximum(0)self.progressBar_1.setInvertedAppearance(True)    # 设置进度反向显示self.progressBar_1.setMinimum(0)self.progressBar_1.setMaximum(0)self.progressBar_2.setMinimum(0)self.progressBar_2.setMaximum(0)self.progressBar_3.setMinimum(0)self.progressBar_3.setMaximum(0)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("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_())

运行效果如下:

QBasicTimer类的简单介绍

上面代码用到了QBasicTimer类,该类是QtCore模块中包含的一个类,主要用来为对象提供定时器事件。QBasicTimer定时器是一个重复的定时器,除非调用stop()方法,否则它将发送后续的定时器事件。启动定时器使用start()方法,该方法有两个参数,分别为超时时间(毫秒)和接收事件的对象,而停止定时器使用stop()方法即可。

2. 自定义等待提示框

在使用PyQt5创建桌面窗口应用程序时,有时会遇到等待长任务执行的情况,PyQt5提供的ProgressBar控件(即QProgressBar对象)虽然也可以通过循环滚动的方式等待任务执行完成,但与我们通常见到的下图所示的等待提示框相比,不是特别美观。

示例:自定义等待提示框

使用PyQt5实现等待提示框时,可以通过加载gif图片的方式模拟等待提示框,首先在创建主窗口时,在窗口的中间位置添加一个可以加载gif图片的Label控件,然后再添加两个PushButton按钮,分别用于控制等待提示框的启动与停止。
完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")# MainWindow.resize(400, 227)MainWindow.resize(300, 300)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.loading = QtWidgets.QLabel(self.centralwidget)# self.loading.setGeometry(QtCore.QRect(150, 20, 100, 100))self.loading.setGeometry(QtCore.QRect(70, 20, 200, 200))self.loading.setStyleSheet("")self.loading.setText("")self.loading.setObjectName("loading")self.pushButton_start = QtWidgets.QPushButton(self.centralwidget)# self.pushButton_start.setGeometry(QtCore.QRect(50, 140, 100, 50))self.pushButton_start.setGeometry(QtCore.QRect(20, 230, 100, 50))self.pushButton_start.setObjectName("pushButton_start")self.pushButton_stop = QtWidgets.QPushButton(self.centralwidget)# self.pushButton_stop.setGeometry(QtCore.QRect(250, 140, 100, 50))self.pushButton_stop.setGeometry(QtCore.QRect(180, 230, 100, 50))self.pushButton_stop.setObjectName("pushButton_stop")MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)self.pushButton_start.clicked.connect(self.start_loading)     # 启动加载提示框self.pushButton_stop.clicked.connect(self.stop_loading)    # 停止加载提示框def start_loading(self):self.gif = QtGui.QMovie("./image/loading.gif")     # 加载gif图片self.loading.setMovie(self.gif)   # 设置gif图片self.gif.start()        # 启动图片,实现等待gif图片的显示def stop_loading(self):self.gif.stop()self.loading.clear()def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.pushButton_start.setText(_translate("MainWindow", "启动等待提示"))self.pushButton_stop.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_())    # 程序关闭时退出程序

运行结果如图所示:



使用的动态图如下:

      上面代码中使用QLabel类的setMovie()方法为其设置要显示的gif动画图片,该方法要求有一个QMovie对象作为参数,QMovie类是QtGui模块中提供的一个用来显示简单且没有声音动画的类。

3. 滑块:QSlider

PyQt5提供了两个滑块控件,分别是水平滑块HorizontalSlider和垂直滑块VerticalSlider,但这两个滑块控件对应的类都是QSlider类,该类提供了一个setOrientation()方法,通过设置该方法的参数,可以将滑块显示为水平或者垂直。

QSlider滑块类的常用方法及说明

<tr><td>setTickPosition()</td><td><ul align="left">设置滑块刻度的标记位置,取值如下:<li>QSlider.NoTicks:不显示刻度,这是默认设置;</li><li>QSlider.TicksBothSides:在滑块的两侧都显示刻度;</li><li>QSlider.TicksAbove:在水平滑块的上方显示刻度;</li><li>QSlider.TicksBelow:在水平滑块的下方显示刻度;</li><li>QSlider.TicksLeft:在垂直滑块的左侧显示刻度;</li><li>QSlider.TicksRight:在垂直滑块的右侧显示刻度。</li></ul></td>
</tr>
<tr><td>value()</td><td>获取滑块的当前值。</td>
</tr>
方法 说明
setMinumum() 设置滑块最小值。
setMaximum()> 设置滑块最大值。
setOrientation()
  • 设置滑块显示方向,取值如下:
  • Qt.Horizontal:水平滑块;
  • Qt.Vertical:垂直滑块。
setPageStep() 设置步长值,通过鼠标**点击滑块时**使用。
setSingleStep() 设置步长值,通过鼠标**拖动滑块时**使用。
setValue() 设置滑块的值。
setTickInterval() 设置滑块的刻度间隔。

QSlider滑块类的常用信号及说明

信号 说明
valueChanged 当滑块的值发生改变时发射信号。
sliderPressed 当用户按下滑块时发射该信号。
sliderMoved 当用户拖动滑块时发射该信号。
sliderReleased 当用户释放滑块时发射该信号。

注意,QSlider滑块只能控制整数范围,它不适合于需要准确的大范围取值的场景。

示例:使用滑块控制标签中的字体大小

在Qt Designer设计器中创建一个窗口,在窗口中分别添加一个HorizontalSlider水平滑块和一个VerticalSlider垂直滑块,然后添加一个HorizontalLayout水平布局管理器,在该布局管理器中添加一个Label标签,用来显示文字。设计完成后,保存为.ui文件,并使用PyUIC工具将其转换为.py文件。在.py文件中通过绑定水平滑块的valueChanged信号,实现拖动水平滑块时,实时改变垂直滑块的刻度值,同时改变Label标签中的字体大小。
完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(313, 196)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")# 创建水平滑块self.horizontalSlider = QtWidgets.QSlider(self.centralwidget)self.horizontalSlider.setGeometry(QtCore.QRect(20, 10, 231, 22))self.horizontalSlider.setMinimum(8)     # 设置最小值为8self.horizontalSlider.setMaximum(72)    # 设置最大值为72self.horizontalSlider.setSingleStep(1)    # 设置通过鼠标拖动时的步长值self.horizontalSlider.setPageStep(1)     # 设置通过鼠标单机时的步长值self.horizontalSlider.setProperty("value", 8)    # 设置默认值为8self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)    # 设置滑块为水平滑块# 设置在滑块上方显示刻度self.horizontalSlider.setTickPosition(QtWidgets.QSlider.TicksAbove)self.horizontalSlider.setTickInterval(3)    # 设置刻度的间隔self.horizontalSlider.setObjectName("horizontalSlider")# 创建垂直滑块self.verticalSlider = QtWidgets.QSlider(self.centralwidget)self.verticalSlider.setGeometry(QtCore.QRect(270, 20, 22, 171))self.verticalSlider.setMinimum(8)    # 设置最小值为8self.verticalSlider.setMaximum(72)   # 设置滑块为垂直滑块self.verticalSlider.setOrientation(QtCore.Qt.Vertical)     # 设置滑块为垂直滑块self.verticalSlider.setInvertedAppearance(True)    # 设置刻度反方向显示# 设置在滑块右侧显示刻度self.verticalSlider.setTickPosition(QtWidgets.QSlider.TicksRight)self.verticalSlider.setTickInterval(3)     # 设置刻度的间隔self.verticalSlider.setObjectName("verticalSlider")# 创建一个水平布局管理器,主要用来放置显示文字的Labelself.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 70, 251, 80))self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)self.horizontalLayout.setGeometry(QtCore.QRect(20, 70, 251, 80))self.horizontalLayout.setObjectName("horizontalLayout")# 创建Label控件,用来显示文字self.label = QtWidgets.QLabel(self.horizontalLayoutWidget)self.label.setAlignment(QtCore.Qt.AlignCenter)     # 设置文字居中对齐self.label.setObjectName("label")self.horizontalLayout.addWidget(self.label)      # 将Label添加到水平布局管理器中MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)# 为水平滑块绑定valueChanged信号,在值发生更改时发射self.horizontalSlider.valueChanged.connect(self.setfontsize)# 定义槽函数,根据水平滑块的值改变垂直滑块的值和Label控件的字体大小def setfontsize(self):value = self.horizontalSlider.value()self.verticalSlider.setValue(value)self.label.setFont(QtGui.QFont("楷体", value))def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWidnow"))self.label.setText(_translate("MainWindow", "敢想敢为,注重细节"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())

说明:上面代码用到了水平布局管理器HorizontalLayout,它实质上是一个QHBoxLayout类的对象,它在这里的主要作用是放置Label控件,这样,Label控件就只可以在水平布局管理器中显示,避免了字体设置过大时,超出窗口范围的问题。
运行程序,当鼠标拖动水平滑块的刻度时,垂直滑块的刻度值会随之变化,另外。Label标签中的文字也会发生改变:


2. 树控件

树控件可以为用户显示节点层次结构,而每个节点又可以包含子节点,包含子节点的节点叫父节点,在设计树形结构(如导航菜单等)时,很方便。PyQt5提供了两个树控件,分别是TreeViewTreeWidget

1. TreeView:树视图

TreeView控件对应PyQt5的QTreeView类,它是树控件的基类,使用时,必须为其提供一个模型来与之配合。

QTreeView类的常用方法及说明

方法 说明
autoExpandDelay() 获取自动展开节点所需要的延迟时间。
collapse() 收缩指定级的节点。
collapseAll() 收缩所有节点。
expand() 展开指定级的节点。
expandAll() 展开所有节点。
header() 树的头信息,常用的有一个setVisible()方法,用来设置是否显示头。
isHeaderHidder() 判断是都隐藏头部。
setAutoExpandDelay() 设置自动展开的延时时间,单位为毫秒,如果值小于0,表示禁用自动展开。
setAlternatingRowColors() 设置每间隔一行颜色是否一样。
setExpanded() 根据索引设置是否展开节点。
setHeaderHidden() 设置是否隐藏头部。
setItemsExpandable() 设置项是否展开。
setMode() 设置要显示的数据模型。
setSortingEnabled() 设置单击头部是否可以排序。
setVerticalScrollBarPolicy() 设置是否显示垂直滚动条。
setHorizontalScrollBarPolicy() 设置是否显示水平滚动条。
setEditTriggers() 设置默认的编辑触发器。
setExpandsOnDoubleClick() 设置是否支持双击展开树节点。
setWordWrap() 设置自动换行。
selectionModel() 获取选中的模型。
sortByColumn() 根据列排序。
setSelectionMode()
  • 设置选中模式,取值如下:
  • QAbstractItemView.NoSelection:不能选择;
  • QAbstractItemView.SingleSelection:单选;
  • QAbstractItemView.MultiSelection:多选;
  • QAbstractItemView.ExtendedSelection:正常单选,按Ctrl或者Shift键后,可以多选;
  • QAbstractItemView.ContiguousSelection:与ExtendedSelection类似。
setSelectionBehavior()
  • 设置选中方式,取值如下:
  • QAbstractItemView.SelectItems:选中当前项;
  • QAbstractItemView.SelectRows:选中整行;
  • QAbstractItemView.SelectColumns:选中整列。

使用TreeView控件分层显示PyQt5内置模型的数据和自定义的数据。

1. 使用内置模型中的数据

PyQt5提供的内置模型及说明
模型 说明
QStringListModel 存储简单的字符串列表。
QStandardItemModel 可以用于树结构的存储,提供了层次数据。
QFileSystemModel 存储本地系统的文件和目录信息(针对当前项目)
QDirModel 存储文件系统。
QsqlQueryModel 存储SQL的查询结构集。
QsqlTableModel 存储SQL中的表格数据。
QsqlRelationalTableModel 存储有外键关系的SQL表格数据。
QSortFilterProxyModel 对模型中的数据进行排序或者过滤。
示例:显示系统文件目录

使用系统内置的QDirModel作为数据模型,在TreeView中显示系统的文件目录。
完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(800, 400)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.treeView = QtWidgets.QTreeView(self.centralwidget)     # 创建树对象self.treeView.setGeometry(QtCore.QRect(0, 0, 794, 395))    # 设置坐标位置和大小# 设置垂直滚动条为按需显示self.treeView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)# 设置水平滚动条为按需显示self.treeView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)# 设置双击或者按下Enter键时,树节点可编辑self.treeView.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked | QtWidgets.QAbstractItemView.EditKeyPressed)# 设置树节点为单选self.treeView.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)# 设置选中节点时为整行选中self.treeView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)self.treeView.setAutoExpandDelay(-1)   # 设置自动展开延时为-1,表示自动展开不可用self.treeView.setItemsExpandable(True)    # 设置是否可以展开项self.treeView.setSortingEnabled(True)   # 设置单击头部可排序self.treeView.setWordWrap(True)   # 设置自动换行self.treeView.setHeaderHidden(False)   # 设置不隐藏头部self.treeView.setExpandsOnDoubleClick(True)    # 设置双击可以展开节点self.treeView.setObjectName("treeView")self.treeView.header().setVisible(True)    # 设置显示头部MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)model = QtWidgets.QDirModel()    # 创建存储文件系统的模型self.treeView.setModel(model)    # 为树控件设置数据模型def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWidow"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()    # 创建窗体对象ui = Ui_MainWindow()     # 创建PyQt设计的窗体对象ui.setupUi(MainWindow)     # 调用PyQt窗体方法,对窗体对象初始化设置MainWindow.show()    # 显示窗体sys.exit(app.exec_())

运行效果如图所示:

2. 使用自定义数据

PyQt5提供了一个QStandardItemModel模型,该模型可以存储任意层次结构的数据。下面介绍如何使用QStandardItemModel模型存储数据结构,并显示在TreeView控件中。

示例:使用TreeView显示各班级的学生成绩信息

创建一个PyQt窗口,并在其中添加一个TreeView控件,然后在.py文件中使用QStandardItemModel模型存储某年级下的各个班级的学生成绩信息,最后将设置完的QStandardItemModel模型作为TreeView控件的数据模型进行显示。
完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(600, 900)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")# 创建一个TreeView树视图self.treeView = QtWidgets.QTreeView(self.centralwidget)self.treeView.setGeometry(QtCore.QRect(0, 0, 599, 898))self.treeView.setObjectName("treeView")MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)model = QtGui.QStandardItemModel()    # 创建数据模型model.setHorizontalHeaderLabels(["年级", "班级", "姓名", "分数"])name = ["橘真琴", "远坂凛", "雾影才藏", "猿飞佐助", "真田幸村", "伊佐那海", "龙之峰帝人", "平和岛静雄", "结城新十郎", "漩涡鸣人", "夜刀神狗郎", "伊佐那社"]   # 姓名列表score = [90, 80, 80, 80, 87, 89, 87, 88, 78, 89, 89, 94]   # 分数列表import random# 设置数据for i in range(0, 6):# 一级节点:年级,只设第1列的数据grade = QtGui.QStandardItem(("%s 年级") % (i + 1))model.appendRow(grade)    # 一级节点for j in range(0, 4):# 二级节点:班级、姓名、分数itemClass = QtGui.QStandardItem(("%s 班") % (j + 1))itemName = QtGui.QStandardItem(name[random.randrange(10)])itemScore = QtGui.QStandardItem(str(score[random.randrange(10)]))# 将二级节点添加到一级节点上grade.appendRow([QtGui.QStandardItem(""), itemClass, itemName, itemScore])self.treeView.setModel(model)    # 为TreeView设置数据模型def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()       # 创建窗体对象ui = Ui_MainWindow()      # 创建PyQt设计的窗体对象ui.setupUi(MainWindow)    # 调用PyQt窗体的方法对窗体对象进行初始化设置MainWindow.show()    # 显示窗体sys.exit(app.exec_())   # 程序关闭时退出进程

运行程序,可以展开年级节点:

2. TreeWidget:树控件

TreeWidget控件对应于PyQt5中的QTreeWidget类,它提供了一个使用预定义树模型的树视图,它的每一个树节点都是一个QTreeWidgetItem。

QTreeWidget类的常用方法及说明

方法 说明
addTopLevelItem() 添加顶级节点
insertTopLevelItems() 在树的顶层索引中插入节点
invisibleRootItem() 获取树控件中不可见的根选项
setColumnCount() 设置要显示的列数
setColumnWidth() 设置列的宽度
selectedItems() 获取选中的树节点
      QTreeWidgetItem中的树节点项。

QTreeWidgetItem类的常用方法及说明

方法 说明
addChild() 添加子节点。
setText() 设置节点的文本。
setCheckState()
  • 设置指定节点的选中状态,取值如下:
  • Qt.Checked:节点选中。
  • Qt.Unchecked:节点未选中。
setIcon() 为节点设置图标。
text() 获取节点的文本。

TreeWidget控件的常见用法如下:

1. 使用TreeWidget控件显示树结构

使用TreeWidget控件显示树结构主要用到QTreeWidgetItem类,该类表示标准树节点,通过其setText()方法可以设置树节点的文本。

示例:使用TreeWidget显示树结构

创建一个PyQt5窗口,并在其中添加一个TreeWidget控件,然后保存为.ui文件,并使用PyUIC工具将其转换为.py文件,在.py文件中,通过创建QTreeWidgetItem对象为树控件设置树节点。
完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTreeWidgetItemclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(400, 300)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)self.treeWidget.setGeometry(QtCore.QRect(0, 0, 400, 300))self.treeWidget.setObjectName("treeWidget")self.treeWidget.setColumnCount(2)    # 设置树结构中的列数self.treeWidget.setHeaderLabels(["姓名", "职务"])    # 设置列标题名root = QTreeWidgetItem(self.treeWidget)       # 创建节点root.setText(0, "组织结构")     # 设置顶级节点文本# 定义字典,存储树中显示的数据dict = {"任正非": "华为董事长", "马云": "阿里巴巴创始人", "马化腾": "腾讯 CEO", "李彦宏": "百度 CEO", "董明珠": "格力董事长"}for key, value in dict.items():   # 遍历字典child = QTreeWidgetItem(root)    # 创建子节点child.setText(0, key)     # 设置第一列的值child.setText(1, value)   # 设置第二列的值self.treeWidget.addTopLevelItem(root)   # 将创建的树节点添加到树控件中self.treeWidget.expandAll()     # 展开所有节点MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())

运行结果如图所示:

2. 为节点设置图标

为节点设置图标主要用到了QtWidgetItem类的setIcon()方法。

示例:为前一个示例中第一列的每个企业家姓名前面设置其对应公司的图标

关键代码如下:

# 为节点设置图标if key == "任正非":child.setIcon(0, QtGui.QIcon("image/华为.png"))elif key == "马云":child.setIcon(0, QtGui.QIcon("image/阿里巴巴.png"))elif key == "马化腾":child.setIcon(0, QtGui.QIcon("image/腾讯.png"))elif key == "李彦宏":child.setIcon(0, QtGui.QIcon("image/百度.png"))elif key == "董明珠":child.setIcon(0, QtGui.QIcon("image/格力.png"))

完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTreeWidgetItemclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(400, 300)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)self.treeWidget.setGeometry(QtCore.QRect(0, 0, 400, 300))self.treeWidget.setObjectName("treeWidget")self.treeWidget.setColumnCount(2)    # 设置树结构中的列数self.treeWidget.setHeaderLabels(["姓名", "职务"])    # 设置列标题名root = QTreeWidgetItem(self.treeWidget)       # 创建节点root.setText(0, "组织结构")     # 设置顶级节点文本# 定义字典,存储树中显示的数据dict = {"任正非": "华为董事长", "马云": "阿里巴巴创始人", "马化腾": "腾讯 CEO", "李彦宏": "百度 CEO", "董明珠": "格力董事长"}for key, value in dict.items():   # 遍历字典child = QTreeWidgetItem(root)    # 创建子节点child.setText(0, key)     # 设置第一列的值child.setText(1, value)   # 设置第二列的值# 为节点设置图标if key == "任正非":child.setIcon(0, QtGui.QIcon("image/华为.png"))elif key == "马云":child.setIcon(0, QtGui.QIcon("image/阿里巴巴.png"))elif key == "马化腾":child.setIcon(0, QtGui.QIcon("image/腾讯.png"))elif key == "李彦宏":child.setIcon(0, QtGui.QIcon("image/百度.png"))elif key == "董明珠":child.setIcon(0, QtGui.QIcon("image/格力.png"))self.treeWidget.addTopLevelItem(root)   # 将创建的树节点添加到树控件中self.treeWidget.expandAll()     # 展开所有节点MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())

运行结果:

3. 为节点设置复选框

为节点设置复选框主要用到了QTreeWidgetItem类的setCheckState()方法,该方法可以设置选中(Qt.Checked),也可以设置未选中(Qt.Unchecked)

示例:为上一示例中的第一列设置复选框,并全部设置为选中状态。

关键代码:

            child.setCheckState(0, QtCore.Qt.Checked)    # 为节点设置复选框,并且选中

全部代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTreeWidgetItemclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(400, 300)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)self.treeWidget.setGeometry(QtCore.QRect(0, 0, 400, 300))self.treeWidget.setObjectName("treeWidget")self.treeWidget.setColumnCount(2)    # 设置树结构中的列数self.treeWidget.setHeaderLabels(["姓名", "职务"])    # 设置列标题名root = QTreeWidgetItem(self.treeWidget)       # 创建节点root.setText(0, "组织结构")     # 设置顶级节点文本# 定义字典,存储树中显示的数据dict = {"任正非": "华为董事长", "马云": "阿里巴巴创始人", "马化腾": "腾讯 CEO", "李彦宏": "百度 CEO", "董明珠": "格力董事长"}for key, value in dict.items():   # 遍历字典child = QTreeWidgetItem(root)    # 创建子节点child.setText(0, key)     # 设置第一列的值child.setText(1, value)   # 设置第二列的值# 为节点设置图标if key == "任正非":child.setIcon(0, QtGui.QIcon("image/华为.png"))elif key == "马云":child.setIcon(0, QtGui.QIcon("image/阿里巴巴.png"))elif key == "马化腾":child.setIcon(0, QtGui.QIcon("image/腾讯.png"))elif key == "李彦宏":child.setIcon(0, QtGui.QIcon("image/百度.png"))elif key == "董明珠":child.setIcon(0, QtGui.QIcon("image/格力.png"))child.setCheckState(0, QtCore.Qt.Checked)    # 为节点设置复选框,并且选中self.treeWidget.addTopLevelItem(root)   # 将创建的树节点添加到树控件中self.treeWidget.expandAll()     # 展开所有节点MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())

运行效果:

4. 设置各行变色显示树节点

隔行变色显示树节点需要用到TreeWidget控件的setAlternatingRowColors()方法,设置为True表示隔行换色,设置为False表示统一颜色。

示例:将上一示例中的树设置为隔行变色形式显示

关键代码如下:

        # 设置隔行变色self.treeWidget.setAlternatingRowColors(True)

完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTreeWidgetItemclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(400, 300)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)self.treeWidget.setGeometry(QtCore.QRect(0, 0, 400, 300))self.treeWidget.setObjectName("treeWidget")self.treeWidget.setColumnCount(2)    # 设置树结构中的列数self.treeWidget.setHeaderLabels(["姓名", "职务"])    # 设置列标题名# 设置隔行变色self.treeWidget.setAlternatingRowColors(True)root = QTreeWidgetItem(self.treeWidget)       # 创建节点root.setText(0, "组织结构")     # 设置顶级节点文本# 定义字典,存储树中显示的数据dict = {"任正非": "华为董事长", "马云": "阿里巴巴创始人", "马化腾": "腾讯 CEO", "李彦宏": "百度 CEO", "董明珠": "格力董事长"}for key, value in dict.items():   # 遍历字典child = QTreeWidgetItem(root)    # 创建子节点child.setText(0, key)     # 设置第一列的值child.setText(1, value)   # 设置第二列的值# 为节点设置图标if key == "任正非":child.setIcon(0, QtGui.QIcon("image/华为.png"))elif key == "马云":child.setIcon(0, QtGui.QIcon("image/阿里巴巴.png"))elif key == "马化腾":child.setIcon(0, QtGui.QIcon("image/腾讯.png"))elif key == "李彦宏":child.setIcon(0, QtGui.QIcon("image/百度.png"))elif key == "董明珠":child.setIcon(0, QtGui.QIcon("image/格力.png"))child.setCheckState(0, QtCore.Qt.Checked)    # 为节点设置复选框,并且选中self.treeWidget.addTopLevelItem(root)   # 将创建的树节点添加到树控件中self.treeWidget.expandAll()     # 展开所有节点MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())

运行效果如下,树控件的奇数行为浅灰色背景,而偶数行为白色背景:

5. 获取选中节点的文本

获取选中节点的文本时,首先需要使用currentItem()方法获取当前的选中项,然后通过text()方法获取指定列的文本。

示例:在上一示例基础上定义槽函数,显示单击的树节点文本

关键代码如下:

        # 为树控件的clicked信号绑定自定义的槽函数,以便在单击树控件时发射:self.treeWidget.clicked.connect(self.gettreetext)# 自定义槽函数def gettreetext(self, index):item = self.treeWidget.currentItem()      # 获取当前选中项from PyQt5.QtWidgets import QMessageBox# 弹出提示框,显示选中项的文本QtWidgets.QMessageBox.information(MainWindow, "提示", "您选择的是:%s -- %s" % (item.text(0), item.text(1)), QtWidgets.QMessageBox.Ok)

完整代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTreeWidgetItemclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(400, 300)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)self.treeWidget.setGeometry(QtCore.QRect(0, 0, 400, 300))self.treeWidget.setObjectName("treeWidget")self.treeWidget.setColumnCount(2)    # 设置树结构中的列数self.treeWidget.setHeaderLabels(["姓名", "职务"])    # 设置列标题名# 设置隔行变色self.treeWidget.setAlternatingRowColors(True)root = QTreeWidgetItem(self.treeWidget)       # 创建节点root.setText(0, "组织结构")     # 设置顶级节点文本# 定义字典,存储树中显示的数据dict = {"任正非": "华为董事长", "马云": "阿里巴巴创始人", "马化腾": "腾讯 CEO", "李彦宏": "百度 CEO", "董明珠": "格力董事长"}for key, value in dict.items():   # 遍历字典child = QTreeWidgetItem(root)    # 创建子节点child.setText(0, key)     # 设置第一列的值child.setText(1, value)   # 设置第二列的值# 为节点设置图标if key == "任正非":child.setIcon(0, QtGui.QIcon("image/华为.png"))elif key == "马云":child.setIcon(0, QtGui.QIcon("image/阿里巴巴.png"))elif key == "马化腾":child.setIcon(0, QtGui.QIcon("image/腾讯.png"))elif key == "李彦宏":child.setIcon(0, QtGui.QIcon("image/百度.png"))elif key == "董明珠":child.setIcon(0, QtGui.QIcon("image/格力.png"))child.setCheckState(0, QtCore.Qt.Checked)    # 为节点设置复选框,并且选中self.treeWidget.addTopLevelItem(root)   # 将创建的树节点添加到树控件中self.treeWidget.expandAll()     # 展开所有节点MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)# 为树控件的clicked信号绑定自定义的槽函数,以便在单击树控件时发射:self.treeWidget.clicked.connect(self.gettreetext)# 自定义槽函数def gettreetext(self, index):item = self.treeWidget.currentItem()      # 获取当前选中项from PyQt5.QtWidgets import QMessageBox# 弹出提示框,显示选中项的文本QtWidgets.QMessageBox.information(MainWindow, "提示", "您选择的是:%s -- %s" % (item.text(0), item.text(1)), QtWidgets.QMessageBox.Ok)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))import sysif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())

运行效果如下:

3. 分割控件

分割类控件主要对窗口中的区域进行功能划分,使窗口看起来更加合理、美观,PyQt5提供了分割线弹簧两种类型的分割控件。

1. 分割线:QFrame

PyQt5提供了两个分割线控件,分别是水平分割线HorizontalLine垂直分割线VerticalLine,但这两个分割线控件对应的类都是QFrame类,该类提供了一个setFrameShape()方法,通过设置该方法的参数,可以将分割线显示为水平或者垂直。

QFrame类的常用方法及说明

方法 说明
setFrameShape()
  • 设置分割线方向,取值如下:
  • QFrame.HLine:水平分割线;
  • QFrame.VLine:垂直分割线。
setFrameShadow()
  • 设置分割线的显示样式,取值如下:
  • QFrame.Sunken:有边框阴影,并且下沉显示,这是默认设置;
  • QFrame.Plain:无阴影;
  • QFrame.Raised:有边框阴影,并且凸起显示。
setLineWidth() 设置分割线的宽度。
setMidLineWidth() 设置分割线的中间线宽度。

示例:PyQT5窗口中的分割线展示

在Qt Designer设计器中创建一个窗口,在窗口中添加8个Label控件,分别用来作为区域和分割线的标识;添加3个HorizontalLine水平分割线和4个VerticalLine垂直分割线,其中,用3个HorizontalLine水平分割线和3个VerticalLine垂直分割线显示分割线的各种样式,而剩余的一个VerticalLine垂直分割线用来将窗口分成两个区域。
关键代码如下:

        # 添加水平分割线,并设置样式为Sunken,表示有下沉显示的边框阴影:self.line_2 = QtWidgets.QFrame(self.centralwidget)self.line_2.setGeometry(QtCore.QRect(90, 75, 201, 31))self.line_2.setFrameShape(QtWidgets.QFrame.HLine)self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)self.line_2.setLineWidth(8)self.line_2.setMidLineWidth(8)self.line_2.setObjectName("line_2")# 添加水平分割线,并设置样式为Plain,表示无阴影:self.line_3 = QtWidgets.QFrame(self.centralwidget)self.line_3.setGeometry(QtCore.QRect(90, 140, 201, 31))self.line_3.setFrameShape(QtWidgets.QFrame.HLine)self.line_3.setFrameShadow(QtWidgets.QFrame.Plain)self.line_3.setLineWidth(8)self.line_3.setMidLineWidth(8)self.line_3.setObjectName("line_3")# 添加水平分割线,并设置样式为Raised,表示有凸起显示的边框阴影:self.line_4 = QtWidgets.QFrame(self.centralwidget)self.line_4.setGeometry(QtCore.QRect(90, 210, 201, 31))self.line_4.setFrameShape(QtWidgets.QFrame.HLine)self.line_4.setFrameShadow(QtWidgets.QFrame.Raised)self.line_4.setLineWidth(8)self.line_4.setMidLineWidth(8)self.line_4.setObjectName("line_4")# 添加垂直分割线,并设置样式为Sunken,表示有下沉显示的边框阴影:self.line_5 = QtWidgets.QFrame(self.centralwidget)self.line_5.setGeometry(QtCore.QRect(403, 70, 41, 151))self.line_5.setFrameShape(QtWidgets.QFrame.VLine)self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken)self.line_5.setLineWidth(4)self.line_5.setMidLineWidth(4)self.line_5.setObjectName("line_5")# 添加垂直分割线,并设置样式为Plain,表示无阴影:self.line_6 = QtWidgets.QFrame(self.centralwidget)self.line_6.setGeometry(QtCore.QRect(520, 70, 41, 151))self.line_6.setFrameShape(QtWidgets.QFrame.VLine)self.line_6.setFrameShadow(QtWidgets.QFrame.Plain)self.line_6.setLineWidth(4)self.line_6.setMidLineWidth(4)self.line_6.setObjectName("line_6")# 添加垂直分割线,并设置样式为Raised,表示有凸起显示的边框阴影:self.line_7 = QtWidgets.QFrame(self.centralwidget)self.line_7.setGeometry(QtCore.QRect(650, 70, 41, 151))self.line_7.setFrameShape(QtWidgets.QFrame.VLine)self.line_7.setFrameShadow(QtWidgets.QFrame.Raised)self.line_7.setLineWidth(4)self.line_7.setMidLineWidth(4)self.line_7.setObjectName("line_7")

完整代码如下:

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(755, 320)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.label = QtWidgets.QLabel(self.centralwidget)self.label.setGeometry(QtCore.QRect(20, 10, 121, 16))self.label.setObjectName("label")self.label_2 = QtWidgets.QLabel(self.centralwidget)self.label_2.setGeometry(QtCore.QRect(480, 10, 91, 16))self.label_2.setObjectName("label_2")self.label_3 = QtWidgets.QLabel(self.centralwidget)self.label_3.setGeometry(QtCore.QRect(20, 80, 72, 15))self.label_3.setObjectName("label_3")self.label_4 = QtWidgets.QLabel(self.centralwidget)self.label_4.setGeometry(QtCore.QRect(20, 150, 72, 15))self.label_4.setObjectName("label_4")self.label_5 = QtWidgets.QLabel(self.centralwidget)self.label_5.setGeometry(QtCore.QRect(20, 220, 72, 15))self.label_5.setObjectName("label_5")self.label_6 = QtWidgets.QLabel(self.centralwidget)self.label_6.setGeometry(QtCore.QRect(400, 240, 72, 15))self.label_6.setObjectName("label_6")self.label_7 = QtWidgets.QLabel(self.centralwidget)self.label_7.setGeometry(QtCore.QRect(530, 240, 72, 15))self.label_7.setObjectName("label_7")self.label_8 = QtWidgets.QLabel(self.centralwidget)self.label_8.setGeometry(QtCore.QRect(650, 240, 72, 15))self.label_8.setObjectName("label_8")self.line = QtWidgets.QFrame(self.centralwidget)self.line.setGeometry(QtCore.QRect(330, 0, 20, 321))self.line.setFrameShape(QtWidgets.QFrame.VLine)self.line.setFrameShadow(QtWidgets.QFrame.Sunken)self.line.setObjectName("line")# 添加水平分割线,并设置样式为Sunken,表示有下沉显示的边框阴影:self.line_2 = QtWidgets.QFrame(self.centralwidget)self.line_2.setGeometry(QtCore.QRect(90, 75, 201, 31))self.line_2.setFrameShape(QtWidgets.QFrame.HLine)self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)self.line_2.setLineWidth(8)self.line_2.setMidLineWidth(8)self.line_2.setObjectName("line_2")# 添加水平分割线,并设置样式为Plain,表示无阴影:self.line_3 = QtWidgets.QFrame(self.centralwidget)self.line_3.setGeometry(QtCore.QRect(90, 140, 201, 31))self.line_3.setFrameShape(QtWidgets.QFrame.HLine)self.line_3.setFrameShadow(QtWidgets.QFrame.Plain)self.line_3.setLineWidth(8)self.line_3.setMidLineWidth(8)self.line_3.setObjectName("line_3")# 添加水平分割线,并设置样式为Raised,表示有凸起显示的边框阴影:self.line_4 = QtWidgets.QFrame(self.centralwidget)self.line_4.setGeometry(QtCore.QRect(90, 210, 201, 31))self.line_4.setFrameShape(QtWidgets.QFrame.HLine)self.line_4.setFrameShadow(QtWidgets.QFrame.Raised)self.line_4.setLineWidth(8)self.line_4.setMidLineWidth(8)self.line_4.setObjectName("line_4")# 添加垂直分割线,并设置样式为Sunken,表示有下沉显示的边框阴影:self.line_5 = QtWidgets.QFrame(self.centralwidget)self.line_5.setGeometry(QtCore.QRect(403, 70, 41, 151))self.line_5.setFrameShape(QtWidgets.QFrame.VLine)self.line_5.setFrameShadow(QtWidgets.QFrame.Sunken)self.line_5.setLineWidth(4)self.line_5.setMidLineWidth(4)self.line_5.setObjectName("line_5")# 添加垂直分割线,并设置样式为Plain,表示无阴影:self.line_6 = QtWidgets.QFrame(self.centralwidget)self.line_6.setGeometry(QtCore.QRect(520, 70, 41, 151))self.line_6.setFrameShape(QtWidgets.QFrame.VLine)self.line_6.setFrameShadow(QtWidgets.QFrame.Plain)self.line_6.setLineWidth(4)self.line_6.setMidLineWidth(4)self.line_6.setObjectName("line_6")# 添加垂直分割线,并设置样式为Raised,表示有凸起显示的边框阴影:self.line_7 = QtWidgets.QFrame(self.centralwidget)self.line_7.setGeometry(QtCore.QRect(650, 70, 41, 151))self.line_7.setFrameShape(QtWidgets.QFrame.VLine)self.line_7.setFrameShadow(QtWidgets.QFrame.Raised)self.line_7.setLineWidth(4)self.line_7.setMidLineWidth(4)self.line_7.setObjectName("line_7")MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.label.setText(_translate("MainWindow", "水平分割线"))self.label_2.setText(_translate("MainWindow", "垂直分割线"))self.label_3.setText(_translate("MainWindow", "Sunken:"))self.label_4.setText(_translate("MainWindow", "Plain:"))self.label_5.setText(_translate("MainWindow", "Raised:"))self.label_6.setText(_translate("MainWindow", "Sunken"))self.label_7.setText(_translate("MainWindow", "Plain"))self.label_8.setText(_translate("MainWindow", "Raised"))if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()MainWindow.show()ui.setupUi(MainWindow)sys.exit(app.exec_())

运行结果如下:

2. 弹簧:QSpacerItem

PyQt5提供了两个弹簧控件,分别是HorizontalSpacer和VerticalSpacer,但这两个控件对应的类都是QSpacerItem类,水平和垂直主要通过宽度和高度(水平弹簧的默认宽度和高度分别是40、20,而垂直弹簧的默认宽度和高度分别是20、40)进行区分。

      QSpacerItem弹簧主要用在布局管理器中,用来使布局管理器中的控件布局更加合理。

示例:使用弹簧控件改变控件位置

在Qt Designer设计器中创建一个窗口,在窗口中添加一个VerticalLayout垂直布局管理器,并向该布局管理器中任意添加控件,默认都是从下往上排列。
在垂直布局管理器中添加控件的设计效果:

在垂直布局管理器中添加控件的运行效果:


      如果想要在垂直布局管理器中改变某个控件的位置,默认是无法改变的,那么怎么办呢?PyQt5提供了弹簧控件来方便开发人员能够根据自身需求更合理地摆放控件的位置。例如,通过应用弹簧对控件位置进行改动。

使用弹簧更改控件位置的设计效果:

使用弹簧更改控件位置的运行效果:

      弹簧控件只在设计窗口时显示,在实际运行时不显示。

4. 其他控件

除了前面的一些常用控件之外,PyQt5还提供了一些比较有特色的控件。

1. Dial:旋钮控件

Dial控件,又称为旋钮控件,它本质上类似于一个滑块控件,只是显示的样式不同。

Dial控件对应PyQt5中的QDial类。

QDial控件常用方法及说明

方法 说明
setFixedSize() 设置旋钮的大小
setRange() 设置表盘的数值范围
setMinimum() 设置最小值
setMaximum() 设置最大值
setNotchesVisible() 设置是否显示刻度

示例:使用旋钮控制标签中的字体大小

使用Dial控件实现与前面QSlider滑块设置标签中文字大小类似的功能。
完整代码如下:

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(402, 122)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")# 添加一个垂直布局管理器,用来显示文字self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)self.horizontalLayoutWidget.setGeometry(QtCore.QRect(130, 20, 251, 81))self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)self.horizontalLayout.setContentsMargins(0, 0, 0, 0)self.horizontalLayout.setObjectName("horizontalLayout")self.label = QtWidgets.QLabel(self.horizontalLayoutWidget)# 设置Label标签水平左对齐,垂直居中对齐self.label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)self.label.setObjectName("label")self.horizontalLayout.addWidget(self.label)# 添加Dial控件self.dial = QtWidgets.QDial(self.centralwidget)self.dial.setGeometry(QtCore.QRect(20, 20, 71, 71))self.dial.setMinimum(8)     # 设置最小值为8self.dial.setMaximum(72)    # 设置最大值为72self.dial.setNotchesVisible(True)     # 设置刻度self.dial.setObjectName("dial")MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)# 为旋钮控件绑定valueChanged信号,在值发生更改时发射self.dial.valueChanged.connect(self.setfontsize)# 定义槽函数,根据旋钮的值改变Label控件的字体大小def setfontsize(self):value = self.dial.value()     # 获取旋钮的值self.label.setFont(QtGui.QFont("楷体", value))    # 设置Label的字体和大小def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.label.setText(_translate("MainWindow", "敢想敢为"))if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()MainWindow.show()ui.setupUi(MinWindow)sys.exit(app.exec_())

运行程序,默认效果如图所示:当用鼠标拖改:

      变旋钮的刻度值时,Label标签中的文字大小也会发生改变:

2. 滚动条:QScrollBar

PyQt5提供了两个滚动条控件,分别是水平滚动条HorizontalScrollBar垂直滚动条VerticalScrollBar,但这两个滚动条控件对应的类都是QScrollBar类,这两个控件通过水平的或垂直的滚动条,可以扩大当前窗口的有效装载面积,从而装载更多的控件。

QScrollBar滚动条类的常用方法及说明

方法 说明
setMinimum() 设置滚动条最小值。
setMaximum() 设置滚动条最大值。
setOritentation()
  • 设置滚动条显示方向,取值如下:
  • Qt.Horizontal:水平滚动条;
  • Qt.Vertical:垂直滚动条。
setValue() 设置滚动条的值。
value() 获取滚动条的当前值。

QScrollBar滚动条类的常用信号及说明

信号 说明
信号 说明
valueChanged 当滚动条的值发生改变时发射该信号
sliderMoved 当用户拖动滚动条的滑块时发射该信号

将水平滚动条和垂直滚动条拖放到PyQt5窗口中的效果如图所示:

      滚动条控件通常与其他控件配合使用,如ScrollArea、TableWidget表格等,另外,也可以使用滚动条控件实现与滑块控件同样的功能,实际上,滚动条控件也是一种特殊的滑块控件

三、PyQt5高级控件的使用相关推荐

  1. ASP.NET Web程序设计 第三章 高级控件

    一.母版页与内容页(重点) 1.母版页(主控页)是以".master"为后缀名的特殊页面,用于实现页面统一布局. 2.母版页与普通页面的区别: 1)母版页不能直接访问,而普通页可以 ...

  2. Android的高级控件(自动提示文本框与下拉列表)

    一.高级控件与常用控件的区别:是否使用适配器 二.适配器 1.种类 ①.数组适配器 ArrayAdapter       new ArrayAdapter<String>(this,R.l ...

  3. Android高级控件----AdapterView与Adapter详解

    在J2EE中提供过一种非常好的框架--MVC框架,实现原理:数据模型M(Model)存放数据,利用控制器C(Controller)将数据显示在视图V(View)上.在Android中有这样一种高级控件 ...

  4. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第八章:高级控件

    本章介绍了App开发常用的一些高级控件用法,主要包括:如何使用下拉框及其适配器.如何使用列表 类视图及其适配器.如何使用翻页类视图及其适配器.如何使用碎片及其适配器等.然后结合本章所学 的知识,演示了 ...

  5. MFC高级控件RichEdit2.0的使用

    MFC高级控件RichEdit的使用 MFC高级控件RichEdit的使用 MFC控件设置焦点,实现回车后编辑框内容清空,焦点停留在该编辑框内 MFC高级控件RichEdit的使用 RichEdit控 ...

  6. Android 高级控件(七)——RecyclerView的方方面面

    Android 高级控件(七)--RecyclerView的方方面面 RecyclerView出来很长时间了,相信大家都已经比较了解了,这里我把知识梳理一下,其实你把他看成一个升级版的ListView ...

  7. 移动开发技术(Android)——实验5 Android高级控件的应用

    移动开发技术--实验5 Android高级控件的应用 一.实验目的 二.实验内容 1.Spinner.ListView控件与Adapter适配器(一) 2.Spinner.ListView控件与Ada ...

  8. 十四、windows窗体高级控件

    1 PictureBox控件 PictureBox控件可以显示来自位图.图标或者原文件,以及来自增强的元文件.Jpeg或GIF文件的图形.如果控件不足以显示整幅图像,则捡钱图像以适应控件的大小 usi ...

  9. android_高级控件_1

    有蛮久没更新了今天来记录一下android的高级控件 AutoCompleteTextView(自动补全): 开发过web项目的小伙伴们应该知道在web项目中实现自动补全是有多麻烦,在安卓开发中实现自 ...

最新文章

  1. Thinking in java 多线程导致数组越界崩溃的BUG
  2. Mob统计分析数据模型理解
  3. 百度安全入选中国工业互联网安全市场研究报告推荐服务商
  4. 新手小白Linux(Centos6.5)部署java web项目(mongodb4.0.2安装及相关操作)
  5. CGRect包含交错,边缘,中心的检测
  6. 计算机考试辽宁2020,报名辽宁2020年9月计算机考试流程
  7. Python DES
  8. golang mac 环境变量_Golang (Go语言) Mac OS X下环境搭建 环境变量配置 开发工具配置 Sublime Text 2...
  9. 使用强类型DataSet增加数据并获取自动增长的ID
  10. CorelDRAW暗角效果怎么做?
  11. 2021年中国人工智能市场发展现状
  12. 教师节感恩_在Excel中计算感恩节日期
  13. 使用数字证书配置IKEv2
  14. Boardcast receiver
  15. 北京办理居住证的全流程
  16. [MySQL] 运算符
  17. L1、L2正则化总结
  18. r语言ggplot2一夜多图_关于GGPLOT2出图里的一页多图模式
  19. Default encoder for format image2 (codec png) is probably disabled. Please choose an encoder manuall
  20. 汉字从拼音到文字的完整映射表

热门文章

  1. 【软工Work1】四则加减乘除混合运算(带括号、真分数)
  2. 最全的TypeScript学习指南
  3. 那些好用的iOS开发工具
  4. FreeSwitch呼入处理流程
  5. 苹果市场占有率_快手充值快快币苹果版
  6. typora显示版本过期,请下载最新版本,可是最新版本84块钱,咋办?
  7. MSRA显著性检测数据集
  8. 阿里云镜像站DNS——Linux配置方法
  9. The request was rejected because the URL contained a potentially malicious String “//“ 报错
  10. [转]PMP之挣值管理(PV、EV、AC、SV、CV、SPI、CPI)的记忆方法