python使用Qt实现GUI编程

文章目录

  • python使用Qt实现GUI编程
      • 知识点
      • 流程
    • 过程
      • Qt 安装
        • pip安装
      • 创建窗口
      • 2.3 信号与槽
      • 2.4 工具栏与菜单
      • 2.5 窗口部件
      • 2.6 布局
        • 2.6.1 垂直布局
        • 2.6.2 水平布局
        • 2.6.3 网格布局
      • 2.7 对话框

基于 Python 3 和 PyQt 5 来认识 GUI 编程

知识点

以下知识点:

  • 使用 Qt 创建窗口
  • Qt 的信号与槽机制
  • Qt 各个组件的使用

流程

流程如下:

  • Qt 安装
  • 创建窗口
  • 信号与槽
  • 工具栏与菜单
  • 窗口部件
  • 布局
  • 对话框

过程

Qt 安装

Qt 是一个跨平台的 C++ 应用程序开发框架。广泛用于开发 GUI 程序,这种情况下又被称为部件工具箱。也可用于开发非 GUI 程序,比如控制台工具和服务器

pip安装

使用支持的Python版本

pip install PyQt5

创建窗口

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *import sysclass MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')# 设置标签label = QLabel('Welcome to Shiyanlou!')# 设置标签显示在中央label.setAlignment(Qt.AlignCenter)self.setCentralWidget(label)# 创建应用实例,通过 sys.argv 传入命令行参数
app = QApplication(sys.argv)
# 创建窗口实例
window = MainWindow()
# 显示窗口
window.show()
# 执行应用,进入事件循环
app.exec_()

这里需要说明的是 Qt 的执行机制。 Qt 的程序通过创建 QApplication 类实例来调用 app.exec_ 方法进入事件循环。此时程序一直在循环监听各种事件并把它们放入消息队列中,在适当的时候从队列中取出处理。

2.3 信号与槽

Qt 中每种组件都有所谓的信号槽(slot)机制。可用来将信号与相应的处理函数进行连接绑定。

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *import sysclass MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')# 设置标签label = QLabel('Welcome to Shiyanlou!')# 设置标签显示在中央label.setAlignment(Qt.AlignCenter)self.setCentralWidget(label)def _my_func(self, s='my_func', a=100):dic = {'s': s, 'a': a}print(dic)# 创建应用实例,通过 sys.argv 传入命令行参数
app = QApplication(sys.argv)
# 创建窗口实例
window = MainWindow()
# 显示窗口
window.show()
# 执行应用,进入事件循环
app.exec_()

以上主要只给出了部分新添加的代码,原有的代码统一使用 ... 略过。

这里将 QMainWindow 的信号 windowTitleChanged_my_func 槽函数相绑定,当窗口标题被更改的信号发出的时候便会触发函数 _my_func 进行处理。

其中在自定义函数 _my_func 中允许设置任意多个参数。

运行上方程序。

根据打印出来的字典键值可以发现 windowTitleChanged 信号在被触发的时候向处理函数 _my_func 传递了一个参数也就是窗口标题。当然也有办法忽略这个值,就是采用 lamda 产生式。其原理就是通过 lamda 产生式的参数 x 捕获标题字符串,然后将 x 废弃不用,从而避免标题传入 _my_func

修改如下:

...
self.windowTitleChanged.connect(lambda x: self._my_func('Shiyanlou', 666))
...

运行结果。

为了更加直观地理解信号与槽,我们进一步修改代码,通过创建按钮响应按钮事件来展示信号与槽机制。

...
class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')# 添加布局layout = QHBoxLayout()# 创建按钮for i in range(5):button = QPushButton(str(i))# 将按钮按压信号与自定义函数关联button.pressed.connect(lambda x=i: self._my_func(x))# 将按钮添加到布局中layout.addWidget(button)# 创建部件widget = QWidget()# 将布局添加到部件widget.setLayout(layout)# 将部件添加到主窗口上self.setCentralWidget(widget)# 自定义的信号处理函数def _my_func(self, n):print('click button %s' % n)
...

