我覆盖了widget QTextEdit的keyPressEven():
void myTextEdit::keyPressEvent(QKeyEvent *e)
{
if(e->key()==Qt::Key_0)
{
qDebug() << "Ok";
}
}
按钮0工作 - 显示“Ok”,但不写入QTextEdit字段。为什么?谢谢你。
答案 0 :(得分:2)
如果要保留默认行为,则需要调用基类实现:
void myTextEdit::keyPressEvent(QKeyEvent *e)
{
if(e->key()==Qt::Key_0)
{
qDebug() << "Ok";
}
QTextEdit::keyPressEvent(e);
}
请参阅keyPressEvent的文档。
答案 1 :(得分:0)
如果有人使用 PySide2
在覆盖 QTextEdit
的内置键绑定时遇到问题,我会在此处发布我的解决方案。希望这对 C++ 也有用。
我们在应用程序中使用 QTextEdit
并希望分发一系列键绑定,但文本编辑器已经有几个硬编码绑定。我们希望编辑器忽略它们并将它们交给它的父级,以便我们的代码最终可以处理它们。
虽然文档说每当一个事件被忽略时(例如通过在安装的 True
方法中返回 eventFilter
)它会自动传递给父级,但事实是当为预定义的keybindings QTextEdit
没有交出它们:事件被忽略并被吸收。因此,以这种方式过滤的任何 textedit 内置键绑定都将被有效地全局禁用。
通过编辑器 sendEvent
内的 eventFilter
传递的直接事件有一个有趣的效果:
sendEvent
并返回 super().sendEvent
时,编辑器会执行键绑定并将事件传递给接收器。sendEvent
并返回 True
时,未执行键绑定,并且未将事件传递给接收器。sendEvent
并返回 False
时,键绑定没有被执行,并且事件被传递给接收者两次。此外:
event.ignore()
没有任何效果:编辑器无论如何都会执行内置的。event.spontaneous()
进行区分导致由于缺少指针而导致段错误。可能有些东西被垃圾回收了,但没有尝试调试。也许我错过了什么。无论如何,下面我会详细介绍对我有用的方法。
计划是完全阻止该事件,但通过 signals
广播它,然后在我们想要的任何地方连接到它们。在您的文本编辑器实例中,定义信号,例如如下:
eventCatched = QtCore.Signal(QtCore.QEvent)
然后,例如以下事件过滤器将阻止执行一些键绑定,并通过 eventCatched
发出一次:
def eventFilter(self, obj, evt):
"""
Remember to install via self.installEventFilter(self)
"""
catch_control_keys = {QtCore.Qt.Key_Left, QtCore.Qt.Key_Right}
catch = False
# documentation for keys and modifiers:
# https://doc.qt.io/qtforpython-5/PySide2/QtCore/Qt.html
if evt.type() == QtCore.QEvent.KeyPress:
modifiers = evt.modifiers()
ctrl = bool(modifiers & QtCore.Qt.ControlModifier)
shift = bool(modifiers & QtCore.Qt.ShiftModifier)
alt = bool(modifiers & QtCore.Qt.AltModifier)
key = evt.key()
# catch all undo/redo builtins
if ((ctrl and shift and key == QtCore.Qt.Key_Z) or
evt.matches(QtGui.QKeySequence.Undo) or
evt.matches(QtGui.QKeySequence.Redo)):
catch = True
# catch specified control-keys
if ctrl and not shift and not alt:
if key in catch_control_keys:
catch = True
#
if catch:
# block event but send it as signal
self.eventCatched.emit(evt)
return True
else:
return super().eventFilter(obj, evt)
然后,我们可以随意连接信号到任何我们想要的地方,我们只需要一个处理事件的方法。就我而言,我只是想将它们传递给主窗口,这可以在构造函数中使用以下单行代码来完成:
text_editor.eventCatched.connect(lambda evt: QtCore.QCoreApplication.sendEvent(self, evt))
这样,每当我们在文本编辑器中捕获一个事件时,它将被忽略并且不会以标准方式传播。相反,将发出一个信号,我们可以订阅该信号,例如在不同的点重新启动传播树,如此处通过 sendEvent
所示。
希望这有帮助!
干杯,
安德烈斯