如何重新实现QTextDocument createObject?

How to reimplement QTextDocument createObject?

如何重新实现 QTextDocument.createObject

此方法在制作QTextFrameQTextListQTextTable或其他QTextObject.

中发挥作用

根据woboq,我认为我的重新实现是一样的。

但是内核停止了。

为什么?我的代码缺少什么?

from PySide2 import QtWidgets
from PySide2 import QtGui
from PySide2 import QtCore
import PySide2
import sys
import os
dirname = os.path.dirname(PySide2.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path
class TextEdit(QtWidgets.QTextEdit):
    def __init__(self, parent=None):
        super(TextEdit, self).__init__(parent=None)
        document = TextDocument(self)
        self.setDocument(document)            
class TextDocument(QtGui.QTextDocument):
    def __init__(self, parent=None):
        super(TextDocument, self).__init__(parent=None)      
        self.setParent(parent)    
    def createObject(self, f):
        obj = QtGui.QTextObject(self)
        if f.isListFormat():
            obj = QtGui.QTextList(self)
        elif f.isTableFormat():
            obj = QtGui.QTextTable(self)
        elif f.isFrameFormat():            
            obj = QtGui.QTextFrame(self)                
        return obj       
def main():
    if QtWidgets.QApplication.instance() is not None:
        app = QtWidgets.QApplication.instance()
    else:
        app = QtWidgets.QApplication([])
    mainwindow = TextEdit()
    mainwindow.show()
    sys.exit(QtWidgets.QApplication.exec_())
if __name__ == "__main__":
    main()

在我看来这是一个错误(我已经用 PyQt5 测试过它并且它工作正常),问题是 QTextObject 的生命周期因为在 C++ 中生命周期是未定义的,因为它是指针但是是 QTextDocument 的 child 所以它的生命周期是 QTextDocument 的生命周期,但是在 python 中它似乎认为它是一个 object 有限范围(局部变量)不尊重QTextDocument 拥有的所有权,因为它是它的 parent。解决方法似乎是使 obj 成为 class:

的成员
def createObject(self, f):
    self.obj = QtGui.QTextObject(self)
    if f.isListFormat():
        self.obj = QtGui.QTextList(self)
    elif f.isTableFormat():
        self.obj = QtGui.QTextTable(self)
    elif f.isFrameFormat():
        self.obj = QtGui.QTextFrame(self)
    return self.obj

或使用属于 class 的容器。

class TextDocument(QtGui.QTextDocument):
    def __init__(self, parent=None):
        super(TextDocument, self).__init__(parent)
        <b>self.objs = []</b>

    def createObject(self, f):
        obj = QtGui.QTextObject(self)
        if f.isListFormat():
            obj = QtGui.QTextList(self)
        elif f.isTableFormat():
            obj = QtGui.QTextTable(self)
        elif f.isFrameFormat():
            obj = QtGui.QTextFrame(self)
        <b>self.objs.append(obj)</b>
        return obj

我更喜欢第二种解决方法,因为在第一种情况下,如果创建多个 QTextObject 可能会产生问题,因为前一个会被删除。

最后我建议报告错误。

某些 object 的生命周期处理似乎是 PySide2 中的一个持续性错误。