另外 Qt 还支持自定义信号,可以通过创建 pyqtSignal 对象实例来定义信号对象。

...
class MainWindow(QMainWindow):# 自定义信号my_signal = pyqtSignal(str)def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')button = QPushButton('Click me!')button.pressed.connect(self._click_button)# 将自定义信号与相应的槽函数连接self.my_signal.connect(self._my_func)# 将部件添加到主窗口上self.setCentralWidget(button)# 自定义的信号处理函数def _click_button(self):# 当按钮被点击的时候将发出信号 my_signalself.my_signal.emit('shiyanlou')def _my_func(self, s):print(s)
...

以上过程实际上就是将按钮按压信号与 _click_button 槽关联,而一旦调用了 _click_button 函数之后又会触发 my_signal 信号,继而调用 my_signal 信号的槽进行处理。

上述调用过程实际上没有任何意义,仅仅只是为了展示 Qt 具备有自定义信号的功能。

2.4 工具栏与菜单

通常我们使用的软件窗口顶部还会有一条工具栏或者菜单栏。

可以使用 Qt 提供的 QToolBar 创建工具栏。

...
class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')# 设置标签label = QLabel('Welcome to Shiyanlou!')# 设置标签显示在中央label.setAlignment(Qt.AlignCenter)# 添加标签到主窗口self.setCentralWidget(label)# 创建工具栏tb = QToolBar('Tool Bar')# 添加工具栏到主窗口self.addToolBar(tb)
...

由于我们尚未给工具栏添加任何实际功能,所以工具栏只能看到一条空白的横杆。

接下来我们为工具栏添加实体按钮,并在窗口底部显示提示信息

下面是图标下载地址:

https://labfile.oss.aliyuncs.com/courses/705/icons.zip
...
class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')# 设置标签label = QLabel('Welcome to Shiyanlou!')# 设置标签显示在中央label.setAlignment(Qt.AlignCenter)# 添加标签到主窗口self.setCentralWidget(label)# 创建工具栏tb = QToolBar('Tool Bar')# 设置工具栏中按钮的大小tb.setIconSize(QSize(16, 16))# 添加工具栏到主窗口self.addToolBar(tb)# 添加按钮动作,并加载图标图像button_action = QAction(QIcon('icons/penguin.png'), 'Menu button', self)# 设置状态栏提示button_action.setStatusTip('This is menu button')button_action.triggered.connect(self.onButtonClick)button_action.setCheckable(True)# 添加到工具栏tb.addAction(button_action)# 为主窗口设置状态栏self.setStatusBar(QStatusBar(self))def onButtonClick(self, s):print(s)
...

接下来为应用添加菜单栏。

...
class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):...# 添加菜单栏mb = self.menuBar()# 禁用原生的菜单栏mb.setNativeMenuBar(False)# 添加 “文件” 菜单file_menu = mb.addMenu('&File')# 为文件菜单添加动作file_menu.addAction(button_action)
...

当然我们还可以实现二级菜单。

...
class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):...# 添加新的菜单选项button_action2 = QAction('C++', self)button_action3 = QAction('Python', self)button_action2.setCheckable(True)button_action3.setCheckable(True)button_action2.triggered.connect(self.onButtonClick)button_action3.triggered.connect(self.onButtonClick)# 添加菜单栏mb = self.menuBar()# 禁用原生的菜单栏mb.setNativeMenuBar(False)# 添加 “文件” 菜单file_menu = mb.addMenu('&File')# 为文件菜单添加动作file_menu.addAction(button_action)# 为菜单选项添加分隔符file_menu.addSeparator()# 添加二级菜单build_system_menu = file_menu.addMenu('&Build System')build_system_menu.addAction(button_action2)build_system_menu.addSeparator()build_system_menu.addAction(button_action3)
...

2.5 窗口部件

Qt 还有一个强大的部件类 QWidgets ,基于这个类派生出很多其它小部件,比如 DialSliderCheckBox 等等。由于部件太多了,这里只是简单做一统一展示,如果有需要深入学习某一部件再参考 官方文档。

