Python Qt GUI設(shè)計(jì):5種事件處理機(jī)制(提升篇—3)

之前在Python Qt GUI設(shè)計(jì):QTimer計(jì)時(shí)器類讨韭、QThread多線程類和事件處理類(基礎(chǔ)篇—8)中祝高,我們已經(jīng)簡(jiǎn)單講到,PyQt為事件處理提供了兩種機(jī)制:高級(jí)的信號(hào)與槽機(jī)制以及低級(jí)的事件處理程序,本篇博文將系統(tǒng)講解Qt的事件處理機(jī)類和制峦睡。

事件處理機(jī)制本身很復(fù)雜辣往,是PyQt底層的知識(shí)點(diǎn),當(dāng)采用信號(hào)與槽機(jī)制處理不了時(shí)姿鸿,才會(huì)考慮使用事件處理機(jī)制谆吴。

信號(hào)與槽可以說(shuō)是對(duì)事件處理機(jī)制的高級(jí)封裝,如果說(shuō)事件是用來(lái)創(chuàng)建窗口控件的苛预,那么信號(hào)與槽就是用來(lái)對(duì)這個(gè)窗口控件進(jìn)行使用的句狼。比如一個(gè)按鈕,當(dāng)我們使用這個(gè)按鈕時(shí)热某,只關(guān)心clicked信號(hào)腻菇,至于這個(gè)按鈕如何接收并處理鼠標(biāo)點(diǎn)擊事件胳螟,然后再發(fā)射這信號(hào),則不用關(guān)心筹吐。但是如果要重載一個(gè)按鈕糖耸,這時(shí)就要關(guān)心這個(gè)問(wèn)題了。比如可以改變它的行為:在鼠標(biāo)按鍵按下時(shí)觸發(fā)clicked信號(hào)丘薛,而不是在釋放時(shí)嘉竟。

1、常見(jiàn)事件類型

Qt事件的類型有很多洋侨,常見(jiàn)的Qt事件如下所示:

鍵盤事件:按鍵按下和松開(kāi)舍扰。

鼠標(biāo)事件:鼠標(biāo)指針移動(dòng)、鼠標(biāo)按鍵按下和松開(kāi)凰兑。

拖放事件:用鼠標(biāo)進(jìn)行拖放妥粟。

滾輪事件:鼠標(biāo)滾輪滾動(dòng)。

繪屏事件:重繪屏幕的某些部分吏够。

定時(shí)事件:定時(shí)器到時(shí)勾给。

焦點(diǎn)事件:鍵盤焦點(diǎn)移動(dòng)。

進(jìn)入和離開(kāi)事件:鼠標(biāo)指針移入Widget內(nèi)锅知,或者移出播急。

移動(dòng)事件::Widget的位置改變。

大小改變事件:Widget的大小改變售睹。

顯示和隱藏事件:Widget顯示和隱藏桩警。

窗口事件:窗口是否為當(dāng)前窗口。

還有一些常見(jiàn)的Qt事件昌妹,比如Socket事件捶枢、剪貼板事件、字體改變事件飞崖、布局改變事件等烂叔。

具體事件類型和說(shuō)明可參見(jiàn)說(shuō)明文檔:

2、事件處理方法

PyQt提供了如下5種事件處理和過(guò)濾方法(由弱到強(qiáng))固歪,其中只有前兩種方法使用最頻繁蒜鸡。

2.1、重新實(shí)現(xiàn)事件函數(shù)

比如mousePressEvent()牢裳、keyPressEvent()逢防、paintEvent()。這是最常規(guī)的事件處理方法蒲讯。

通過(guò)示例了解重新實(shí)現(xiàn)事件函數(shù)的使用方法忘朝,效果如下所示:

這個(gè)示例中包含了多種事件類型,所以比較復(fù)雜伶椿。

首先是類的建立辜伟,建立text和message兩個(gè)變量氓侧,使用paintEvent函數(shù)把它們輸出到窗口中。

