pyqt5教程(六)事件和信号

一、事件

所有的GUI应用都是事件驱动的。事件主要由应用的用户操作产生的。但是事件可能由其他条件触发,比如:一个网络连接,一个窗口管理器,一个定时器,这些动作都可能触发事件的产生。
当我们调用应用的exec_()方法时,应用进入了主循环。主循环用于检测事件的产生并且将事件送到用于处理的对象中去。
在事件模型,有三个参与者

  • 事件源
    事件源是状态发生改变的对象。它产生了事件。
  • 事件对象
    事件对象(event)封装了事件源中的状态变化。
  • 事件目标
    事件目标是想要被通知的对象
    事件源对象代表了处理一个事件直到事件目标做出响应的任务。
    PyQt5有一个独一无二的信号和槽机制来处理事件。信号和槽用于对象之间的通信。当指定事件发生,一个事件信号会被发射。槽可以被任何Python脚本调用。当和槽连接的信号被发射时,槽会被调用。

二、信号 & 槽

下面这个例子演示了PyQt5中的信号和槽的使用。

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider,
    QVBoxLayout, QApplication)
 
 
class Example(QWidget):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()
         
         
    def my_UI(self):
         
        lcd = QLCDNumber(self)                  #LCDNumber 显示类
        sld = QSlider(Qt.Horizontal, self)      #QSlider 显示类
 
        vbox = QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(sld)
 
        self.setLayout(vbox)
        sld.valueChanged.connect(lcd.display)   #将滑块条的valueChanged信号和lcd数字显示的display槽连接在一起
         
        self.setGeometry(300, 300, 300, 250)
        self.setWindowTitle('信号 & 槽')
        self.show()
         
 
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

在我们的例子中,我们显示了一个QtGui.QLCDNumber和一个QtGui.QSlider类。我们拖动滑块条的把手,lcd数字会变化。

三、重写事件处理函数

PyQt中的事件处理通常通过重写事件处理函数来处理。

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication
 
 
class Example(QWidget):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()
         
         
    def my_UI(self):     
         
        self.setGeometry(300, 300, 300, 250)
        self.setWindowTitle('事件处理')
        self.show()
         
         
    def keyPressEvent(self, e):         #重写keyPressEvent()事件处理函数
                                        #如果我们点击了Esc按钮,应用将会被终止。         
        if e.key() == Qt.Key_Escape:
            self.close()
         
         
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

点击Esc按钮,应用将会被终止

四、事件发送者

有时需要方便的知道哪一个组件是信号发送者。因此,PyQt5拥有了sender()方法来解决这个问题。

import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
 
 
class Example(QMainWindow):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()
         
         
    def my_UI(self):     
 
        btn1 = QPushButton("按钮1", self)
        btn1.move(30, 50)
 
        btn2 = QPushButton("按钮2", self)
        btn2.move(150, 50)
       
        btn1.clicked.connect(self.buttonClicked)    #两个按钮都连接到了同一个槽中    
        btn2.clicked.connect(self.buttonClicked)
         
        self.statusBar()
         
        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('事件发送者')
        self.show()
         
         
    def buttonClicked(self):        #在buttonClikced()方法中,我们调用sender()方法来判断哪一个按钮是我们按下的
       
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' 是发送者')
         
         
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

我们调用sender()方法判断发送信号的信号源是哪一个。然后在应用的状态栏上显示被按下的按钮的标签内容


五、发送信号

从QObejct生成的对象可以发送信号。
在下面的例子中我们将会看到怎样去发送自定义的信号。

import sys
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QMainWindow, QApplication
 
 
class Communicate(QObject):     #信号使用了pyqtSignal()方法创建,
                                #并且成为外部类Communicate类的属性。    
     
        closeApp = pyqtSignal() #创建一个新的信号叫做closeApp
     
 
class Example(QMainWindow):
     
    def __init__(self):
        super().__init__()
         
        self.my_UI()
         
         
    def my_UI(self):     
 
        self.c = Communicate()
        self.c.closeApp.connect(self.close)  #把自定义的closeApp信号连接到QMainWindow的close()槽上。    
         
        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('发出信号')
        self.show()
         
         
    def mousePressEvent(self, event):
         
        self.c.closeApp.emit()              #在窗口上点击一下鼠标,closeApp信号会被发射
         
         
if __name__ == '__main__':
     
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

我们创建一个新的信号叫做closeApp。当触发鼠标点击事件时信号会被发射。信号连接到了QMainWindow的close()方法。
这部分的PyQt5教程中,我们概览了信号了槽机制。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,852评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • RAC使用测试Demo下载:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees阅读 6,349评论 3 10
  • 妈妈生下弟弟的那年,我五岁。那天早晨,我和妹妹很早就被姥姥撵出家门玩儿去了。我们去找了邻居小哥哥,到水坑边捞一种只...
    杨帆沧州阅读 193评论 1 3
  • 怎么什么都不对 怎么什么都乏味 收到白色的玫瑰 颜色看上去憔悴 连拥抱的体会都觉得有点累 只好自我安慰我学不会 连...
    宝玉11阅读 130评论 0 0