Событие - ловить только Qt.Key_Delete

1

Я хотел бы изменить поведение Key_Delete для QTableWidget, но из-за использования конструктора я не хочу вносить какие-либо изменения в файл py с формой. Поэтому вместо переопределения QTableWidget, как будто это ответ: Как реализовать MousePressEvent для виджета Qt-Designer в PyQt Я делаю что-то вроде этого:

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)

но это не сработает.

Теги:
pyqt4

1 ответ

4
Лучший ответ

Во-первых: "но он не работает", как правило, недостаточно описателен. Какое поведение вы ожидали? Каково было поведение, которое вы видели? Были ли сообщения об ошибках?

Я могу легко увидеть несколько ошибок здесь.

  • Вы переопределяете метод QTableWidget.keyPressEvent, который ожидает 2 аргумента: (экземпляр QTableWidget, событие). Но в коде, который вы показываете выше, функция, которую вы используете для переопределения, принимает только один аргумент (первый аргумент "self" не учитывается, поскольку он автоматически предоставляется).

  • Поскольку вы установили QTableWidget.keyPressEvent = self.test, и вы также пытаетесь вызвать эту функцию из self.test(), вы создали бесконечно рекурсивную функцию.

  • При вызове QTableWidget.keyPressEvent первым аргументом, который вы передали (self), является объект QMainWindow. Однако, как я уже упоминал выше, эта функция ожидает, что QTableWidget будет первым аргументом.

  • Поскольку вы переопределяете этот метод на уровне класса, ВСЕ 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

Наконец, другим (возможно, более чистым) подходом было бы создание подкласса QTableWdget и, в рамках конструктора, "продвигать" виджет таблицы в ваш новый класс.

  • 0
    Спасибо за ваш ответ! Под «но это не работает» я имел в виду «я не знаю, как сохранить исходное поведение других клавиш, кроме Qt.Key_Delete». Мой пример без последнего возврата работает только с клавишей Delete. Поэтому, когда я нажимаю другую клавишу в QTableWidget, чем клавиша Delete, ничего не происходит (клавиши со стрелками не работают). Я хотел бы переопределить этот метод на уровне класса . Итак, вопрос в том, что я должен изменить в своем примере кода, чтобы подавить только событие Key_Delete и передать другие события?
  • 0
    Вы можете переопределить метод класса, если хотите, вам просто нужно: 1) убедиться, что функция, с которой вы переопределяете, имеет правильную сигнатуру, и 2) сохранить ссылку на исходную функцию в другом месте, чтобы ее можно было вызывать для других ключи. Мне любопытно: почему вы хотите переопределить на уровне класса, а не экземпляра?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню