【问题标题】:How to reimplement QTextDocument createObject?如何重新实现 QTextDocument createObject?
【发布时间】:2020-05-09 08:12:19
【问题描述】:

如何重新实现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()

【问题讨论】:

    标签: python pyside2 qtextedit qtextdocument


    【解决方案1】:

    在我看来这是一个错误(我已经用 PyQt5 对其进行了测试并且它工作正常),问题是 QTextObject 的生命周期,因为在 C++ 中,生命周期是未定义的,因为它是一个指针但是作为 QTextDocument 的子级,因此它的生命周期是 QTextDocument 的生命周期,但在 python 中,它似乎认为它是一个范围有限的对象(局部变量),不尊重 QTextDocument 对其拥有的所有权,因为它是它的父级。一种解决方法似乎是让 obj 成为该类的成员:

    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 TextDocument(QtGui.QTextDocument):
        def __init__(self, parent=None):
            super(TextDocument, self).__init__(parent)
            self.objs = []
    
        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)
            self.objs.append(obj)
            return obj

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

    最后我建议报告这个错误。

    某些对象生命周期的处理似乎是 PySide2 中的一个持久性 bug。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      • 2011-02-28
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多