update函數(shù)的作用是更新窗口导狡,由于在窗口更新過(guò)程中會(huì)觸發(fā)一次 paintEvent函數(shù)(paintEvent是窗口基類QWidget的內(nèi)部函數(shù))约巷,因此在本例中update函數(shù)的作用等同于paintEvent函數(shù)。

然后是重新實(shí)現(xiàn)窗口關(guān)閉事件與上下文菜單事件旱捧,對(duì)于上下文菜單事件独郎,主要影響message變量的結(jié)果,paintEvent負(fù)責(zé)把這個(gè)變量在窗口底部輸出枚赡。

繪制事件是代碼的核心事件氓癌,它的主要作用是時(shí)刻跟蹤text與message這兩個(gè)變量的信息,并把 text的內(nèi)容繪制到窗口的中部贫橙,把message的內(nèi)容繪制到窗口的底部(保持5秒后就會(huì)被清空)贪婉。

以及最后一些鼠標(biāo)、鍵盤的點(diǎn)擊操作等卢肃。

實(shí)現(xiàn)代碼如下所示:

import sys

from PyQt5.QtCore import (QEvent, QTimer, Qt)

from PyQt5.QtWidgets import (QApplication, QMenu, QWidget)

from PyQt5.QtGui import QPainter

class Widget(QWidget):

? ? def __init__(self, parent=None):

? ? ? ? super(Widget, self).__init__(parent)

? ? ? ? self.justDoubleClicked = False

? ? ? ? self.key = ""

? ? ? ? self.text = ""

? ? ? ? self.message = ""

? ? ? ? self.resize(400, 300)

? ? ? ? self.move(100, 100)

? ? ? ? self.setWindowTitle("Events")

? ? ? ? QTimer.singleShot(0, self.giveHelp)? # 避免窗口大小重繪事件的影響疲迂,可以把參數(shù)0改變成3000(3秒),然后在運(yùn)行莫湘,就可以明白這行代碼的意思尤蒿。

? ? def giveHelp(self):

? ? ? ? self.text = "請(qǐng)點(diǎn)擊這里觸發(fā)追蹤鼠標(biāo)功能"

? ? ? ? self.update() # 重繪事件,也就是觸發(fā)paintEvent函數(shù)幅垮。

? ? '''重新實(shí)現(xiàn)關(guān)閉事件'''

? ? def closeEvent(self, event):

? ? ? ? print("Closed")

? ? '''重新實(shí)現(xiàn)上下文菜單事件'''

? ? def contextMenuEvent(self, event):

? ? ? ? menu = QMenu(self)

? ? ? ? oneAction = menu.addAction("&One")

? ? ? ? twoAction = menu.addAction("&Two")

? ? ? ? oneAction.triggered.connect(self.one)

? ? ? ? twoAction.triggered.connect(self.two)

? ? ? ? if not self.message:

? ? ? ? ? ? menu.addSeparator()

? ? ? ? ? ? threeAction = menu.addAction("Thre&e")

? ? ? ? ? ? threeAction.triggered.connect(self.three)

? ? ? ? menu.exec_(event.globalPos())

? ? '''上下文菜單槽函數(shù)'''

? ? def one(self):

? ? ? ? self.message = "Menu option One"

? ? ? ? self.update()

? ? def two(self):

? ? ? ? self.message = "Menu option Two"

? ? ? ? self.update()

? ? def three(self):

? ? ? ? self.message = "Menu option Three"

? ? ? ? self.update()

? ? '''重新實(shí)現(xiàn)繪制事件'''

? ? def paintEvent(self, event):

? ? ? ? text = self.text

? ? ? ? i = text.find("\n\n")

? ? ? ? if i >= 0:

? ? ? ? ? ? text = text[0:i]

? ? ? ? if self.key: # 若觸發(fā)了鍵盤按鈕腰池,則在文本信息中記錄這個(gè)按鈕信息。

? ? ? ? ? ? text += "\n\n你按下了: {0}".format(self.key)

? ? ? ? painter = QPainter(self)

? ? ? ? painter.setRenderHint(QPainter.TextAntialiasing)

? ? ? ? painter.drawText(self.rect(), Qt.AlignCenter, text) # 繪制信息文本的內(nèi)容

