【问题标题】:Went from QGraphicsView to QMainWindow now keyPressEvent doesn't see arrow keys从 QGraphicsView 到 QMainWindow 现在 keyPressEvent 没有看到箭头键
【发布时间】:2012-09-04 14:57:22
【问题描述】:

我正在尝试了解 PyQt4 中的事件处理,但偶然发现了一个案例 keyPressEvent 在我更改类定义后看到除了箭头键之外的所有键。

从看到所有键:

class MaskWindow(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)

        self.deskTop = QtGui.QDesktopWidget()
        self.scene = QtGui.QGraphicsScene(self)

看不到箭头键、向下翻页和向上翻页,但其他人可以使用,例如制表符Shifta-z

class MaskWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self, None, QtCore.Qt.WindowStaysOnTopHint|
                                   QtCore.Qt.FramelessWindowHint)            

        self.deskTop = QtGui.QDesktopWidget()
        self.view = QtGui.QGraphicsView(self)
        self.scene = QtGui.QGraphicsScene(self)

这是箭头键不再捕获的键处理程序:

def keyPressEvent(self, event):
    key = event.key()
    if key == QtCore.Qt.UpArrow
        self.diameter += 1
    if key == QtCore.Qt.DownArrow:
        self.diameter -= 1

换班时我错过了什么?

【问题讨论】:

  • 这几乎可以肯定是因为您传递给构造函数的窗口标志。你在哪个平台上?
  • 这是在 Windows 7 上。我选择了 QMainWindow,这样我就可以将窗口设置为顶部并失去边框。有没有办法用 QGraphicsView 对象来代替?
  • 请忽略我之前的评论,看我下面的回答。

标签: python event-handling pyqt4


【解决方案1】:

您重新实现的keyPressEvent 函数使用了错误的枚举常量。

应该使用QtCore.Qt.Key枚举:

def keyPressEvent(self, event):
    key = event.key()
    if key == QtCore.Qt.Key_Up:
        self.diameter += 1
    if key == QtCore.Qt.Key_Down:
        self.diameter -= 1

并且可以使用setWidowFlags 函数在任何小部件(包括QGraphicsView)上更改窗口标志:

class MaskWindow(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)
        self.setWindowFlags(self.windowFlags() |
            QtCore.Qt.WindowStaysOnTopHint |
            QtCore.Qt.FramelessWindowHint)

更新

在您的示例中,重新实现的 keyPressEvent 不能与 QMainWindow 一起使用的原因是因为它不会再获得任何键事件 - 它们将转到带有键盘焦点的子小部件。

解决此问题的一种方法是在要从中获取关键事件的小部件上设置event filter

class MaskWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self, None,
            QtCore.Qt.WindowStaysOnTopHint |
            QtCore.Qt.FramelessWindowHint)
        self.view = QtGui.QGraphicsView(self)
        self.view.installEventFilter(self)
        self.setCentralWidget(self.view)

    def eventFilter(self, source, event):
        if (source is self.view and
            event.type() == QtCore.QEvent.KeyPress):
            key = event.key()
            if key == QtCore.Qt.Key_Up:
                self.diameter += 1
            elif key == QtCore.Qt.Key_Down:
                self.diameter -= 1
        return QtGui.QMainWindow.eventFilter(self, source, event)

【讨论】:

  • 谢谢,您的建议使用 GraphicsView 窗口标志有效。我仍然不清楚为什么 QMainWindow 方法没有按照您的建议将 QtCore.Qt.UpArrow 更改为 QtCore.Qt.Key_Up 后捕获箭头键。这更多是出于好奇。
  • @Dave。我已经用更完整的解释更新了我的答案。
  • 太好了,我想我得到了大部分,除了最后的 return QtGui.QMainWindow.eventFilter(self, source, event) 。最后一行的原因是什么?
  • @Dave。调用基类eventFilter 可确保默认事件处理仍然正常工作。但是,如果您想阻止对特定事件 进行任何进一步处理,则可以直接返回True。有关详细信息,请参阅docs for eventFilter
猜你喜欢
  • 1970-01-01
  • 2011-08-10
  • 2018-09-16
  • 2010-10-27
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多