...
class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')# 定义布局layout = QVBoxLayout()# 展示的部件列表widgets = [QCheckBox,QComboBox,QDateEdit,QDateTimeEdit,QDial,QDoubleSpinBox,QFontComboBox,QLCDNumber,QLineEdit,QProgressBar,QPushButton,QRadioButton,QSlider,QSpinBox,QTimeEdit]# 将部件添加到列表中for item in widgets:layout.addWidget(item())widget = QWidget()widget.setLayout(layout)self.setCentralWidget(widget)
...

2.6 布局

Qt 支持多种控件布局方式,主要有:

  • 垂直布局
  • 水平布局
  • 网格布局

当然这些布局方式之间也都支持混合嵌套使用。

2.6.1 垂直布局

为了更加直观的看到布局效果,我们这里定义了一个新类 Color 继承自 QWidget 用于显示色块。

...
# 用于显示色块
class Color(QWidget):def __init__(self, color, *args, **kwargs):super().__init__(*args, **kwargs)self.setAutoFillBackground(True)palette = self.palette()palette.setColor(QPalette.Window, QColor(color))self.setPalette(palette)class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')colors = ['red', 'green', 'blue', 'yellow']# 水平布局layout = QVBoxLayout()for color in colors:layout.addWidget(Color(color))widget = QWidget()widget.setLayout(layout)self.setCentralWidget(widget)
...

2.6.2 水平布局

知道了垂直布局之后,水平布局也相当简单,就是将 QVBoxLayout 修改为 QHBoxLayout

2.6.3 网格布局

...
class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')colors = ['red', 'green', 'blue', 'yellow']# 网格布局layout = QGridLayout()for i, color in enumerate(colors):for j in range(len(colors)):layout.addWidget(Color(color), i, j)widget = QWidget()widget.setLayout(layout)self.setCentralWidget(widget)
...

2.7 对话框

...
# 自定义对话框
class CustomDialog(QDialog):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.setWindowTitle('New Dialog')# 添加按钮选项QBtn = QDialogButtonBox.Ok | QDialogButtonBox.CancelbuttonBox = QDialogButtonBox(QBtn)buttonBox.accepted.connect(self.accept)buttonBox.rejected.connect(self.reject)layout = QVBoxLayout()layout.addWidget(buttonBox)self.setLayout(layout)class MainWindow(QMainWindow):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 设置窗口标题self.setWindowTitle('My First App')# 设置标签label = QLabel('Welcome to Shiyanlou!')# 设置标签显示在中央label.setAlignment(Qt.AlignCenter)# 添加标签到主窗口self.setCentralWidget(label)# 添加按钮动作,并加载图标图像button_action = QAction('New dialog', self)button_action.triggered.connect(self.onButtonClick)# 添加菜单栏mb = self.menuBar()# 禁用原生的菜单栏mb.setNativeMenuBar(False)# 添加 “文件” 菜单file_menu = mb.addMenu('&File')# 为文件菜单添加动作file_menu.addAction(button_action)def onButtonClick(self, s):# 创建对话框dlg = CustomDialog(self)# 运行对话框,这一步非常重要!!!dlg.exec_()
...

上面我们大概了解了使用 Qt 进行 GUI 编程的流程,也粗略接触了 Qt 各个控件,但是这个要作为 Qt 入门还远远不够,因为 Qt 内容实在太多了,要继续深入学习