? ? ? ? if self.message: # 若消息文本存在則在底部居中繪制消息忙芒,5秒鐘后清空消息文本并重繪示弓。

? ? ? ? ? ? painter.drawText(self.rect(), Qt.AlignBottom | Qt.AlignHCenter,

? ? ? ? ? ? ? ? ? ? ? ? ? ? self.message)

? ? ? ? ? ? QTimer.singleShot(5000, self.clearMessage)

? ? ? ? ? ? QTimer.singleShot(5000, self.update)

? ? '''清空消息文本的槽函數(shù)'''

? ? def clearMessage(self):

? ? ? ? self.message = ""

? ? '''重新實(shí)現(xiàn)調(diào)整窗口大小事件'''

? ? def resizeEvent(self, event):

? ? ? ? self.text = "調(diào)整窗口大小為: QSize({0}, {1})".format(

? ? ? ? ? ? event.size().width(), event.size().height())

? ? ? ? self.update()

? ? '''重新實(shí)現(xiàn)鼠標(biāo)釋放事件'''

? ? def mouseReleaseEvent(self, event):

? ? ? ? # 若鼠標(biāo)釋放為雙擊釋放,則不跟蹤鼠標(biāo)移動(dòng)

? ? ? ? # 若鼠標(biāo)釋放為單擊釋放呵萨,則需要改變跟蹤功能的狀態(tài)避乏,如果開(kāi)啟跟蹤功能的話就跟蹤,不開(kāi)啟跟蹤功能就不跟蹤

? ? ? ? if self.justDoubleClicked:

? ? ? ? ? ? self.justDoubleClicked = False

? ? ? ? else:

? ? ? ? ? ? self.setMouseTracking(not self.hasMouseTracking()) # 單擊鼠標(biāo)

? ? ? ? ? ? if self.hasMouseTracking():

? ? ? ? ? ? ? ? self.text = "開(kāi)啟鼠標(biāo)跟蹤功能.\n" + \

? ? ? ? ? ? ? ? ? ? ? ? ? ? "請(qǐng)移動(dòng)一下鼠標(biāo)甘桑!\n" + \

? ? ? ? ? ? ? ? ? ? ? ? ? ? "單擊鼠標(biāo)可以關(guān)閉這個(gè)功能"

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? self.text = "關(guān)閉鼠標(biāo)跟蹤功能.\n" + \

? ? ? ? ? ? ? ? ? ? ? ? ? ? "單擊鼠標(biāo)可以開(kāi)啟這個(gè)功能"

? ? ? ? ? ? self.update()

? ? '''重新實(shí)現(xiàn)鼠標(biāo)移動(dòng)事件'''

? ? def mouseMoveEvent(self, event):

? ? ? ? if not self.justDoubleClicked:

? ? ? ? ? ? globalPos = self.mapToGlobal(event.pos()) # 窗口坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo)

? ? ? ? ? ? self.text = """鼠標(biāo)位置:

? ? ? ? ? ? 窗口坐標(biāo)為:QPoint({0}, {1})

? ? ? ? ? ? 屏幕坐標(biāo)為:QPoint({2}, {3}) """.format(event.pos().x(), event.pos().y(), globalPos.x(), globalPos.y())

? ? ? ? ? ? self.update()

? ? '''重新實(shí)現(xiàn)鼠標(biāo)雙擊事件'''

? ? def mouseDoubleClickEvent(self, event):

? ? ? ? self.justDoubleClicked = True

? ? ? ? self.text = "你雙擊了鼠標(biāo)"

? ? ? ? self.update()

? ? '''重新實(shí)現(xiàn)鍵盤按下事件'''

? ? def keyPressEvent(self, event):

? ? ? ? self.key = ""

? ? ? ? if event.key() == Qt.Key_Home:

? ? ? ? ? ? self.key = "Home"

? ? ? ? elif event.key() == Qt.Key_End:

? ? ? ? ? ? self.key = "End"

? ? ? ? elif event.key() == Qt.Key_PageUp:

