事件 - 仅捕获 Qt.Key_Delete

1 投票
1 回答
5130 浏览
提问于 2025-04-16 16:11

我想改变QTableWidget中删除键(Key_Delete)的行为,但因为我使用了Designer,所以不想在py文件中做任何修改。因此,我不打算像这个回答中那样重新实现QTableWidget:如何在PyQt中为Qt-Designer小部件实现MousePressEvent,我做了类似这样的事情:

class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
    QtGui.QWidget.__init__(self, parent)
    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)

    self.ui.tableWidget.__class__.keyPressEvent = self.test

def test(self,event):
    if event.key() == Qt.Key_Delete:
        print "test"

    return QTableWidget.keyPressEvent(self, event)

问题是,我不知道如何保持除了Qt.Key_Delete以外其他按键的原始行为。我已经把最后一行改成这样:

return QtGui.QTableWidget.keyPressEvent(self, event)
return QtGui.QTableWidget.event(self, event)

但这样并没有效果。

1 个回答

4

首先,“但它不工作”通常不够具体。你期待什么样的行为?你看到的是什么行为?有没有错误信息?

不过,我可以很容易地发现这里有几个错误。

  1. 你在重写 QTableWidget 的 keyPressEvent 方法,这个方法需要两个参数:(QTableWidget 实例,事件)。但是在你上面展示的代码中,你用来重写它的函数只接受一个参数(第一个参数 'self' 是自动提供的,所以不算)。

  2. 因为你把 QTableWidget.keyPressEvent 设置为 self.test,并且你还试图在 self.test() 内部调用这个函数,这样就造成了一个无限递归的函数。

  3. 当你调用 QTableWidget.keyPressEvent 时,你传入的第一个参数(self)是一个 QMainWindow 对象。然而,正如我上面提到的,这个函数的第一个参数应该是 QTableWidget。

  4. 因为你是在 级别重写这个方法,所以所有的 QTableWidgets 都会被迫使用同一个 keyPressEvent 函数(这会很麻烦)。相反,你应该只重写你特定小部件的方法:self.ui.tableWidget.keyPressEvent = self.test (另外要注意,tableWidget.keyPressEvent 的签名和 QTableWidget.keyPressEvent 是不同的)

示例:

from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
win = QtGui.QMainWindow()
win.show()

table = QtGui.QTableWidget()
win.setCentralWidget(table)
def test(event):
    if event.key() == QtCore.Qt.Key_Delete:
        print "delete"
    return QtGui.QTableWidget.keyPressEvent(table, event)
table.keyPressEvent = test

最后,另一种(可能更简洁的)方法是创建一个 QTableWidget 的子类,并在 Designer 中将表格小部件“提升”到你的新类。

撰写回答