Python PyQt5 教程

这篇博客详尽介绍了PyQt5,从基础的布局管理,包括QMainWindow和QWidget的区别,到事件和信号、对话框、控件、拖拽功能,再到绘图和自定义控件的实现。内容涵盖布局的多种方法,如QBoxLayout、QGridLayout、QFormLayout,还涉及到QSplitter和拖拽操作。此外,还展示了如何处理鼠标事件、绘制文本、颜色、画笔和笔刷。博客提供了丰富的代码示例,帮助读者深入理解PyQt5的使用。
摘要由CSDN通过智能技术生成

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++ 示例 步骤)

  1. 第一步:创建一个QWidget实例,并将这个实例设置为 centralWidget:
        QWidget *widget = new QWidget();
        this->setCentralWidget(widget);
  2. 第二部:创建一个主布局mainLayout,并把所需要的所有控件都往里面放(工具栏、菜单栏、状态栏除外):
        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->addWidget(...);
        mainLayout->addLayout(...);
        ...
  3. 第三步:将 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)
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值