PyQt中提供了两种针对事件处理的机制:一种是事件,另一种则是信号和槽

一、事件

事件处理在PyQt中是比较底层的,常用的事件有键盘事件、鼠标事件、拖放事件、滚轮事件、定时事件、焦点事件、进入和离开事件(光标移入控件或者移出),移动事件(窗口位置变化),显示和隐藏事件,窗口事件(窗口是否为当前窗口)、以及常见的Qt事件:Socket事件、剪贴板事件、文字改变事件,布局改变事件等。

针对这些事件,PyQt提供了多种事件处理和过滤方法,其中最常用的有两种:

(1)重写事件具体的函数(例如:mousePressEvent()/keyPressEvent()....)

(2)重新实现QObject.event()一般用在PyQt没有提供该事件的处理函数的情况下,即添加一个新的事件;

1.1 重写事件

 import sys,os
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication,QMessageBox
from PyQt5.QtGui import QIcon path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class MyWindow(QWidget): def __init__(self):
super(MyWindow, self).__init__()
self.initUI() def initUI(self):
self.setGeometry(300, 300, 300, 250)
self.setWindowTitle('重写事件示例')
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path)) def closeEvent(self, QCloseEvent):
'''
重写closeEvent方法,关闭窗口时触发
'''
reply = QMessageBox.question(self,'本程序',"是否要退出程序?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No)
if reply == QMessageBox.Yes:
QCloseEvent.accept()
else:
QCloseEvent.ignore() def keyPressEvent(self, QKeyEvent):
'''
重写keyPressEvent事件,按下ESC就会退出程序
'''
if QKeyEvent.key() == Qt.Key_Escape:
self.close() if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())

重写事件示例

这段代码里重写了keyPressEvent和closeEvent两个事件。实现了两个功能:(1)按下ESC是可退出关闭窗口;(2)关闭当前窗口时,弹出对话框。

效果图如下:

在pycharm中编辑时,我们可以发现,QWidget类下虽然有该keyPressEvent和closeEvent方法,但并没有编写有意义的内容。

1.2 创建新事件

可参考前面小节的center(),不再详述。

除上述内容外,再对三个概念加以学习,即事件对象、事件发送。

事件对象时python用来描述一系列自身属性的对象。

 import sys,os
from PyQt5.QtWidgets import QApplication,QWidget,QGridLayout,QLabel
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class MyWindow(QWidget): def __init__(self):
super().__init__()
self.initUI() def initUI(self):
self.setGeometry(600,300,350,250)
self.setWindowTitle('信号和槽')
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path)) grid = QGridLayout()
grid.setSpacing(10) x=0
y=0
self.text = "x:{},y:{}".format(x,y)
self.label = QLabel(self.text,self)
grid.addWidget(self.label,0,0,Qt.AlignTop) self.setMouseTracking(True) #开启鼠标追踪
self.setLayout(grid) def mouseMoveEvent(self, QMouseEvent):
x = QMouseEvent.x()
y = QMouseEvent.y()
text = "x:{},y:{}".format(x, y)
self.label.setText(text) if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())

事件对象示例

在这个示例中,我们再label里显示鼠标的坐标。mouseMoveEvent方法下的QMouseEvent即鼠标移动的事件对象,也就是需要捕捉的信号来源。

事件发送是在程序设计与调试时,我们需要知道是哪一个控件发送了信号,利用PyQt5中的sender()方法可以实现。

 import sys,os
from PyQt5.QtWidgets import QMainWindow,QApplication,QPushButton
from PyQt5.QtGui import QIcon path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class MyWindow(QMainWindow): def __init__(self):
super().__init__()
self.initUI() def initUI(self):
self.setGeometry(600,300,300,260)
self.setWindowTitle('事件发送')
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path)) btn1 = QPushButton('按钮一',self)
btn2 = QPushButton('按钮二',self) btn1.move(30,50)
btn2.move(150,50) btn1.clicked.connect(self.buttonClicked)
btn2.clicked.connect(self.buttonClicked) self.statusBar() def buttonClicked(self):
sender = self.sender()
self.statusBar().showMessage(sender.text() + '被按下') if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())

事件发送示例

sender()方法可以返回发送信号的控件名称。这在我们调试时可以起到极大的辅助作用。方便快速了解程序背后的设计思路。

二、信号和槽

信号(Signal)和槽(Slot)是Qt中的核心机制,也是在PyQt编程中对象之间进行通信的机制。在Qt中,每个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject的子对象)都支持信号与槽机制。当信号发射时,连接的槽函数将会自动执行。在PyQt5中信号与槽通过object.signal.connect()方法连接。

使用时,既可以自定义信号,也可以使用pyqt内置信号。信号与槽具有以下几个特点:

  • 一个信号可以连接多个槽;
  • 一个信号也可以连接另一个信号;
  • 一个槽可以监听多个信号;
  • 信号与槽的连接可能同步或者异步,还可能跨线程连接;
  • 信号也可能断开。

除此之外,还有几个常用的操作方法需要说明:

  1. connect()方法可以将信号与槽函数连接。注意这里的槽函数不能加括号(后面会讲到);
  2. disconnect可以将接触信号与槽的连接;
  3. emit()可以发射信号
  4. 如果需要自定义信号,可以使用PyQt5.QtCore下的pyqtSignal方法。
 import sys,os
