pyqt5 事件event 过滤 installEventFilter eventFilter QEvent.MetaCall

代码:

from PyQt5.QtCore import QThread, pyqtSignal, QDateTime, QObject,QEvent
from PyQt5.QtWidgets import QApplication, QDialog, QLineEdit, QLabel
import time
import sys


class BackendThread(QObject):
    # 通过类成员对象定义信号
    update_date = pyqtSignal(str)

    # 处理业务逻辑
    def run(self):
        while True:
            data = QDateTime.currentDateTime()
            currTime = data.toString("yyyy-MM-dd hh:mm:ss")
            self.update_date.emit(str(currTime))
            time.sleep(1)


class Window(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setWindowTitle('PyQt 5界面实时更新例子')
        self.resize(400, 100)
        self.input = QLabel(self)
        self.input.resize(400, 100)
        self.initUI()

    def initUI(self):
        # 创建线程
        self.backend = BackendThread()
        # 连接信号
        self.backend.update_date.connect(self.handleDisplay)
        self.thread = QThread()
        self.backend.moveToThread(self.thread)
        # 开始线程
        self.thread.started.connect(self.backend.run)
        self.thread.start()



    # 将当前时间输出到文本框
    def handleDisplay(self, data):
        self.input.setText(data)

    def keyPressEvent(self, event):
        print('keyPressEvent')
        pass

    def eventFilter(self, objwatched, event):
        eventType = event.type()
        #print(eventType)
        if eventType == QEvent.KeyPress:
            print('eventFilter KeyPress')

        elif eventType == QEvent.MetaCall:
            print('eventFilter MetaCall')
        return super().eventFilter(objwatched, event)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    app.installEventFilter(win)
    sys.exit(app.exec_())

参考资料:

PyQt学习随笔:Qt事件QEvent.type类型常量及其含义资料汇总详细内容速查
https://blog.csdn.net/LaoYuanPython/article/details/102527651

PyQt5-事件处理机制
https://www.cnblogs.com/ygzhaof/p/10132824.html

 def eventFilter(self, obj, event):
       
       if obj == self.lineEdit:
        if event.type()== QEvent.FocusIn:
            #self.inp_text_signal.emit("已进")
            if self.lineEdit.text().strip() == '请输入用户名':
                self.lineEdit.clear()
            
                
            print("ok1")
        elif event.type()== QEvent.FocusOut:
            if self.lineEdit.text().strip() == '':
                self.lineEdit.setText("请输入用户名")
            print("ok2")
        else:
            pass
        return False
        

除了《PyQt学习随笔:Qt事件QEvent.type类型常量及其含义资料速查》介绍的Qt已经定义的事件外,Qt还支持自定义事件。

为了方便起见,可以使用 registerEventType()函数为应用程序注册和保留自定义事件类型。这样做可以避免意外地重新使用应用程序中其他地方已在使用的自定义事件类型。

用户自定义事件的值必须在QEvent.User事件到QEvent.MaxUser事件之间,其中QEvent.User事件的常量值为1000,QEvent.MaxUser事件的常量值为65535。
PyQt学习随笔:应用中通过installEventFilter安装重写的eventFilter捕获应用事件的方法
https://blog.csdn.net/LaoYuanPython/article/details/102539773
8、registerEventType(hint = -1)方法,用于注册和返回一个用户自定义事件类型,它是线程安全的函数。其中

参考:

PyQt5 使用windows系统消息 识别设备插拔

关键字: python, PyQt5, nativeEvent, WM_DEVICECHANGE, winEvent

以下代码已经过精简,去除无关部分,可直接运行,运行环境为python3.7.2 64bit PyQt5.11.3 64bit

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from ctypes.wintypes import MSG

class MainWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        
    def nativeEvent(self, eventType, msg):
        message = MSG.from_address(int(msg))
        if message.message == 0x219:  # WM_DEVICECHANGE
            if message.wParam == 0x8000:  # DBT_DEVICEARRIVAL
                print("in")
            elif message.wParam == 0x8004:  # DBT_DEVICEREMOVECOMPLETE
                print("out")
            elif message.wParam == 0x0007:  # DBT_DEVNODE_CHANGED
                print("node")
        return False, msg

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

运行时,会有一个很小的界面,界面里什么都没有。插拔设备会在解释器的终端里输出。

之前就有想用PyQt5识别windows系统消息。但是今天才开始去弄这个。查了很多资料,花了有半天时间,才弄完。因为资料很多都已经过期了。所以我遇到的几个问题跟大家说一下。

nativeEvent是QWidget的虚函数
关于这一部分的Qt5的文档在这里。Qt5是C++的多平台的GUI库。
http://doc.qt.io/qt-5/qwidget.html#nativeEvent
PyQt是针对Python的。使用起来略有不同,相关文档也并不是很全,不是很系统化,也只能用的时候再找了。

网上查的MSG.from_address(msg.init())并不能在我的环境中运行。
我试了一下可以使用MSG.from_address(int(msg))
但我并不清楚是什么原因。

关于nativeEvent的返回值。有些资料说必须是False 否则会有问题。这个我没有试。第二个返回值也是按资料上填的。运行倒是能成功,但如果有人熟悉这一块,欢迎回复我。

我查阅的一些资料:
https://blog.csdn.net/hidxl/article/details/53633874
https://blog.csdn.net/neverstop_2009/article/details/47361309
https://blog.csdn.net/swqqcs/article/details/7251321
————————————————
https://blog.csdn.net/josephzhang1012/article/details/86694876

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

猜你喜欢

转载自blog.csdn.net/wowocpp/article/details/105340022