? ? ? ? ? ? if event.modifiers() & Qt.ControlModifier:

? ? ? ? ? ? ? ? self.key = "Ctrl+PageUp"

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? self.key = "PageUp"

? ? ? ? elif event.key() == Qt.Key_PageDown:

? ? ? ? ? ? if event.modifiers() & Qt.ControlModifier:

? ? ? ? ? ? ? ? self.key = "Ctrl+PageDown"

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? self.key = "PageDown"

? ? ? ? elif Qt.Key_A <= event.key() <= Qt.Key_Z:

? ? ? ? ? ? if event.modifiers() & Qt.ShiftModifier:

? ? ? ? ? ? ? ? self.key = "Shift+"

? ? ? ? ? ? self.key += event.text()

? ? ? ? if self.key:

? ? ? ? ? ? self.key = self.key

? ? ? ? ? ? self.update()

? ? ? ? else:

? ? ? ? ? ? QWidget.keyPressEvent(self, event)

if __name__ == "__main__":

? ? app = QApplication(sys.argv)

? ? form = Widget()

? ? form.show()

? ? app.exec_()

2.2、重新實(shí)現(xiàn)QObject.event()

一般用在PyQt沒(méi)有提供該事件的處理函數(shù)的情況下歹叮,即增加新事件時(shí)跑杭。

對(duì)于窗口所有的事件都會(huì)傳遞給event函數(shù),event函數(shù)會(huì)根據(jù)事件的類型咆耿,把事件分配給不同的函數(shù)進(jìn)行處理德谅。例如,對(duì)于繪圖事件萨螺,event會(huì)交給paintEvent函數(shù)處理窄做;對(duì)于鼠標(biāo)移動(dòng)事件愧驱,event會(huì)交給mouseMoveEvent函數(shù)處理;對(duì)于鍵盤按下事件椭盏,event會(huì)交給keyPressEvent函數(shù)處理组砚。

有一種特殊情況是對(duì)Tab鍵的觸發(fā)行為,event函數(shù)對(duì)Tab鍵的處理機(jī)制是把焦點(diǎn)從當(dāng)前窗口控件的位置切換到Tab鍵次序中下一個(gè)窗口控件的位置掏颊,并返回True糟红,而不是交給keyPressEvent函數(shù)處理。

因此這里需要在event函數(shù)中對(duì)按下Tab鍵的處理邏輯重新改寫(xiě)乌叶,使它與鍵盤上普通的鍵沒(méi)什么不同盆偿。

2.1、重新實(shí)現(xiàn)事件函數(shù)例子中補(bǔ)充以下代碼准浴,實(shí)現(xiàn)重新定義:

'''重新實(shí)現(xiàn)其他事件事扭,適用于PyQt沒(méi)有提供該事件的處理函數(shù)的情況,Tab鍵由于涉及焦點(diǎn)切換乐横,不會(huì)傳遞給keyPressEvent求橄,因此,需要在這里重新定義晰奖。'''

? ? def event(self, event):

? ? ? ? if (event.type() == QEvent.KeyPress and

? ? ? ? ? ? ? ? ? ? event.key() == Qt.Key_Tab):

? ? ? ? ? ? self.key = "在event()中捕獲Tab鍵"

? ? ? ? ? ? self.update()

? ? ? ? ? ? return True

效果如下所示:

2.3谈撒、安裝事件過(guò)濾器

如果對(duì)QObject調(diào)用installEventFilter,則相當(dāng)于為這個(gè)QObject安裝了一個(gè)事件過(guò)濾器匾南,對(duì)于QObject的全部事件來(lái)說(shuō)啃匿,它們都會(huì)先傳遞到事件過(guò)濾函數(shù)eventFilter中,在這個(gè)函數(shù)中我們可以拋棄或者修改這些事件蛆楞,比如可以對(duì)自己感興趣的事件使用自定義的事件處理機(jī)制溯乒,對(duì)其他事件使用默認(rèn)的事件處理機(jī)制。

