事件介绍

事件的处理机制非常的复杂,属于PyQt底层的事,不必我们关心,学会使用就行。如果说事件是用来创建窗口,那么信号与槽就是用来对这个控件进行处理。事件属于低级的处理方式,信号与槽是高级的处理方式,一般信号与槽处理不了的问题,再使用事件处理。信号与槽功能强大使用简单但是不能解决所有的问题,事件使用麻烦但是可以处理全部的问题。事件的处理主要是重载类方法,信号与槽的处理主要是绑定、发送以及处理。

事件

  1. 重写mousePressEvent,keyPressEvent,paintEvent等方法,最常用(控件级)

  2. 重写QObject.event方法,一般在PyQt没有提供该事件的处理方法时使用(控件级)

  3. 安装事件过滤器:如果对QObject调用installEventFilter,相当于对这个QObject对象添加了一个过滤器。对于QObject的全部事件来说,都会先经过过滤器的处理,在过滤器里面就可以进行我们自己的处理,比如修改丢弃等,慎用,因为会处理所有的事件,会降低效率(控件级)

  4. 在QApplication中安装事件过滤器:比QObject的过滤器更强大,对所有的QObject的所有事件进行过滤,且第一时间捕获。事件的过滤先经过QApplication的处理再进过QObject的处理,必须慎用(应用级)

  5. 重写QApplication的notify方法,要想在任何事件被处理之前捕获事件,唯一的方法就是重写QApplication的notify方法,一般只在调试中使用(应用级)

 事件处理流程(紫色部分是应用级处理,绿色部分是对象级处理)

例子

import sys

from PyQt5.QtCore import QEvent
from PyQt5.QtWidgets import QApplication, QWidget class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__() def mousePressEvent(self, mouseEvent):
print('MyWidget.mousePressEvent')
return QWidget.mousePressEvent(self, mouseEvent) def event(self, event):
if event.type() == QEvent.MouseButtonPress:
print('MyWidget.event')
return QWidget.event(self, event) def eventFilter(self, object, event):
if event.type() == QEvent.MouseButtonPress:
print('MyWidget.eventFilter')
return QWidget.eventFilter(self, object, event) class MyQApplication(QApplication):
def __init__(self, param):
super(MyQApplication, self).__init__(param) def notify(self, object, event):
if event.type() == QEvent.MouseButtonPress:
print('MyQApplication.notify')
return QApplication.notify(self, object, event) def eventFilter(self, object, event):
if event.type() == QEvent.MouseButtonPress:
print('MyQApplication.eventFilter')
return QApplication.eventFilter(self, object, event) if __name__ == '__main__':
app = MyQApplication(sys.argv)
app.installEventFilter(app)
w = MyWidget()
w.installEventFilter(w)
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())

信号与槽

信号与槽是PyQt的核心机制,也是对象与对象之间的通信方法。信号与槽函数的对应方式是多对多,且信号可以连接信号。除了控件默认的信号外,可以自己定义和实现信号。

信号定义:

mySignal = pyqtSignal([param])

连接信号到槽:

mySignal.connect(handlerFunc)

发送信号:

mySignal.emit([param])

断开信号与槽:

mySignal.disconnect(handlerFunc)

例子:自定义信号并实现与槽的链接

import sys
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
mySignal = pyqtSignal() def __init__(self):
super(MyWidget, self).__init__()
button = QPushButton(self)
button.setText('点我')
button.clicked.connect(self.buttonClicked)
self.mySignal.connect(self.mySignalHandler) def buttonClicked(self):
print('button clicked emit and handler')
self.mySignal.emit() def mySignalHandler(self):
print('my signal emit and handler') if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())

信号与槽高级玩法

信号重载

