【问题标题】:QTableView intercepts Key_Down and Key_Up eventsQTableView 拦截 Key_Down 和 Key_Up 事件
【发布时间】:2014-09-26 03:13:28
【问题描述】:

我正在尝试在 QTableView 上实现“事物”。所以,我开始重写它的 keyPressEvent 方法,因为它到处都有描述:

if e.key() == QtCore.Qt.Key_F2 and self.tableau.hasFocus():
    blabla

elif e.key() == QtCore.Qt.Key_Return and self.tableau.hasFocus():
    blabla

#TEST
elif e.key() == QtCore.Qt.Key_Right:
    print("right")
elif e.key() == QtCore.Qt.Key_Down:
    print("down")
else:
    print("waza")

我可以处理 F2 和 Return 事件,它们可以工作。但不是 Key_Down 事件! Key_right 也有效,但 Down 无效。我认为这是因为 QTableWidget “拦截”了一些事件。例如,当按下普通字母时,也不会“发出”任何事件。

我想访问所有事件(或至少是 Up 和 Down 事件),我该怎么做?

编辑:

我使用的视图基本上是一个QTableView,我稍微修改了一下:

class ViewPerso(QtGui.QTableView):

    def __init__(self, parent=None):
        super(ViewPerso, self).__init__(parent)

        self.parent = parent


    def currentChanged(self, current, previous):

        index = current.sibling(current.row(), 4)

        try:
            if not index.data() or len(self.parent.vidsSelected()) > 1:
                return
        except AttributeError:
            pass

        self.clicked.emit(current)
        self.scrollTo(current)


    def keyboardSearch(self, search):

        pass

我不使用 QTableWidget,它不符合我的要求。我还对视图委托进行了子类化,但通常(通常)不会有任何干扰。

这是我使用视图的方式:加载模型、代理,然后使用视图:

    self.modele = ModelPerso()

    self.modele.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
    self.modele.setTable("videos")
    self.modele.select()

    self.proxy = QtGui.QSortFilterProxyModel()
    self.proxy.setSourceModel(self.modele)

    self.tableau = ViewPerso(self)
    self.tableau.setModel(self.proxy)
    self.tableau.setItemDelegate(ViewDelegate(self))

我不知道按键在哪里结束,现在,它们就消失了。我认为(我认为),每个小部件都有处理按键事件的方法,也许 QTableView 会忽略上下键?

【问题讨论】:

  • 请发布更多代码:您是否有单独的 tableView 和 tableWidget,或者您在谈论其他内容?你知道按键最终在哪里,还是消失了?
  • 完成。也许我应该覆盖视图类中的 keypressEvent 方法?

标签: python pyqt qtableview


【解决方案1】:

对于在课外实施, 您必须在外面覆盖此 keyPressEvent 方法。 像这个例子:

import sys
from PyQt4 import QtCore, QtGui

class ViewPerso (QtGui.QTableView):
    def __init__(self, parent = None):
        super(ViewPerso, self).__init__(parent)
        self.parent = parent

    def currentChanged (self, current, previous):
        index = current.sibling(current.row(), 4)
        try:
            if not index.data() or len(self.parent.vidsSelected()) > 1:
                return
        except AttributeError:
            pass
        self.clicked.emit(current)
        self.scrollTo(current)

    def keyboardSearch (self, search):
        pass

class exampleQMainWindow (QtGui.QMainWindow):
    def __init__ (self):
        super(exampleQMainWindow, self).__init__()
        testQTableWidget = ViewPerso(self)
        self.setCentralWidget(testQTableWidget)
        testQTableWidget.keyPressEvent = self.keyPressEvent

    def keyPressEvent (self, eventQKeyEvent):
        key = eventQKeyEvent.key()
        if key == QtCore.Qt.Key_F1:
            print 'Help'
        elif key == QtCore.Qt.Key_F5:
            print 'Reload'
        elif key == QtCore.Qt.Key_Left:
            print 'Left'
        elif key == QtCore.Qt.Key_Up:
            print 'Up'
        elif key == QtCore.Qt.Key_Right:
            print 'Right'
        elif key == QtCore.Qt.Key_Down:
            print 'Down'

app = QtGui.QApplication([])
window = exampleQMainWindow()
window.show()
sys.exit(app.exec_())

【讨论】:

  • 嗯,好的,这段代码有效,它打印了它必须做的事情。至少现在我知道 QTableView 类处理了一些按键事件。可以肯定的是,在 Qt 代码中,QTableView 的 keypressEvent 方法对 Qt.Key_Down 做了一些事情。那么,是否可以在 ViewPerso 的 keyPressEvent 方法中使用 super(),然后将事件发送到类之外,以便在主代码中使用它?我想对 ViewPerso 类之外的事件执行操作。
  • 您可以使用 SIGNAL() 连接您的课外活动。另一种方式,您可以在类外覆盖 keyPressEvent 方法。请阅读我上次编辑的帖子“已编辑:2014 年 3 月 8 日 11:49”。
【解决方案2】:

好吧,我终于做到了:

class ViewPerso (QtGui.QTableView):
    def __init__(self, parent = None):
        super(ViewPerso, self).__init__(parent)
        self.parent = parent

    def currentChanged (self, current, previous):
        index = current.sibling(current.row(), 4)
        try:
            if not index.data() or len(self.parent.vidsSelected()) > 1:
                return
        except AttributeError:
            pass
        self.clicked.emit(current)
        self.scrollTo(current)

    def keyboardSearch (self, search):
        pass

    def keyPressEvent (self, e):
        super(ViewPerso, self).keyPressEvent(e)
        e.ignore()

该事件可能卡在 ViewPerso 中,因此通过像这样覆盖它的 keyPressEvent 方法,我得到了 QTableWidget 对事件所做的通常处理,并且我将事件传播到父窗口小部件,所以我可以再次使用它。

我尝试按照您在编辑中显示的内容进行操作,但这对我来说根本不起作用,我真的不知道为什么。我的程序也很大(约 10k 行),所以原因可能来自任何地方。但感谢让我意识到错误来自哪里。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 2017-01-10
    • 2015-11-05
    • 2021-06-27
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多