文章首发个人博客:http://zmister.com
Python GUI教程(一):在PyQt5中创建第一个GUI图形用户界面
Python GUI教程(二):添加窗口小部件到图形用户界面GUI中
Python GUI教程(三):在GUI窗口中进行布局管理
Python GUI教程(四):安装并使用Qt设计师设计Python GUI
Python GUI教程(五):通过Qt设计师在GUI中添加窗口部件
Python GUI教程(六):使用Qt设计师进行窗口布局
Python GUI教程(七):转换qt设计师的ui代码为Python代码
Python GUI教程(八):在主窗口中调用对话框
Python GUI教程(九):从UI文件中解耦Python代码
Python GUI教程(十):创建一个复杂的GUI
Python GUI教程(十一):使用多线程保持GUI的响应
Python GUI教程(十二):使用拖放控件
Python GUI教程(十三):在GUI中使用pyqtgraph绘图库
本篇将会涉及:
- 构建一个更加复制的GUI
- 在选项卡部件中应用多个层级
- 添加一个树部件和一个日历部件
- 使用一个刻度盘部件来控制一个LCD显示器部件上的数字
- 连接刻度盘部件和LCD部件到一个单选按钮上
- 使用一个单选按钮来更新进度栏部件
延续上一篇的解耦思想,我们使用Qt设计师创建一个基本的包含各个部件的图形窗口,再在逻辑代码中对图形窗口进行调用和操作。
创建一个复杂的GUI
我们使用Qt设计师创建一个稍显复杂的GUI。其中包括:
- 两个选项卡TabWidgets
- 两个子选项卡TabWidgets
- 一个日期部件DateEdit
- 一个日历部件CalendarWidget
- 一个树形部件TreeWidget
- 一个组盒子GroupBox
- 三个单选按钮RadioButton
- 一个字体选择盒子FontComboBox
- 一个Lable标签
- 一个进度条progressBar
- 一个刻度盘Dial
- 一个LCD数据显示器LcdNumber
所有的步骤通过Qt设计师的拖拽就可以完成。
创建主选项卡
新建一个主窗口,拖拽TabWidget部件到主窗口中:
![](https://img.haomeiwen.com/i38544/ac412f77011fed4c.gif)
在选项卡1中创建一个子选项卡
继续使用TabWidget部件,在选项卡1中创建一个子选项卡:
![](https://img.haomeiwen.com/i38544/1341db8af539b23b.gif)
在子选项卡1中添加一个树部件
我们继续使用TreeWidget部件,在刚刚创建的子选项卡1中创建一个树,并添加一些信息:
![](https://img.haomeiwen.com/i38544/f6dd26e763822c14.gif)
在子选项卡2中添加日期和日历部件
现在切换到子选项卡2中,我们使用DateEdit部件和CalendarWidget部件,在子选项卡2中添加一个日期修改框和一个日历框,采用垂直布局:
![](https://img.haomeiwen.com/i38544/5dd396cdc402bed5.gif)
在选项卡2中添加按钮组
选项卡1已经构建好了,现在切换到选项卡2。
我们先使用GroupBox部件在创建一个组部件,然后在其中添加三个PushButton部件:
![](https://img.haomeiwen.com/i38544/d6007d5550b83876.gif)
在选项卡2中添加刻度和LCD部件
我们再在选项卡2中添加一个刻度盘和LCD显示器,放置在一个组部件中:
![](https://img.haomeiwen.com/i38544/1301276bed4292eb.gif)
在选项卡2中添加一个字体选择器
接着,使用FontComboBox部件和Label部件,在选项卡2中添加一个字体选择器和文本显示:
![](https://img.haomeiwen.com/i38544/aeb84d741953a250.gif)
在选项卡2中添加一个进度栏
最后,我们使用ProcessBar部件在选项卡2中添加一个进度栏:
![](https://img.haomeiwen.com/i38544/606c249ca503d8fd.gif)
这样就完成了整个GUI的图形界面设计。
接下来,我们创建信号/槽来实现GUI的事件响应。
构建信号/槽
转换UI文件为Python文件
我们首先转换设计好的UI文件为Python文件,按照之前的解耦思想,将界面代码与逻辑代码分离。
![](https://img.haomeiwen.com/i38544/496c845ac41ee38d.gif)
转换UI文件后,新建一个Python文件,引入转换为Python代码的GUI窗口:
# coding:utf-8
from PyQt5 import QtCore,QtWidgets,QtGui
from GUI import complex
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = complex.Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
运行一下,看是否正常:
![](https://img.haomeiwen.com/i38544/d423f3ac1fc211d6.gif)
新建一个逻辑类
为了便于操作,我们创建一个新类MainWindow,将程序的主循环放入其中,其余的逻辑功能以类的方法的方式添加:
# coding:utf-8
# 州的先生 zmister.com Python GUI教程
from PyQt5 import QtCore,QtWidgets,QtGui
from GUI import complex
import sys
class MainWindow(object):
def __init__(self):
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = complex.Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
if __name__ == "__main__":
MainWindow()
实现日历选择同步到日期选择器
我们在选项卡1的子选项卡2中构建了一个日期修改器和一个日历。
我们需要在日历上对日期进行点击的时候,日期修改器上同步显示我们选择的日期。
我们在MainWindow()类中,新建一个update_date()方法,用于设置日期修改器的数值:
def update_date(self):
self.ui.dateEdit.setDate(self.ui.calendarWidget.selectedDate())
再新建一个update_calendar()方法,用于设置点击日历的信号/槽,将其响应到日期修改器上:
def update_calendar(self):
self.ui.calendarWidget.selectionChanged.connect(self.update_date)
完整的代码如下:
# coding:utf-8
# 州的先生 zmister.com Python GUI教程
from PyQt5 import QtCore,QtWidgets,QtGui
from GUI import complex
import sys
class MainWindow(object):
def __init__(self):
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
self.ui = complex.Ui_MainWindow()
self.ui.setupUi(MainWindow)
self.update_date()
self.update_calendar()
MainWindow.show()
sys.exit(app.exec_())
# 修改日期修改器数值
def update_date(self):
self.ui.dateEdit.setDate(self.ui.calendarWidget.selectedDate())
# 日历信号槽
def update_calendar(self):
self.ui.calendarWidget.selectionChanged.connect(self.update_date)
if __name__ == "__main__":
MainWindow()
这样,我们点击了日历上的一个日期,日期修改器上就会显示我们点击日期。
![](https://img.haomeiwen.com/i38544/8ea321fb63d54c99.gif)
实现LCD显示器数字跟随刻度盘变化
我们在组合子部件中放置了一个Dial刻度盘和LCDNumber显示器。
我们可以设置LCD显示器上的数字跟随着刻度盘的变化而变化。
同样是创建两个方法:
# 设置LCD数字
def set_lcd(self):
self.ui.lcdNumber.display(self.ui.dial.value())
# 刻度盘信号槽
def set_dial(self):
self.ui.dial.valueChanged['int'].connect(self.set_lcd)
一个用来设置LCD显示器的数字,一个用来响应刻度盘的信号。
![](https://img.haomeiwen.com/i38544/7a33a19e66f7de43.gif)
实现按钮控制进度栏
我们在选项卡2中放置了3个单选按钮,和一个进度条,现在我们让单选按钮来控制进度栏的进度。其中,第一个按钮是默认选项,第二个按钮用来重置清零进度栏,第三个按钮用来根据LCD上的数字来更新。
设置第二个按钮清零进度栏,新建一个方法:
def zero_process(self):
self.ui.radioButton_2.clicked.connect(self.ui.progressBar.reset)
![](https://img.haomeiwen.com/i38544/037c31eadad439b3.gif)
设置第三个按钮的功能,新建两个方法:
# 更新进度栏
def update_process(self):
value = self.ui.lcdNumber.value()
self.ui.progressBar.setValue(value)
# 点击按钮3
def click_radio3(self):
self.ui.radioButton_3.clicked.connect(self.update_process)
![](https://img.haomeiwen.com/i38544/35c985dd3f9f6bd9.gif)
更新字体选择
我们还在选项卡2中放置了一个字体选择部件和一个label标签部件,我们可以设置选择了某个字体,就显示在label标签上。
def set_font(self):
self.ui.fontComboBox.activated['QString'].connect(self.ui.label.setText)
![](https://img.haomeiwen.com/i38544/0808cdae60f15aa2.gif)
这样,一个稍显复杂的GUI就完成了。
网友评论