import sys
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
# 无参数信号
mySignal_no_aram = pyqtSignal()
# 带一个整型参数信号
mySignal_int = pyqtSignal(int)
# 带一个整型或字符串信号
mySignal_int_or_str = pyqtSignal([int], [str])
# 带两个参数,int和srt 或 str和str
mySignal_two_param = pyqtSignal([int, str], [str, str]) def mySignal_no_aram_handler(self):
print('mySignal_no_aram_handler') def mySignal_int_handler(self):
print('mySignal_int_handler') def mySignal_int_or_str_int_handler(self):
print('mySignal_int_or_str_int_handler') def mySignal_int_or_str_str_handler(self):
print('mySignal_int_or_str_str_handler') def mySignal_two_param_int_str_handler(self):
print('mySignal_two_param_int_str_handler') def mySignal_two_param_str_str_handler(self):
print('mySignal_two_param_str_str_handler') def __init__(self):
super(MyWidget, self).__init__()
button = QPushButton(self)
button.setText('点我')
button.clicked.connect(self.onClicked) # 绑定信号到槽函数
self.mySignal_no_aram.connect(self.mySignal_no_aram_handler)
self.mySignal_int.connect(self.mySignal_int_handler)
self.mySignal_int_or_str[int].connect(self.mySignal_int_or_str_int_handler)
self.mySignal_int_or_str[str].connect(self.mySignal_int_or_str_str_handler)
self.mySignal_two_param[int, str].connect(self.mySignal_two_param_int_str_handler)
self.mySignal_two_param[str, str].connect(self.mySignal_two_param_str_str_handler) def onClicked(self):
# 发送信号
self.mySignal_no_aram.emit()
self.mySignal_int.emit(1)
self.mySignal_int_or_str[int].emit(2)
self.mySignal_int_or_str[str].emit('abc')
self.mySignal_two_param[int, str].emit(3, 'def')
self.mySignal_two_param[str, str].emit('abc', 'def') if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())

使用自定义参数

import sys
from functools import partial
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
button1 = QPushButton(self)
button1.setText('button1')
button1.move(10, 10)
button2 = QPushButton(self)
button2.setText('button2')
button2.move(10, 50) # button1.clicked.connect(lambda: self.onClicked(button1))
# button2.clicked.connect(lambda: self.onClicked(button2))
# 等价
button1.clicked.connect(partial(self.onClicked, button1))
button2.clicked.connect(partial(self.onClicked, button2)) def onClicked(self, btn):
print("%s" % btn.text()) if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())

使用装饰器定义信号与槽

import sys
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
button = QPushButton(self)
button.setText('点击') # 设置发送者名称
button.setObjectName('button')
# 实现绑定
QtCore.QMetaObject.connectSlotsByName(self) # 槽函数命名规则:on_发送者名称_发射信号名称(self, param)
@QtCore.pyqtSlot()
def on_button_clicked(self):
print('you clicked button') if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())

