已设置滚动条时更新 WheelEvent 上的 QLineEdit

Update a QLineEdit on a WheelEvent when scroll bar is already set

我正在尝试更新 QLineEdit 当我在鼠标上进行滚轮移动并且同时按下键盘上的数字时。不幸的是,我没有看到 QLineEdit 小部件的鼠标滚轮事件,所以我不明白如何为每个 QLineEdit 设置信号。我遇到的另一个问题是 QLineEdit 已经在滚动条环境中,我无法检测到所有滚轮事件,因为滚动是先完成的。

例如使用此代码:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys


class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        super(SurfViewer, self).__init__()
        self.parent = parent

        self.centralTabs= QTabWidget()
        self.setCentralWidget(self.centralTabs)
        self.setFixedWidth(200)
        self.setFixedHeight(200)

        #tab Model selection
        self.tab_ModelSelect = QWidget()
        self.centralTabs.addTab(self.tab_ModelSelect,"Label")


        self.groupscrolllayouttest = QHBoxLayout() ####
        self.groupscrollbartest = QGroupBox() ####


        self.mainHBOX_param_scene = QVBoxLayout()
        for i in range(10):
            LineEdit = QLineEdit(str(i))
            LineEdit.setFixedWidth(200)
            self.mainHBOX_param_scene.addWidget(LineEdit) 
        self.installEventFilter(self)

        scroll = QScrollArea()
        widget = QWidget(self)
        widget.setLayout(QVBoxLayout())
        widget.layout().addWidget(self.groupscrollbartest)
        scroll.setWidget(widget)
        scroll.setWidgetResizable(True)
        self.groupscrollbartest.setLayout(self.mainHBOX_param_scene)
        self.groupscrolllayouttest.addWidget(scroll)

        self.tab_ModelSelect.setLayout(self.groupscrolllayouttest)

    def eventFilter(self, widget, event):
        if (event.type() == QEvent.Wheel) :
            # get which key is pressed 
            # if the key is a number, put the number in 'num' variable
            # get on which QLineEdit the wheel was make
            # set the text of that QLineEdit to previous value +- num

            event.ignore()
        return QWidget.eventFilter(self, widget, event) 

def main():
    app = QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.setWindowTitle('window')
    # ex.showMaximized()
    ex.show()
    sys.exit(app.exec_( ))


if __name__ == '__main__':
    main()  

我尝试用 wheelevent 做一些事情,但如前所述,我没有进入这个功能,因为滚动条首先被激活。我试图测试车轮事件是否发生在 QLineEdit 上,但我什至努力做到这一点...

我想做的是当我用鼠标在 QlineEdit 上按下“5”键时,我想将 QLineEdit 文本增加或减少 5根据鼠标滚轮的方向。

我用 eventfilter 红了一些 post(如 How to get Click Event of QLineEdit in Qt?),但我不明白它是如何工作的。

在我的 eventFilter 函数中,我需要做几个步骤:

# get which key is pressed 
# if the key is a number, put the number in 'num' variable
# get on which QLineEdit the wheel was make
# set the text of that QLineEdit to previous value +- num

但是我不知道怎么做。特别是获取按下的键并知道轮子是在哪个 QlineEdit 上制作的。

如果您希望所有 QLineEdit 都具有该行为,那么您创建自己的 class 并覆盖必要的事件是合适的,以避免当指针在 QLineEdit 内部时移动滚动条并且按下已建立的键,我们接受事件,这样它就不会传播。

另一个建议是不要使用 5 键,因为这是 QLineEdit 可以处理导致问题的文本,为此您可以使用 SHIFT 键:

class LineEdit(QLineEdit):
    KEY = Qt.Key_Shift
    def __init__(self, *args, **kwargs):
        QLineEdit.__init__(self, *args, **kwargs)
        self.isKeyPressed = False

    def keyPressEvent(self, event):
        if event.key() == LineEdit.KEY:
            self.isKeyPressed = True
        QLineEdit.keyPressEvent(self, event)

    def keyReleaseEvent(self, event):
        if event.key() == LineEdit.KEY:
            self.isKeyPressed = False
        QLineEdit.keyReleaseEvent(self, event)

    def wheelEvent(self, event):
        if self.isKeyPressed:
            delta = 1 if event.angleDelta().y() > 0 else -1
            fn = self.font()
            fn.setPointSize(fn.pointSize() +  delta)
            self.setFont(fn)
            event.accept()

完整示例:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class LineEdit(QLineEdit):
    KEY = Qt.Key_Shift
    def __init__(self, *args, **kwargs):
        QLineEdit.__init__(self, *args, **kwargs)
        self.isKeyPressed = False

    def keyPressEvent(self, event):
        if event.key() == LineEdit.KEY:
            self.isKeyPressed = True
        QLineEdit.keyPressEvent(self, event)

    def keyReleaseEvent(self, event):
        if event.key() == LineEdit.KEY:
            self.isKeyPressed = False
        QLineEdit.keyReleaseEvent(self, event)

    def wheelEvent(self, event):
        if self.isKeyPressed:
            delta = 1 if event.angleDelta().y() > 0 else -1
            fn = self.font()
            fn.setPointSize(fn.pointSize() +  delta)
            self.setFont(fn)
            event.accept()

class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        super(SurfViewer, self).__init__()
        self.parent = parent

        self.centralTabs= QTabWidget()
        self.setCentralWidget(self.centralTabs)
        self.setFixedWidth(200)
        self.setFixedHeight(200)

        #tab Model selection
        self.tab_ModelSelect = QWidget()
        self.centralTabs.addTab(self.tab_ModelSelect,"Label")


        self.groupscrolllayouttest = QHBoxLayout() ####
        self.groupscrollbartest = QGroupBox() ####


        self.mainHBOX_param_scene = QVBoxLayout()
        for i in range(10):
            le = LineEdit(str(i))
            le.setFixedWidth(200)
            self.mainHBOX_param_scene.addWidget(le) 
        self.installEventFilter(self)

        scroll = QScrollArea()
        widget = QWidget(self)
        widget.setLayout(QVBoxLayout())
        widget.layout().addWidget(self.groupscrollbartest)
        scroll.setWidget(widget)
        scroll.setWidgetResizable(True)
        self.groupscrollbartest.setLayout(self.mainHBOX_param_scene)
        self.groupscrolllayouttest.addWidget(scroll)
        self.tab_ModelSelect.setLayout(self.groupscrolllayouttest)

def main():
    app = QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.setWindowTitle('window')
    # ex.showMaximized()
    ex.show()
    sys.exit(app.exec_( ))


if __name__ == '__main__':
    main()