Возможно, это задано много раз, но я не могу найти решение.
У меня есть диалог:
class PostDialog(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.ui = Ui_Dialog() #code from designer!!
self.ui.setupUi(self)
self.ui.plainTextEdit = ContentEditor()
В этом диалоговом окне есть конструктор QPlainTextEdit.
Мне нужно переопределить keyPress и keyRelease этого QPlainTextEdit.
Итак, я подклассифицировал его:
class ContentEditor(QtGui.QPlainTextEdit):
def __init__(self, parent=None):
QtGui.QPlainTextEdit.__init__(self, parent)
def keyPressEvent(self, event):
print "do something"
но ContentEditor.keyPressEvent никогда не вызывается! Зачем?
Я рекомендую использовать installEventFilter для этой цели:
Это будет выглядеть так:
class PostDialog(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.ui = Ui_Dialog() #code from designer!!
self.ui.setupUi(self)
self.ui.plainTextEdit.installEventFilter(self)
def eventFilter(self, event):
if event.type() == QtCore.QEvent.KeyPress:
# do some stuff ...
return True # means stop event propagation
else:
return QtGui.QDialog.eventFilter(self, event)
То, что вы пытаетесь сделать, лучше сделать продвигать в Qt Designer виджет QPlainTextEdit в ваш подкласс ContentEditor.
Документация Qt
В диалоговом окне "Продвинутые виджеты":
"Продвинуть имя класса": ContentEditor
"Файл заголовка": your_python_module_name.h
Возможно, вам нужно вызвать метод setFocusPolicy
QWidget для получения события KeyPress.
Из документов API QWidget для метода keyPressEvent:
This event handler, for event event, can be reimplemented in a subclass to receive key press events for the widget. A widget must call setFocusPolicy() to accept focus initially and have focus in order to receive a key press event.
Вам, вероятно, просто нужно будет поменять следующие две строки:
self.ui.setupUi(self)
self.ui.plainTextEdit = ContentEditor()
Если вы напишете это так:
self.ui.plainTextEdit = ContentEditor()
self.ui.setupUi(self)
вы убедитесь, что ваш пользовательский виджет привязан до того, как пользовательский интерфейс будет настроен. В противном случае вы просто заменяете ссылку на уже инициализированный объект.