PyQt5事件处理的更多相关文章

  1. Ubuntu 14.04下搭建Python3.4 + PyQt5.3.2 + Eric6.0开发平台

    引言 找了很多Python GUI工具集,还是觉得PyQt比较理想,功能强大跨平台,还支持界面设计器.花一天时间折腾了Ubuntu14.04(32位)+ Python3.4 + Qt5.3.2 + P ...

  2. PyQt5多点触控写字板实现及困惑

    Qt支持程序多点触控,就想使用PyQt5做一个触控画板,经过几番周折,查阅了TouchEvent官方文档,又参考了一篇QT for Android的例子,采用eventfilter过滤器来识别触屏事件 ...

  3. pyqt5之简单窗口的创建

    在学完tkinter后,发现tkinter在布局方面特别的不方便(Tkinter资料:http://effbot.org/tkinterbook/tkinter-index.htm),因此学习pyqt ...

  4. PyQt5基础应用一

    一.PyQt5基础   1.1 创建窗口 import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == '__ ...

  5. pyqt5 -——基本功能(HelloWorld)

    一. 简单窗口 这个简单的小例子展示的是一个小窗口.但是我们可以在这个小窗口上面做很多事情,改变大小,最大化,最小化等,这需要很多代码才能实现.这在很多应用中很常见,没必要每次都要重写这部分代码,Qt ...

  6. 五、Pyqt5事件、信号和槽

    PyQt中提供了两种针对事件处理的机制:一种是事件,另一种则是信号和槽. 一.事件 事件处理在PyQt中是比较底层的,常用的事件有键盘事件.鼠标事件.拖放事件.滚轮事件.定时事件.焦点事件.进入和离开 ...

  7. 一、PyQt5基础概念与安装配置

    一.初识PyQt5 对于桌面程序开发,用户图形界面(GUI)的设计非常重要.一款美观.易用的用户界面可以很大程度上提高对使用这的友好度.由于Python最初是作为脚本语言开发,并没有GUI功能.但Py ...

  8. pyQT4和pyQT5的主要模块介绍

    下面简单介绍一下pyQT4和pyQT5的主要模块 pyQT4 的主要模块 QtCore 模块包括了核心的非GUI功能,该模块用来对时间.文件.目录.各种数据类型.流.网址.媒体类型.线程或进程进行处理 ...

  9. PyQt5简介及demo

    PyQt5说明 pyqt5是一套Python绑定Digia QT5应用的框架.它可用于Python 2和3.本教程使用Python 3.Qt库是最强大的GUI库之一.pyqt5的官方网站http:// ...

随机推荐

  1. class 类组件:

    ES6  中的class 类组件: // class 关键字:确定一个类型student以类的概念存在 class student{ //构造函数 是默认自动执行 // 初始化 name age 属性 ...

  2. 008.OpenShift Metric应用

    一 METRICS子系统组件 1.1 metric架构介绍 OpenShift metric子系统支持捕获和长期存储OpenShift集群的性能度量,收集节点以及节点中运行的所有容器的指标. metr ...

  3. ODBC 常见数据源配置整理

    目录 1. 简介 1.1 ODBC和JDBC 1.2 ODBC配置工具 1.3 ODBC 数据源连接配置 2. MySQL 数据源配置 2.1 配置步骤 2.2 链接参数配置 3. SQLServer ...

  4. 如果人生也能存档——C#中的备忘录模式

    大家好,老胡又和大家见面了.首先承认今天的博客有点标题党了,人生是没有存档,也没有后悔药的.有存档和后悔药的,那是游戏,不知道这是不是游戏让人格外放松的原因之一. 今天恰逢端午放假,就让我们来试着做一 ...

  5. C++的逗号运算符

    逗号运算符( , )是C++语言运算符中优先级最低的一种运算符,结合顺序是从左至右,用来顺序求值(最后一个逗号后面表达式的值作为整个表达式的值). 感觉这个东西还是挺冷门的,之前都不知道,平时也比较少 ...

  6. 动态追踪技术之SystemTap

    SystemTap SystemTap是一个深入检查Linux系统活动的工具,使用该工具编写一些简单的代码就可以轻松的提取应用或内核的运行数据,以诊断复杂的性能或者功能问题.有了它,开发者不再需要重编 ...

  7. JAVA基础你需要知道的几点

    一.关于变量 变量可以看成可操作的存储空间,有如下三种: 局部变量:定义在方法或语句块内部,必须先声明初始化才能使用:生命周期从声明位置开始到方法或语句块执行完毕. 成员变量(实例变量):定义在方法外 ...

  8. SpringMVC和Spring

    SpringMVC和Spring汇总 转载:https://www.cnblogs.com/doudouxiaoye/p/5693399.html 1. 为什么使用Spring ? 1). 方便解耦, ...

  9. 并发06--JAVA中的并发工具类

    1.等待多线程完成的CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成操作. 使用join也可以完成这个操作,代码示例如下: package com.exam ...

  10. linux下将多个ts文件合并为一个MP4文件

    1. 安装ffmpeg工具 sudo apt install ffmpeg 2. 确保所有ts文件无损坏后,确保当前目录(即存放ts文件的目录)无txt文件及mp4文件,在存放ts文件的目录下建立te ...