由于這種方法會(huì)對(duì)調(diào)用installEventFilter的所有QObject的事件進(jìn)行過(guò)濾豹爹,因此如果要過(guò)濾的事件比較多裆悄,則會(huì)降低程序的性能。

通過(guò)示例臂聋,了解事件過(guò)濾器的使用方法光稼,效果如下所示:

對(duì)于使用事件過(guò)濾器,關(guān)鍵是要做好兩步孩等。

對(duì)要過(guò)濾的控件設(shè)置installEventFilter艾君,這些控件的所有事件都會(huì)被eventFilter函數(shù)接收并處理。

示例中肄方,這個(gè)過(guò)濾器只對(duì)label1的事件進(jìn)行處理冰垄,并且只處理它的鼠標(biāo)按下事件(MouseButtonPress)和鼠標(biāo)釋放事件(MouseButtonRelease) 。

如果按下鼠標(biāo)鍵权她,就會(huì)對(duì)label1裝載的圖片進(jìn)行縮放(長(zhǎng)和寬各縮放一半)虹茶。

實(shí)現(xiàn)代碼如下所示:

# -*- coding: utf-8 -*-

from PyQt5.QtGui import *

from PyQt5.QtCore import *

from PyQt5.QtWidgets import *

import sys

class EventFilter(QDialog):

? ? def __init__(self, parent=None):

? ? ? ? super(EventFilter, self).__init__(parent)

? ? ? ? self.setWindowTitle("事件過(guò)濾器")

? ? ? ? self.label1 = QLabel("請(qǐng)點(diǎn)擊")

? ? ? ? self.label2 = QLabel("請(qǐng)點(diǎn)擊")

? ? ? ? self.label3 = QLabel("請(qǐng)點(diǎn)擊")

? ? ? ? self.LabelState = QLabel("test")

? ? ? ? self.image1 = QImage("images/cartoon1.ico")

? ? ? ? self.image2 = QImage("images/cartoon1.ico")

? ? ? ? self.image3 = QImage("images/cartoon1.ico")

? ? ? ? self.width = 600

? ? ? ? self.height = 300

? ? ? ? self.resize(self.width, self.height)

? ? ? ? self.label1.installEventFilter(self)

? ? ? ? self.label2.installEventFilter(self)

? ? ? ? self.label3.installEventFilter(self)

? ? ? ? mainLayout = QGridLayout(self)

? ? ? ? mainLayout.addWidget(self.label1, 500, 0)

? ? ? ? mainLayout.addWidget(self.label2, 500, 1)

? ? ? ? mainLayout.addWidget(self.label3, 500, 2)

? ? ? ? mainLayout.addWidget(self.LabelState, 600, 1)

? ? ? ? self.setLayout(mainLayout)

? ? def eventFilter(self, watched, event):

? ? ? ? if watched == self.label1: # 只對(duì)label1的點(diǎn)擊事件進(jìn)行過(guò)濾逝薪,重寫(xiě)其行為,其他的事件會(huì)被忽略

? ? ? ? ? ? if event.type() == QEvent.MouseButtonPress: # 這里對(duì)鼠標(biāo)按下事件進(jìn)行過(guò)濾蝴罪,重寫(xiě)其行為

? ? ? ? ? ? ? ? mouseEvent = QMouseEvent(event)

? ? ? ? ? ? ? ? if mouseEvent.buttons() == Qt.LeftButton:

? ? ? ? ? ? ? ? ? ? self.LabelState.setText("按下鼠標(biāo)左鍵")

? ? ? ? ? ? ? ? elif mouseEvent.buttons() == Qt.MidButton:

? ? ? ? ? ? ? ? ? ? self.LabelState.setText("按下鼠標(biāo)中間鍵")

? ? ? ? ? ? ? ? elif mouseEvent.buttons() == Qt.RightButton:

? ? ? ? ? ? ? ? ? ? self.LabelState.setText("按下鼠標(biāo)右鍵")

? ? ? ? ? ? ? ? '''轉(zhuǎn)換圖片大小'''

? ? ? ? ? ? ? ? transform = QTransform()

? ? ? ? ? ? ? ? transform.scale(0.5, 0.5)