python使用Qt实现GUI编程相关推荐

  1. python qt gui快速编程 pdf_翻译:《用python和Qt进行GUI编程》——介绍

    介绍: 这本书讲的是如何利用Python和Qt来开发GUI应用程序的.仅仅需要一点点必备的知识:你可以使用一些面相对象的语言来编程,例如C++,C#,java或者python等等.在富文本编辑的那些章 ...

  2. Python基于tkinter的GUI编程讲座

    Python基于tkinter的GUI编程讲座 图形用户界面(GUI.Graphical User Interface)是基于图形的界面,windows就是一个图形用户界面的操作系统,而DOS是基于字 ...

  3. 黑白棋算法简单实现与基于Qt的GUI编程的综合应用

    一.序言: 最近学习了Qt的界面编程,包括了QObject.QWidget.QIODevice.QMessageBox.QTcpSockt.QTcpServer.QFile.QFileInfo.QDa ...

  4. Python 基于tkinter的GUI编程

    tkinter是Python的标准GUI库 加载tkinter模块 Tk():创建应用程序主窗口 tkinter控件(组件.窗口部件) Label控件(标签) 示例代码 **(文本显示)** 示例代码 ...

  5. Qt的gui编程是,点击一次button出现两次action

    点击button,动作执行两次, 原因是有两个connect,一个是自己写的代码 connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(o ...

  6. Python QtGUI与数据可视化编程(一)想写GUI程序?来试试Python Qt吧!

    ✅作者简介:大家好我是五维星空,目前是某国企的一名Java全栈程序员,热爱技术.喜欢代码,希望我的文章能给大家带来收获. ✅个人主页:五维星空的csdn博客 ✅系列专栏:Python QtGUI与可视 ...

  7. Python GUI编程-了解相关技术[整理]

    Python GUI编程-了解相关技术[整理] 我们可以看到,其实python进行GUI开发并没有自身的相关库,而是借用第三方库进行开发.tkinter是tcl/tk相关,pyGTK是Gtk相关,wx ...

  8. linux 移除python_第16 p,PYthon中的用户交互,Python GUI编程

    大家好,我是杨数Tos,这是<从零基础到大神>系列课程的第16篇文章,第二阶段的课程:Python基础知识:PYthon中的用户交互.Python GUI编程实现方式介绍. 学习本课程,建 ...

  9. pyqt5示例_木辛老师的编程课堂:Python和Qt第一讲之初识PyQt5

    让我们初步认识一下PyQt5,了解一下它能给我们带来的强大功能吧 请点击右上角"关注"按钮关注我们哟:跟着木辛老师学习Python编程知识,变身快乐的编程达人吧~ PyQt简介 在 ...

最新文章

  1. java统计分析_数据统计(java实现)
  2. 神策数据罗彦博:如何正确使用漏斗分析提升转化?
  3. solr 6.5.1 创建core失败的原因 Can‘t find resource ‘solrconfig.xml‘
  4. java+icepdf+下载_Java使用icepdf将pdf文件按页转成图片
  5. pycharm 配置设置远程调试【远程解释器】
  6. 83.均衡策略:round-robin
  7. java中的linked_为Java实现LinkedArray
  8. Shell脚本应用之服务启动脚本
  9. 《JSjQuery 交互式web前端开发》(四)判断和循环
  10. md文件转换为pdf文件(带目录和不带目录简捷操作)
  11. wangeditor富文本编辑器的复制word到浏览器发生乱码
  12. 华为OceanStor Pacific斩获IO500榜单第二,数据存储的时与势
  13. 计算机科学与技术有几大类,计算机科学与技术类包括哪些专业
  14. 微信公众号打开网页自动登陆配置
  15. ps一点等于多少厘米_请问PS中“像素”和“厘米”是肿么换算的?
  16. 【something】简单的平均脸制作
  17. 输入scor为80结果实验
  18. 数学建模学习笔记(1):层次分析法(AHP)(附有详细使用步骤)
  19. 如何将pdf中一些特定页提取存储在另一个pdf中
  20. 电商企业营销案例方案:2019年618大促用红包推广引流

热门文章

  1. Nginx 服务安装搭建
  2. 【显示器】关于自制显示器的两三事 其二
  3. 结转损益时数量金额核算的会计科目出错怎么办?
  4. datasheet阅读方法及datasheet下载网站
  5. 零基础怎么入门python
  6. 边缘识别+轮廓识别+边框+二值化
  7. 请给我发邮件,不要发微信
  8. SQL \G 实现垂直显示结果
  9. PyTorch | 手动实现线性回归
  10. Java运行程序找不到ODBC驱动