PyQt5,第一个窗口

0.前言

Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架,是目前开发桌面应用程序主流框架。PyQt5是Qt框架的Python绑定,使用SIP绑定生成器构建。注意,Qt大部分模块为LGPL协议,但是PyQt5为GPL3。

开始学习前,我们先install PyQt5模块:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple PyQt5

PyQt的文档不是很全,可以参照PySide2的文档:https://doc.qt.io/qtforpython/ ,PySide2是Qt官方的Python绑定版本。

1.第一个窗口

我们先实现一个简单的窗口,再派生我们自己的窗口类。

import sys
from PyQt5.QtWidgets import QApplication,QWidget

if __name__=="__main__":
    #每个Qt应用程序必须创建一个Application对象
    #通过调用其exec_()运行事件循环,这样才能周期性的处理窗口的操作、绘制等事件。
    #sys.argv参数是一个列表,从命令行输入参数。
    app=QApplication(sys.argv)

    #QWidget是QtWidget框架组建的基类
    w=QWidget()
    #设置窗口大小
    w.resize(300,200)
    #设置窗口标题
    w.setWindowTitle("Hello World")
    #显示窗口
    w.show()

    #系统exit()方法确保应用程序干净的退出
    #这里exec_()方法有下划线,因为exec是一个Python关键字,所以用exec_()代替
    sys.exit(app.exec_())

2.信号槽简述

在Qt中,我们有一种替代回调技术的方法:我们使用信号和槽,这也是Qt的主要特性。发生特定事件时会触发对应信号,QObject对象有一个队列用来保存关联的信号槽,信号触发时会自动调用槽函数。Qt的类具有许多预定义的信号,我们在实际应用时也需要定义自己的信号,通过connect函数可以把信号关联到别的信号或者槽函数上,槽函数在Qt5中可以是任意可调用对象。信号和插槽机制是类型安全的:信号的参数列表必须与槽函数的参数列表匹配(槽函数参数个数可以比信号参数个数更少)。详情见文档:https://doc.qt.io/qt-5.12/signalsandslots.html

下面通过代码展示信号槽,我们创建两个按钮,一个用来关闭窗口,一个用来打印测试。

import sys
#qApp是QApplication的单例实例,如QCoreApplication::instance
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,qApp

#继承QWidget,增加一个按钮
class MyWidget(QWidget):
    def __init__(self, parent=None):
        #调用父类构造
        super().__init__(parent=parent)
        self.setWindowTitle("Hello World")
        self.resize(500,400)

        #创建一个布局来放按钮,Qt中使用parent参数来组织对象树父子关系
        vlayout=QVBoxLayout(self)
        #一个按钮
        self.closeBtn=QPushButton("Close",self)
        #按钮添加到布局
        vlayout.addWidget(self.closeBtn)
        #布局设置到Widget中,此处注释掉,已用self参数关联
        #self.setLayout(vlayout)

        #按钮点击信号,调用app的退出函数
        #槽函数可以是任意的可调用对象
        self.closeBtn.clicked.connect(qApp.quit)

        #另一个按钮
        self.printBtn=QPushButton("Print",self)
        vlayout.addWidget(self.printBtn)
        #lambda也是可调用对象,这里我们打印选中状态
        self.printBtn.setCheckable(True)
        self.printBtn.clicked.connect(lambda isCheck:print(isCheck))

if __name__=="__main__":
    app=QApplication(sys.argv)

    w=MyWidget()
    w.show()

    sys.exit(app.exec_())

3.事件简述

在Qt中,事件是从抽象QEvent类派生的对象,它们表示发生在应用程序内部或由于应用程序需要了解的外部活动而发生的事情。事件可以由QObject子类的任何实例接收和处理,但它们与小部件尤其相关。

根据事件的创建方式和分配方式,事件可以分为三类:

  • 窗口系统会生成自发事件( Spontaneous events )。它们被放入系统队列,并由事件循环一个接一个地处理。
  • 发布事件( Posted events )由Qt或应用程序生成。它们由Qt排队并由事件循环处理。
  • 发送事件( Sent events )是由Qt或应用程序生成的,但它们直接发送到目标对象。

当我们调用QApplication的 exec_() 函数时,应用程序进入Qt的事件循环。

Qt中的事件可以在五个不同级别上进行处理:

  • 重新实现特定的事件处理程序。( 如 paint 事件的 paintEvent() )
  • 重新实现 QObject 的 event() 函数。
  • 在 QObject 上安装事件过滤器。
  • 在qApp上安装事件过滤器。( qApp是QApplication的单例实例 )
  • 重新实现QApplication的 notify() 函数。

详情见文档:https://doc.qt.io/qt-5.12/eventsandfilters.html

下面通过代码展示事件处理程序怎么写,给resizeEvent改变窗口大小的处理程序加个打印语句。

import sys
from PyQt5.QtGui import QResizeEvent
from PyQt5.QtWidgets import QApplication,QWidget

#继承QWidget,增加resize改变窗口大小的事件处理
class MyWidget(QWidget):
    def __init__(self, parent=None):
        #调用父类构造
        super().__init__(parent=parent)
        self.setWindowTitle("Hello World")
        self.resize(500,400)

    def resizeEvent(self,event):
        #super().resizeEvent(event)
        #打印尺寸
        print(event.size())

if __name__=="__main__":
    app=QApplication(sys.argv)

    w=MyWidget()
    w.show()

    sys.exit(app.exec_())

4.参考

Qt信号槽文档:https://doc.qt.io/qt-5.12/signalsandslots.html

Qt事件系统文档:https://doc.qt.io/qt-5.12/eventsandfilters.html

Qt事件处理文档:https://doc.qt.io/archives/qq/qq11-events.html

PyQt5文档:https://www.riverbankcomputing.com/static/Docs/PyQt5/introduction.html

PyQt5教程:http://code.py40.com/1961.html

发布了106 篇原创文章 · 获赞 31 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/gongjianbo1992/article/details/104342738