? ? ? ? ? ? ? ? tmp = self.image1.transformed(transform)

? ? ? ? ? ? ? ? self.label1.setPixmap(QPixmap.fromImage(tmp))

? ? ? ? ? ? if event.type() == QEvent.MouseButtonRelease: # 這里對(duì)鼠標(biāo)釋放事件進(jìn)行過(guò)濾董济,重寫(xiě)其行為

? ? ? ? ? ? ? ? self.LabelState.setText("釋放鼠標(biāo)按鈕")

? ? ? ? ? ? ? ? self.label1.setPixmap(QPixmap.fromImage(self.image1))

? ? ? ? return QDialog.eventFilter(self, watched, event) # 其他情況會(huì)返回系統(tǒng)默認(rèn)的事件處理方法。

if __name__ == '__main__':

? ? app = QApplication(sys.argv)

? ? dialog = EventFilter()

? ? dialog.show()

? ? sys.exit(app.exec_())

2.4洲炊、在QApplication中安裝事件過(guò)濾器

這種方法比2.3感局、安裝事件過(guò)濾器更強(qiáng)大,QApplication的事件過(guò)濾器將捕獲所有QObject的所有事件暂衡,而且第一個(gè)獲得該事件询微。也就是說(shuō),在將事件發(fā)送給其他任何一個(gè)事件過(guò)濾器之前(就是在第三種方法之前)狂巢,都會(huì)先發(fā)送給QApplication的事件過(guò)濾器撑毛。

2.3、安裝事件過(guò)濾器示例基礎(chǔ)上修改唧领,屏蔽三個(gè)label標(biāo)簽控件的installEventFilter代碼藻雌,這種事件處理方法確實(shí)過(guò)濾了所有事件,而不像第三種方法那樣只過(guò)濾三個(gè)標(biāo)簽控件的事件斩个。效果如下所示:

實(shí)現(xiàn)代碼如下所示:

# -*- coding: utf-8 -*-

from PyQt5.QtGui import *

from PyQt5.QtCore import *

from PyQt5.QtWidgets import *

import sys

class EventFilter(QDialog):

? ? def __init__(self, parent=None):

? ? ? ? super(EventFilter, self).__init__(parent)

? ? ? ? self.setWindowTitle("事件過(guò)濾器")

? ? ? ? self.label1 = QLabel("請(qǐng)點(diǎn)擊")

? ? ? ? self.label2 = QLabel("請(qǐng)點(diǎn)擊")

? ? ? ? self.label3 = QLabel("請(qǐng)點(diǎn)擊")

? ? ? ? self.LabelState = QLabel("test")

? ? ? ? self.image1 = QImage("images/cartoon1.ico")

? ? ? ? self.image2 = QImage("images/cartoon1.ico")

? ? ? ? self.image3 = QImage("images/cartoon1.ico")

? ? ? ? self.width = 600

? ? ? ? self.height = 300

? ? ? ? self.resize(self.width, self.height)

? ? ? ? # self.label1.installEventFilter(self)

? ? ? ? # self.label2.installEventFilter(self)

? ? ? ? # self.label3.installEventFilter(self)

? ? ? ? mainLayout = QGridLayout(self)

? ? ? ? mainLayout.addWidget(self.label1, 500, 0)

? ? ? ? mainLayout.addWidget(self.label2, 500, 1)

? ? ? ? mainLayout.addWidget(self.label3, 500, 2)

? ? ? ? mainLayout.addWidget(self.LabelState, 600, 1)

? ? ? ? self.setLayout(mainLayout)

? ? def eventFilter(self, watched, event):

? ? ? ? print(type(watched))

? ? ? ? if watched == self.label1: # 只對(duì)label1的點(diǎn)擊事件進(jìn)行過(guò)濾胯杭,重寫(xiě)其行為,其他的事件會(huì)被忽略

? ? ? ? ? ? if event.type() == QEvent.MouseButtonPress: # 這里對(duì)鼠標(biāo)按下事件進(jìn)行過(guò)濾受啥,重寫(xiě)其行為

