Python 为keyPressEvent重写子类化QTextEdit是唯一的方法吗?

Python 为keyPressEvent重写子类化QTextEdit是唯一的方法吗?,python,qt,user-interface,textview,pyside2,Python,Qt,User Interface,Textview,Pyside2,我正在用PySide2构建一个Qt应用程序,它至少有一个类似texteditor的视图。我有两个原因想修改QTextEdit的keyPressEvent方法的功能: 添加用户定义的键盘操作来操作文本的功能(例如使用tab/shift+tab的标准缩进/缩进,尽管还有许多其他功能) 为了方便将来的一些功能,显示的文本将存储在一个完全不同的结构中(不是HTML/RTF/等,而是一个树)。这让我相信,我不能将QTextEdit用作组合视图+控制器,但必须提取控制器逻辑,以便在每次按键后正确修改底层结构

我正在用PySide2构建一个Qt应用程序,它至少有一个类似texteditor的视图。我有两个原因想修改QTextEdit的
keyPressEvent
方法的功能:

  • 添加用户定义的键盘操作来操作文本的功能(例如使用tab/shift+tab的标准缩进/缩进,尽管还有许多其他功能)
  • 为了方便将来的一些功能,显示的文本将存储在一个完全不同的结构中(不是HTML/RTF/等,而是一个树)。这让我相信,我不能将QTextEdit用作组合视图+控制器,但必须提取控制器逻辑,以便在每次按键后正确修改底层结构,并将生成的文本提供给QTextEdit。(尽管如此,我考虑过利用QTextEdit在引擎盖下使用HTML的事实,可能使用
    div
    a
    标记隐藏结构。下面的注释
  • 考虑到Python是被解释的,这两者的结合——再加上同时使用QSyntaxHighlighter的愿望——让我感到担忧。如果每个按键上都执行了大量的业务逻辑,那么它最终可能会非常引人注目。现在,我不想过早地进行优化,但我希望避免走上一条可能需要花费更多时间进行更改的道路。我只是好奇,如果没有写C++中的QTEXTITE子类,如果有其他的方法,我还没想到它可能会更有性能。

    或者,如果QTextEdit需要一个C++子类,如果重写<代码> KyPrExsEvs<代码>是最好的方法。


    注意:以下更新与将业务登录注入QTextEdit的输入处理(并划分视图/控制器职责)的愿望没有直接关系,而是向具有与第2项类似用例的任何其他人提供信息:只是在QtDesigner中玩转小部件,而且无论是
    锚定还是
    标记都不能至少“标记”结构元素,同时用户也看不见。(
    不随文本移动,并且
    始终移动到头部)。

    您可以使用事件过滤器处理按键操作,而无需子类化
    QTextEdit

    from PySide import QtCore, QtGui
    
    class Window(QtGui.QWidget):
        def __init__(self):
            QtGui.QWidget.__init__(self)
            self.edit = QtGui.QTextEdit(self)
            self.edit.installEventFilter(self)
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(self.edit)
    
        def eventFilter(self, widget, event):
            if (event.type() == QtCore.QEvent.KeyPress and
                widget is self.edit):
                key = event.key()
                if key == QtCore.Qt.Key_Escape:
                    print('escape')
                else:
                    if key == QtCore.Qt.Key_Return:
                        self.edit.setText('return')
                    elif key == QtCore.Qt.Key_Enter:
                        self.edit.setText('enter')
                    return True
            return QtGui.QWidget.eventFilter(self, widget, event)
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.setGeometry(500, 300, 300, 300)
        window.show()
        sys.exit(app.exec_())
    

    (刚刚测试过)是的,这确实消除了子类的需要(对于案例1)。然而,同样的问题也会出现,因为所有的逻辑都是用Python处理的,这听起来像是过早的优化。但一般来说,您可以采用任何CPU密集型算法,将其移植到C/C++并将其转换为Python扩展,从而在Python/Qt.mmm中维护大部分应用程序逻辑。您的上一个版本与您在上一部分中指出的内容无关。对我来说,这闻起来像一个,你的具体目标是什么?。或者更糟糕的是,你的问题太宽泛了,一个问题不要问太多。我不认为这太多。我想问的是,我向输入处理过程中注入代码的建议是否不是一个最佳的解决方案。我提供了更大的背景来解释我为什么要这么做。不过,我要澄清一下,我指出这一点是因为费里的答案符合“1”,你应该可以把它扩展到“2”,但它显然很复杂。我认为,如果您绕过keyPressEvent的先决条件为“2”创建一个新问题会更好,例如:“我想要X、Y和Z,例如,如果我写“W”必须发生“W”,等等。到目前为止,我尝试使用keyPressEvent:show code,等等”。这将更具可扩展性。因为从标题“you force”中可以看出解决方案是keyPressEvent,可能还有另一种选择,例如,可以使用QShortcuts替换fferri的答案