InstallEventFilter 自定义 class

InstallEventFilter for custom class

我写了一个小程序,想安装EventFilter来跟踪鼠标事件。有什么想法吗?

#!/usr/bin/env python
import os
import sys
from PySide2.QtCore import Qt, QSize, QRegExp, QFile, QTextStream
from PySide2.QtGui import QKeySequence, QTextCharFormat, QBrush,QColor, QTextDocument, QTextCursor
from PySide2.QtWidgets import (QApplication, QDesktopWidget, QMainWindow,
                               QPlainTextEdit, QGridLayout, QGroupBox,
                               QFormLayout, QHBoxLayout, QLabel, QLineEdit,
                               QMenu, QMenuBar, QPushButton, QMessageBox,
                               QTextEdit, QVBoxLayout, QWidget, QAction)

class BlockWindow():
    def __init__(self, waiver_files, app):
        self.waiver_files = waiver_files
        self.app = app
    
    def create_widget(self): 
        self.create_violation_text()
        self.create_violation_window()
        self.create_text_finder()
        #order matter
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.text_finder)
        main_layout.addWidget(self.create_violation_box)
        return main_layout
       
    
    def create_text_finder(self):
        """
        create text finder which wil search string into document
        """
        self.text_finder = QGroupBox()
        layout = QHBoxLayout()
        label = QLabel()
        label.setText("Keyword:")
        self.line_edit = QLineEdit()
        self.line_edit.setText("Enter your search here")
        push_button = QPushButton("Find")
        layout.addWidget(label)
        layout.addWidget(self.line_edit)
        layout.addWidget(push_button)
        self.text_finder.setLayout(layout)
    
    def create_violation_window(self):
        """
        creating violation window which contain text editor,
        violation type and checkbox
        """
        self.create_violation_box = QGroupBox()
        layout = QGridLayout()
        layout.addWidget(self.plain_textedit, 1, 0, 12, 1)
        layout.setColumnMinimumWidth(0, 10)
        self.create_violation_box.setLayout(layout)
    
    def create_violation_text(self):
        """
        creating main violation window which contain all violations
        """
        self.plain_textedit =  QPlainTextEdit()
        self.plain_textedit.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.plain_textedit.setStyleSheet(
        """QPlainTextEdit {font-size: 14pt;
                           font-family: Courier;}""")
        self.plain_textedit.viewport().installEventFilter(self)
    

class MainWindow(QMainWindow):
    def __init__(self, waiver_files, app):
        super().__init__()
        self.width = 1100
        self.height = 700
        self.waiver_files = waiver_files
        self.app = app
        self.set_main_window()
        
        
    def set_main_window(self):
        """
        Setting main window position
        """
        self.setWindowTitle("GUI %s" %(os.path.abspath(__file__)))
        self.setFixedSize(QSize(self.width, self.height))
        wid = QDesktopWidget() 
        screen_width = wid.screen().frameGeometry().width()
        screen_height = wid.screen().frameGeometry().height()
        self.setGeometry(screen_width/2-self.width/2,
                         screen_height/2-self.height/2, 
                         self.width, self.height)
    
    def create_block(self):
        blk = BlockWindow(self.waiver_files, self.app)
        main_layout = blk.create_widget()
        window = QWidget()
        window.setLayout(main_layout)
        self.setCentralWidget(window)
    
    def eventfilter(self, obj, event):
        print ("hi")

        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow(__file__, app)
    window.create_block()
    window.show()
    app.exec_()

BlockWindow class 是一个简单的 python 对象,而 installEventFilter() 需要一个 QObject

现在你的class也完全没有用,因为它只用来调用函数和return一个对象,然后它就被彻底删除了。

您应该做的是创建您要添加的小部件的子class,并且通过这样做您还将获得事件过滤器功能(因为 QWidget 继承自 QObject)。

注意:

  • eventFilter()(有一个大写的“F”!)必须总是 return一个bool通常最好总是return 基本实现的结果 if 事件未被处理;
  • 只有在目标小部件上按下鼠标按钮或使用 setMouseTracking(True)(可以在滚动区域而不是视口上设置)时,才能跟踪鼠标移动;
class BlockWindow(QWidget):
    def __init__(self, waiver_files, app):
        super().__init__()
        self.waiver_files = waiver_files
        self.app = app

    def create_widget(self): 
        self.create_violation_text()
        self.create_violation_window()
        self.create_text_finder()
        main_layout = QVBoxLayout(self) # <- note this, equivalent to 
                                        # self.setLayout(main_layout)
        main_layout.addWidget(self.text_finder)
        main_layout.addWidget(self.create_violation_box)

    # ...

    def eventFilter(self, obj, event):
        if event.type() == event.MouseMove:
            print('mouse moving')
        return super().eventFilter(obj, event)

class MainWindow(QMainWindow):
    # ...
    def create_block(self):
        blk = BlockWindow(self.waiver_files, self.app)
        blk.create_widget()
        self.setCentralWidget(blk)

还要注意:width() and height() are existing dynamic attributes of all QWidgets, and shall not be overwritten with custom variables; the reference to the application is pointless, as it can (and should) always be get through the static QApplication.instance().