from PyQt5.QtCore import pyqtSignal,QObject
from PyQt5.QtWidgets import QMainWindow,QApplication
from PyQt5.QtGui import QIcon path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) class Communicate(QObject):
closeApp = pyqtSignal() class MyWindow(QMainWindow): def __init__(self):
super(MyWindow, self).__init__()
self.initUI() def initUI(self):
self.setGeometry(600,300,500,400)
self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
self.setWindowTitle('信号发送') self.c = Communicate()
self.c.closeApp.connect(self.close) def mousePressEvent(self, *args, **kwargs):
self.c.closeApp.emit() if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())

信号与槽

在这个示例中,我们创建了一个closeApp的信号,该信号会在鼠标按下时触发。且该事件与QMainwindow绑定。

class Communicate(QObject):
closeApp = pyqtSignal()

  这里,我们创建了一个Communicate类,并在该类下创建了信号。

self.c = Communicate()
self.c.closeApp.connect(self.close)

  首先将communicate()类示例化给self.c。然后将closeApp信号与窗口的close()方法连接。

    def mousePressEvent(self, *args, **kwargs):
self.c.closeApp.emit()

  点击鼠标按键时,emit()方法会将closeApp信号发射。

五、Pyqt5事件、信号和槽的更多相关文章

  1. PyQT5:信号和槽

    PyQT5:信号和槽 信号和槽 Qt的主要特征之一是它使用信号和插槽在对象之间进行通信. 当潜在的事件发生时,会发出一个信号.插槽是可调用的Python,如果将信号连接到插槽,则在发出信号时将调用该插 ...

  2. pyqt5核心-信号与槽(第二弹)

    果: from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.s ...

  3. PyQt5中的信号与槽,js 与 Qt 对象之间互相调用

    一.PyQt中的信号与槽 信号(Signal)和槽(Slot)是Qt中的核心机制,用在对象之间互相通信.在Qt中每个QObject对象和PyQt中所有继承自QWidget的控件(这些都是QObject ...

  4. PyQt5(3)——信号和槽初探

    信号和槽是QT的核心机制(当信号发射时,链接的槽函数会自动执行) 在pyqt5中信号和槽通过 QObject.signal.connect()链接. QObject类或子类(QWidget)派生的类都 ...

  5. Qt对象模型之一:信号和槽

    一.信号和槽机制概述 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal).这种发出是没有目 ...

  6. PyQt5信号与槽详解

    1.信号与槽函数基础'''信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行'''from PyQt5.QtWidgets import *import sys class signal(Q ...

  7. pyqt5信号与槽2

    信号和槽与类的属性和方法在层次上是相同的,同属与一个类的特征. 信号的定义由工厂函数生成: signal=PyQt5.QtCore.pyqtSignal(types[, name[, result[, ...

  8. [ PyQt入门教程 ] PyQt5信号与槽

    信号和槽是PyQt编程对象之间进行通信的机制.每个继承自QWideget的控件都支持信号与槽机制.信号发射时(发送请求),连接的槽函数就会自动执行(针对请求进行处理).本文主要讲述信号和槽最基本.最经 ...

  9. PyQt5信号与槽关联的两种方式

    目录 通过QtDesigner 手动关联的方式 通过QtDesigner 单击菜单栏切换到信号槽编辑模式 单击控件并拖动鼠标到信号的接收对象上,一般为对话框自己,松开鼠标弹出信号和槽选择框 选中cli ...

随机推荐

  1. HTTPS 基本流程3

    前文说到了6 组key material, 12个hash 值,非常迷惑, 今天才搞明白, 原来所有这些内容就是 对称密钥的内容. 上面的图 虽然不是很清晰,但是, 其实也已经写明白了, 就是 右边的 ...

  2. 分布式 基本理论 CAP

    谈及分布式,必然谈到 CAP, CAP 已经是被说烂了的一个 话题, 绕不开, 逃不掉.  而且, 理解起来 会有些吃力. 分布式的CAP理论告诉我们 “任何一个分布式系统都无法同时满足 一致性(Co ...

  3. DP问题

    1.背包问题

  4. cdh启动datanode报错

    问题: 为cdh新增节点时,在分配datanode后,启动报错 Can't open /iot/opt/cloudera-manager/cm-5.11.2/run/cloudera-scm-agen ...

  5. list之flex布局写法

    list之flex布局写法 移动端实际场景中经常会遇到将header置顶,然后下面list需要滚动的情况,通常的做法会是将header使用fixed的方式固定到顶部,然后list主体相对于header ...

  6. 44_redux_comment应用_redux版本_同步功能

    项目结构: components里面的东西没变,将app.jsx移动至containers中 /* * 包含所有action的type名称常量 * */ //添加评论 export const ADD ...

  7. redis伪集群脚本

    #安装redis伪集群脚本,先把redis-..gem及启动脚本放在/data1/redis-cluster目录下,然后执行该脚本即可 #!/bin/bash set -e #获取redis本机ip ...

  8. NE76003单片机调试DS18B20 步骤

    一.硬件部分 GND脚接地: DQ脚接P03,外加4K7上拉电阻: VCC脚接3.3v供电: 二.软件部分 1.配置P03为准准双向 IO类型: void Init_power_gpio(void){ ...

  9. NYOJ37-回文字符串(dp)

    37-回文字符串 内存限制:64MB 时间限制:3000ms 特判: No通过数:88 提交数:177 难度:4 题目描述: 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如& ...

  10. vue中的一些知识点--多看文档

    重温vue,一些知识点简单记录. 1.我们都知道当数据变化时,视图会重新渲染.注意:只有当vue实例被创建时,data中存在的属性才是响应式的.后续新添加的属性不会触发视图变化. 使用 Object. ...