PyQt5教程 :http://code.py40.com/face
教程翻译自:http://zetcode.com/gui/pyqt5/
PyQt5 的 核心API 以及 扩展应用(CSDN 学院收费视频):https://edu.csdn.net/course/play/9870/222942
pyqt5 - 对文本样式进行操作:https://www.cnblogs.com/XJT2018/p/9835262.html
setStyleSheet 用法:https://www.cnblogs.com/aheng123/p/5630761.html
Pyqt5 —— setStyleSheet 用法:https://blog.csdn.net/weixin_42066185/article/details/82225197
颜色代码查询,RGB 查询:http://tool.chinaz.com/tools/selectcolor.aspx
RGB颜色值转换成十六进制颜色码:https://www.sioe.cn/yingyong/yanse-rgb-16/
【第一节】PyQt5简介:http://code.py40.com/1948.html
【第二节】PyQt5基本功能:http://code.py40.com/1961.html
【第三节】PyQt5布局管理:http://code.py40.com/1995.html
【第四节】PyQt5菜单和工具栏:http://code.py40.com/1984.html
【第五节】PyQt5事件和信号:http://code.py40.com/2004.html
【第六节】PyQt5 对话框:http://code.py40.com/2009.html
【第七节】PyQt5控件:http://code.py40.com/2018.html
【第八节】PyQt5控件(II):http://code.py40.com/2026.html
【第九节】PyQt 拖拽:http://code.py40.com/2035.html
【第十节】PyQt5绘图:http://code.py40.com/2042.html
【第十一节】PyQt5自定义控件:http://code.py40.com/2049.html
【第十二节】PyQt5俄罗斯方块:http://code.py40.com/2052.html
PyQt5 说明
pyqt5是一套Python绑定Digia QT5应用的框架。它可用于Python 2和3。本教程使用Python 3。Qt库是最强大的GUI库之一。pyqt5的官方网站http://www.riverbankcomputing.co.uk/news。
pyqt5 做为 Python 的一个模块,它有 620 多个类和 6000 个函数和方法。这是一个跨平台的工具包,它可以运行在所有主要的操作系统,包括 UNIX,Windows,Mac OS。pyqt5 是双重许可。开发者可以在 GPL 和 商业许可 之间进行选择。
pyqt5 的类别分为几个模块,包括以下:
- QtCore
- QtGui
- QtWidgets
- QtMultimedia
- QtBluetooth
- QtNetwork
- QtPositioning
- Enginio
- QtWebSockets
- QtWebKit
- QtWebKitWidgets
- QtXml
- QtSvg
- QtSql
- QtTest
说明:
QtCore | 包含了核心的非 GUI 功能。 此模块用于处理时间、文件和目录、各种数据类型、流、URL、MIME类型、线程或进程。 |
QtGui | 包含类窗口系统集成、事件处理、二维图形、基本成像、字体和文本。 |
QtWidgets | 模块包含创造经典桌面风格的用户界面提供了一套UI元素的类。 |
QtMultimedia | 包含的类来处理多媒体内容和 API 来访问相机和收音机的功能。 |
QtBluetooth | 模块包含类的扫描设备和连接并与他们互动。描述模块包含了网络编程的类。 这些类便于 TCP 和 IP 和 UDP 客户端和服务器的编码,使网络编程更容易和更便携。 |
QtNetwork | 网络模块 |
QtPositioning | 包含类的利用各种可能的来源,确定位置,包括卫星、Wi-Fi、或一个文本文件。 |
Enginio | 模块实现了客户端库访问 Qt 云服务托管的应用程序运行时。 |
QtWebSockets | 模块包含实现 WebSocket 协议类。 |
QtWebKit | 包含一个基于 Webkit2 图书馆 Web 浏览器 实现类。 |
QtWebKitWidgets | 包含的类的基础 webkit1 ,用于 qtwidgets 应用 Web 浏览器的实现。 |
QtXml | 包含与 XML 文件的类。这个模块为 SAX 和 DOM API 提供了实现。 |
QtSvg | 模块提供了显示 SVG 文件内容的类。可伸缩矢量图形(SVG)是一种描述二维图形和图形应用的语言。 |
QtSql | 模块提供操作数据库的类。 |
QtTest | 包含的功能,使 pyqt5 应用程序的单元测试 |
pyqt5 不向后兼容 pyqt4。pyqt5 有几个显著的变化。将旧代码调整到新库并不困难。有几个大的改变如下:
- Python模块已经重组。一些模块已经删除(qtscript),有的被分割成子模块(QtGui,QtWebKit)。
- 新的模块作了详细的介绍,包括qtbluetooth,qtpositioning,或enginio。
- pyqt5只支持新型的信号和槽handlig。电话signal()或slot()不再支持。
- pyqt5不支持Qt的API被标记为过时或陈旧的任何部分在QT V5.0。
【第 1 节】 到 【第 4 节】演示代码
( 可以 把 __init__ 函数中的 注释逐个取消,然后运行程序看执行效果 ):
- # -*- coding: utf-8 -*-
- # @Author :
- # @File : main.py
- # @Software: PyCharm
- # @description : XXX
-
-
- import sys
-
- # QMainWindow 类提供了一个主要的应用程序窗口。
- # 你用它可以让应用程序添加状态栏,工具栏和菜单栏。
- from PyQt5.QtWidgets import QWidget, QMainWindow
-
- from PyQt5.QtWidgets import QApplication
- from PyQt5.QtWidgets import QDesktopWidget, QMessageBox, QLabel, QPushButton, QAction
- from PyQt5.QtWidgets import QAction, qApp
- from PyQt5.QtWidgets import QLineEdit, QTextEdit
- from PyQt5.QtWidgets import QHBoxLayout # horizontal 水平布局
- from PyQt5.QtWidgets import QVBoxLayout # vertical 垂直布局
- from PyQt5.QtWidgets import QGridLayout # Grid 网格布局
-
- from PyQt5.QtGui import QIcon
-
-
- # 如果不想一个一个 导入,可以 import *
- # from PyQt5.QtWidgets import *
-
-
- class MyForm1(QWidget):
- def __init__(self):
- super(MyForm1, self).__init__()
- # self._init_ui_1()
- # self._init_ui_2()
- # self._init_ui_3()
- # self._init_ui_4()
- self._init_ui_5()
- pass
-
- def center(self):
- """
- 控制窗口显示在屏幕中心的方法
- :return:
- """
- # 获得窗口
- qr = self.frameGeometry()
- # 获得屏幕中心点
- cp = QDesktopWidget().availableGeometry().center()
- # 显示到屏幕中心
- qr.moveCenter(cp)
- self.move(qr.topLeft())
-
- def _init_ui_1(self):
- """
- 重置大小,中心显示
- :return:
- """
- self.resize(1000, 600)
- self.center()
- self.show()
-
- def _init_ui_2(self):
- """
- 使用 绝对位置 布局元素位置
- :return:
- """
- lbl1 = QLabel('Zetcode', self)
- lbl1.move(15, 10)
-
- lbl2 = QLabel('tutorials', self)
- lbl2.move(35, 40)
-
- lbl3 = QLabel('for programmers', self)
- lbl3.move(55, 70)
-
- self.setGeometry(300, 300, 250, 150)
- self.setWindowTitle('Absolute')
- self.show()
-
- def _init_ui_3(self):
- """
- 使用布局 来 布局 元素位置
- :return:
- """
- btn_ok = QPushButton("OK")
- btn_cancel = QPushButton("Cancel")
-
- hbox = QHBoxLayout()
- hbox.addStretch(1)
- hbox.addWidget(btn_ok)
- hbox.addWidget(btn_cancel)
-
- vbox = QVBoxLayout()
- vbox.addStretch(1)
- vbox.addLayout(hbox)
-
- self.setLayout(vbox)
-
- self.setGeometry(300, 300, 300, 150)
- self.setWindowTitle('Buttons')
- self.show()
-
- def _init_ui_4(self):
- """
- 使用 网格布局 来 布局 元素位置
- :return:
- """
- grid = QGridLayout()
- self.setLayout(grid)
-
- names = [
- 'Cls', 'Bck', '', 'Close',
- '7', '8', '9', '/',
- '4', '5', '6', '*',
- '1', '2', '3', '-',
- '0', '.', '=', '+'
- ]
-
- positions = [(i, j) for i in range(5) for j in range(4)]
-
- for position, name in zip(positions, names):
-
- if name == '':
- continue
- button = QPushButton(name)
- grid.addWidget(button, *position)
-
- self.move(300, 150)
- self.setWindowTitle('Calculator')
- self.show()
-
- def _init_ui_5(self):
- """
- 网格布局 跨越 多行 或者 多列
- :return:
- """
- title = QLabel('Title')
- author = QLabel('Author')
- review = QLabel('Review')
-
- titleEdit = QLineEdit()
- authorEdit = QLineEdit()
- reviewEdit = QTextEdit()
-
- grid = QGridLayout()
- grid.setSpacing(10)
-
- grid.addWidget(title, 1, 0)
- grid.addWidget(titleEdit, 1, 1)
-
- grid.addWidget(author, 2, 0)
- grid.addWidget(authorEdit, 2, 1)
-
- grid.addWidget(review, 3, 0)
- grid.addWidget(reviewEdit, 3, 1, 5, 1)
-
- self.setLayout(grid)
-
- self.setGeometry(300, 300, 350, 300)
- self.setWindowTitle('Review')
- self.show()
-
- def closeEvent(self, event):
- """
- 重写关闭窗口事件
- :param event:
- :return:
- """
- reply = QMessageBox.question(
- self, 'Message', 'Are you sure close window ?',
- QMessageBox.Yes | QMessageBox.No, QMessageBox.No
- )
- if reply == QMessageBox.Yes:
- event.accept()
- else:
- event.ignore()
- pass
-
-
- class MyForm2(QMainWindow):
- """
- QMainWindow 类提供了一个主要的应用程序窗口。
- 你用它可以让应用程序添加状态栏,工具栏和菜单栏。
- """
-
- def __init__(self):
- super(MyForm2, self).__init__()
- # self._init_ui_6()
- # self._init_ui_7()
- # self._init_ui_8()
- self._init_ui_9()
-
- def _init_ui_6(self):
- """
- 状态栏
- :return:
- """
- self.statusBar().showMessage('Ready')
- self.setGeometry(800, 300, 250, 150)
- self.setWindowTitle('Statusbar')
- self.show()
-
- def _init_ui_7(self):
- """
- 菜单栏
- :return:
- """
- # QAction可以操作菜单栏,工具栏,或自定义键盘快捷键。
-
- # 创建一个事件和一个特定的图标和一个“退出”的标签。
- exitAction = QAction(QIcon('exit.png'), '&Exit', self)
- exitAction.setShortcut('Ctrl+Q') # 定义该操作的快捷键。
-
- # 创建一个鼠标指针悬停在该菜单项上时的提示。
- exitAction.setStatusTip('Exit application')
-
- # # 第三行创建一个鼠标指针悬停在该菜单项上时的提示。
- exitAction.triggered.connect(qApp.quit)
-
- self.statusBar()
-
- # 创建一个菜单栏
- menubar = self.menuBar()
- # 添加菜单
- fileMenu = menubar.addMenu('&File')
- # 添加事件
- fileMenu.addAction(exitAction)
-
- self.setGeometry(800, 300, 300, 200)
- self.setWindowTitle('Menubar')
- self.show()
-
- def _init_ui_8(self):
- """
- 工具栏
- :return:
- """
- exitAction = QAction(QIcon('exit24.png'), 'Exit', self)
- exitAction.setShortcut('Ctrl+Q')
- exitAction.triggered.connect(qApp.quit)
-
- self.toolbar = self.addToolBar('Exit')
- self.toolbar.addAction(exitAction)
-
- self.setGeometry(800, 300, 300, 200)
- self.setWindowTitle('Toolbar')
- self.show()
-
- def _init_ui_9(self):
- # 创建一个菜单条,工具栏和状态栏的小窗口
- textEdit = QTextEdit()
- self.setCentralWidget(textEdit)
-
- exitAction = QAction(QIcon('exit24.png'), 'Exit', self)
- exitAction.setShortcut('Ctrl+Q')
- exitAction.setStatusTip('Exit application')
- exitAction.triggered.connect(self.close)
-
- self.statusBar()
-
- menubar = self.menuBar()
- fileMenu = menubar.addMenu('&File')
- fileMenu.addAction(exitAction)
-
- toolbar = self.addToolBar('Exit')
- toolbar.addAction(exitAction)
-
- self.setGeometry(800, 300, 350, 250)
- self.setWindowTitle('Main window')
- self.show()
-
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- form_1 = MyForm1()
- form_2 = MyForm2()
- sys.exit(app.exec_())
- pass
点击产生一个新窗口:
- import sys
- from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton
-
-
- class Form1(QWidget):
-
- def __init__(self):
- super(Form1, self).__init__()
- self.setWindowTitle('From_1')
- self.resize(600, 300)
- self._init_ui()
- self.show()
-
- def close_window(self):
- """
- 点击按钮 将 窗体1 关掉
- :return:
- """
- self.close()
-
- def _init_ui(self):
- v_box = QVBoxLayout()
- self.btn_1 = QPushButton('btn_1: close Form_2')
- self.btn_2 = QPushButton('btn_2: show Form_2')
- v_box.addWidget(self.btn_1)
- v_box.addWidget(self.btn_2)
- self.setLayout(v_box)
-
-
- class Form2(QWidget):
-
- def __init__(self):
- super(Form2, self).__init__()
- self.setWindowTitle('From_2')
- self.resize(800, 400)
- self._init_ui()
-
- def display(self):
- """
- 显示窗体
- :return:
- """
- self.show()
-
- def _init_ui(self):
- h_box = QHBoxLayout()
- btn_3 = QPushButton('btn_3')
- btn_4 = QPushButton('btn_4')
- h_box.addWidget(btn_3)
- h_box.addWidget(btn_4)
- self.setLayout(h_box)
-
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- w1 = Form1()
- w2 = Form2()
- w1.show()
- w1.btn_1.clicked.connect(w1.close_window)
- w1.btn_2.clicked.connect(w2.display)
- app.exec_()
布局示例:
PyQt入门(五)— 布局:https://blog.csdn.net/qq_34710142/article/details/80875625
- from PyQt5 import QtWidgets
-
-
- class MyWindow(QtWidgets.QWidget):
-
- def __init__(self):
- super().__init__()
- self.setWindowTitle('嵌套布局示例')
-
- # 开始:
- wlayout = QtWidgets.QHBoxLayout() # 全局布局(1个):水平
-
- hlayout = QtWidgets.QHBoxLayout() # 局部布局(4个):水平、竖直、网格、表单
- vlayout = QtWidgets.QVBoxLayout()
- glayout = QtWidgets.QGridLayout()
- flayout = QtWidgets.QFormLayout()
-
- hlayout.addWidget(QtWidgets.QPushButton(str(1))) # 局部布局添加部件(例如:按钮)
- hlayout.addWidget(QtWidgets.QPushButton(str(2)))
- vlayout.addWidget(QtWidgets.QPushButton(str(3)))
- vlayout.addWidget(QtWidgets.QPushButton(str(4)))
- glayout.addWidget(QtWidgets.QPushButton(str(5)), 0, 0)
- glayout.addWidget(QtWidgets.QPushButton(str(6)), 0, 1)
- glayout.addWidget(QtWidgets.QPushButton(str(7)), 1, 0)
- glayout.addWidget(QtWidgets.QPushButton(str(8)), 1, 1)
- flayout.addWidget(QtWidgets.QPushButton(str(9)))
- flayout.addWidget(QtWidgets.QPushButton(str(10)))
- flayout.addWidget(QtWidgets.QPushButton(str(11)))
- flayout.addWidget(QtWidgets.QPushButton(str(12)))
-
- hwg = QtWidgets.QWidget() # 准备四个部件
- vwg = QtWidgets.QWidget()
- gwg = QtWidgets.QWidget()
- fwg = QtWidgets.QWidget()
-
- hwg.setLayout(hlayout) # 四个部件设置局部布局
- vwg.setLayout(vlayout)
- gwg.setLayout(glayout)
- fwg.setLayout(flayout)
-
- wlayout.addWidget(hwg) # 四个部件加至全局布局
- wlayout.addWidget(vwg)
- wlayout.addWidget(gwg)
- wlayout.addWidget(fwg)
-
- self.setLayout(wlayout) # 窗体本尊设置全局布局
-
-
- if __name__ == "__main__":
- import sys
-
- app = QtWidgets.QApplication(sys.argv)
- win = MyWindow()
- win.show()
- sys.exit(app.exec_())
效果:
布局 时 需要注意点
继承 QMainWindow 时布局界面 和 继承 QWidget 时 布局界面 是不一样的
1. 继承 QMainWindow 时 的界面布局
如何给QMainWindow正确地设置布局( C++ 示例 步骤)
- 第一步:创建一个QWidget实例,并将这个实例设置为 centralWidget:
QWidget *widget = new QWidget();
this->setCentralWidget(widget); - 第二部:创建一个主布局mainLayout,并把所需要的所有控件都往里面放(工具栏、菜单栏、状态栏除外):
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addWidget(...);
mainLayout->addLayout(...);
... - 第三步:将 widget 的布局设置为 mainLayout:
centralWidget()->setLayout(mainLayout);
//centralWidget()返回的是第一步创建的那个QWidget实例
继承 QMainWindow 时,需要设置 中心部件(即 主界面),如下面代码需要添加三行代码:
- main_widget = QWidget() # 界面 实例
- self.setCentralWidget(main_widget) # 设置 为 中心界面
- ......
- ......
- self.centralWidget().setLayout(v_box) # 设置中心界面的布局
根据 C++ 示例 步骤改成 python ,完整示例代码如下:
- import sys
-
- # QMainWindow 类提供了一个主要的应用程序窗口。
- # 你用它可以让应用程序添加状态栏,工具栏和菜单栏。
- from PyQt5.QtWidgets import QWidget, QMainWindow
-
- from PyQt5.QtWidgets import (
- QApplication, QDesktopWidget, QHBoxLayout, QVBoxLayout,
- QPushButton, QListView,
- )
-
-
- class LayoutDemoByQMainWindow(QMainWindow):
-
- def __init__(self):
- super(LayoutDemoByQMainWindow, self).__init__()
- self.resize(1000, 600) # 重置大小
- self._center_display() # 中心显示
- self.vertical_layout()
- self.show()
-
- def _center_display(self):
- """
- 控制窗口显示在屏幕中心的方法
- :return:
- """
- # 获得窗口
- qr = self.frameGeometry()
- # 获得屏幕中心点
- cp = QDesktopWidget().availableGeometry().center()
- # 显示到屏幕中心
- qr.moveCenter(cp)
- self.move(qr.topLeft())
-
- def vertical_layout(self):
- """
- 垂直布局
- :return:
-