? ? ? ? ? ? ? ? mouseEvent = QMouseEvent(event)

? ? ? ? ? ? ? ? if mouseEvent.buttons() == Qt.LeftButton:

? ? ? ? ? ? ? ? ? ? self.LabelState.setText("按下鼠標(biāo)左鍵")

? ? ? ? ? ? ? ? elif mouseEvent.buttons() == Qt.MidButton:

? ? ? ? ? ? ? ? ? ? self.LabelState.setText("按下鼠標(biāo)中間鍵")

? ? ? ? ? ? ? ? elif mouseEvent.buttons() == Qt.RightButton:

? ? ? ? ? ? ? ? ? ? self.LabelState.setText("按下鼠標(biāo)右鍵")

? ? ? ? ? ? ? ? '''轉(zhuǎn)換圖片大小'''

? ? ? ? ? ? ? ? transform = QTransform()

? ? ? ? ? ? ? ? transform.scale(0.5, 0.5)

? ? ? ? ? ? ? ? tmp = self.image1.transformed(transform)

? ? ? ? ? ? ? ? self.label1.setPixmap(QPixmap.fromImage(tmp))

? ? ? ? ? ? if event.type() == QEvent.MouseButtonRelease: # 這里對(duì)鼠標(biāo)釋放事件進(jìn)行過(guò)濾做个,重寫(xiě)其行為

? ? ? ? ? ? ? ? self.LabelState.setText("釋放鼠標(biāo)按鈕")

? ? ? ? ? ? ? ? self.label1.setPixmap(QPixmap.fromImage(self.image1))

? ? ? ? return QDialog.eventFilter(self, watched, event) # 其他情況會(huì)返回系統(tǒng)默認(rèn)的事件處理方法。

if __name__ == '__main__':

? ? app = QApplication(sys.argv)

? ? dialog = EventFilter()

? ? app.installEventFilter(dialog)

? ? dialog.show()

? ? sys.exit(app.exec_())

2.5滚局、重新實(shí)現(xiàn)QApplication的notify()方法

PyQt使用notify()來(lái)分發(fā)事件居暖,要想在任何事件處理器之前捕獲事件,唯一的方法就是重新實(shí)現(xiàn)QApplication的notify()藤肢,在實(shí)踐中太闺,在調(diào)試時(shí)才會(huì)使用這種方法,實(shí)際中基本用不多嘁圈,這里不再贅述了省骂。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市最住,隨后出現(xiàn)的幾起案子冀宴,更是在濱河造成了極大的恐慌,老刑警劉巖温学,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異甚疟,居然都是意外死亡仗岖,警方通過(guò)查閱死者的電腦和手機(jī)逃延,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)轧拄,“玉大人揽祥,你說(shuō)我怎么就攤上這事¢莸纾” “怎么了拄丰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)俐末。 經(jīng)常有香客問(wèn)我料按,道長(zhǎng),這世上最難降的妖魔是什么卓箫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任载矿,我火速辦了婚禮,結(jié)果婚禮上烹卒,老公的妹妹穿的比我還像新娘闷盔。我一直安慰自己,他們只是感情好旅急,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布逢勾。 她就那樣靜靜地躺著,像睡著了一般藐吮。 火紅的嫁衣襯著肌膚如雪溺拱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天炎码,我揣著相機(jī)與錄音盟迟,去河邊找鬼。 笑死潦闲,一個(gè)胖子當(dāng)著我的面吹牛攒菠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歉闰,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辖众,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了和敬?” 一聲冷哼從身側(cè)響起凹炸,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昼弟,沒(méi)想到半個(gè)月后啤它,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年变骡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了离赫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡塌碌,死狀恐怖渊胸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情台妆,我是刑警寧澤翎猛,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站接剩,受9級(jí)特大地震影響切厘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜搂漠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一迂卢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桐汤,春花似錦而克、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至拣度,卻和暖如春碎绎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抗果。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工筋帖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冤馏。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓日麸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親逮光。 傳聞我的和親對(duì)象是個(gè)殘疾皇子代箭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容