【问题标题】:Minimizing the size of a QTextEdit in a QTreeWidgetItem最小化 QTreeWidgetItem 中 QTextEdit 的大小
【发布时间】:2012-09-12 18:32:41
【问题描述】:

我有一个 QTreeWidget 填充了一些 itemwidgets,其主要小部件将是一个 QTextEdit。我遇到的问题似乎是将尺寸缩小到可以管理的程度。将大小策略设置为最大值的常用方法似乎不起作用。下面是示例代码:

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyMainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.tree = QTreeWidget(self)
        self.tree.setColumnCount(1)
        self.setCentralWidget(self.tree)

        textEdit = QTextEdit()
        textEdit.setText("very Small Text Edit")
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding)
        textEdit.setSizePolicy(sizePolicy)

        itemWidget = QTreeWidgetItem()
        itemWidget.setText(0, "")
        self.tree.addTopLevelItem(itemWidget)
        self.tree.setItemWidget(itemWidget, 0, textEdit)        

        biggerTextEdit = QTextEdit()
        biggerTextEdit.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas et mauris in felis tempus molestie eu sit amet sapien. Proin dapibus pretium ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque feugiat semper sem a accumsan. Nulla sollicitudin enim quis velit blandit posuere. Ut fringilla vulputate dolor, a accumsan lectus gravida a. Sed convallis facilisis mi et ullamcorper. Integer consectetur aliquet odio sit amet posuere.")        

        itemWidget2 = QTreeWidgetItem()
        itemWidget2.setText(0, "")
        self.tree.addTopLevelItem(itemWidget2)
        self.tree.setItemWidget(itemWidget2, 0, biggerTextEdit)        

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    ui = MyMainWindow()
    ui.show()
    sys.exit(app.exec_())

请注意,无论文本的长度如何,似乎都不会对文本编辑的高度产生任何影响。 QTextEdit 如何将自身(至少垂直)缩放到尽可能小的尺寸,并且为了知识,为什么它不像许多其他小部件那样以这种方式表现?提前致谢!

编辑:我现在应该注意到,我试图通过使用 QLabel(在调整大小、显示和文字扭曲方面,就像我想要的那样工作)并设置文本交互标志可编辑。如果有办法访问标签的编辑文本,这几乎是可行的。不幸的是,标签上的任何 .text() 调用都会产生原始文本。 QLineEdit 不能是多行或自动换行,QTextEdit 似乎过于复杂。

现在的问题是,什么是创建小型(300 个字符或更少)文本显示小部件且可编辑的最佳小部件?

【问题讨论】:

  • 文本长度对QTextEdit 的大小没有任何影响。这就是为什么它有一个可滚动的区域,这样它就可以显示任意长度的文本,而不管它的大小。你想让它随着文本的长度而调整吗?
  • 没错。理想情况下,如果 textedit 只有一行文本,例如,它的高度只有 25px。如果有三行文本,则为 75 像素。当然,这些都是估计。

标签: python pyqt4 qtextedit sizing model-view


【解决方案1】:

为了实现您的目标,您必须自定义项目代理,因为它们为您的树小部件提供演示和编辑服务。 Qt 文档有一些有用的information regarding models, views and delegates(包括tutorial)。以下代码使用委托解决了您的问题:

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyMainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.tree = QTreeWidget(self)
        self.tree.setColumnCount(1)
        self.tree.setItemDelegate(MyDelegate(self))
        self.setCentralWidget(self.tree)

        itemWidget = QTreeWidgetItem()
        itemWidget.setFlags(itemWidget.flags() | Qt.ItemIsEditable)
        itemWidget.setText(0, "very Small Text Edit")
        self.tree.addTopLevelItem(itemWidget)

        itemWidget2 = QTreeWidgetItem()
        itemWidget2.setFlags(itemWidget.flags() | Qt.ItemIsEditable)
        itemWidget2.setText(0, """very Small Text Edit\n
        very Small Text Edit\n
        very Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Editvery Small Text Edit""")
        self.tree.addTopLevelItem(itemWidget2)

class MyDelegate(QStyledItemDelegate):

    def sizeHint(self, option, index):
        default = QStyledItemDelegate.sizeHint(self, option, index)
        return QSize(default.width(), default.height() + 12)

    def createEditor(self, parent, option, index):
        editor = QTextEdit(parent)
        return editor

    def setEditorData(self, editor, index):
        text = index.model().data(index, Qt.DisplayRole).toString()
        editor.setText(text)

    def setModelData(self, editor, model, index):
        model.setData(index, QVariant(editor.toPlainText()))


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    ui = MyMainWindow()
    ui.show()
    sys.exit(app.exec_())

代码包含对sizeHint() 的简单重新实现。另请注意,您可以在 createEditor 方法中自定义您的 QTextEdit。您可能还想重新实现 paint() 方法(这取决于您的需要)。

请注意,子类化QTreeWidgetItem 不是可行的方法(它甚至不是QWidget)。然而QTreeWidget 是一个使用预定义树模型的便利类,因此在模型/视图编程框架中解决问题是有意义的。

【讨论】:

  • 看起来正是我想要的。谢谢!
【解决方案2】:

我想出了一个解决方案,它涉及将QTextEdit 子类化而不是QStyledItemDelegate。新的QTextEdit 根据内容计算它需要的高度。然后我使用信号将计算出的高度输入到QTreeWidgetItemsetSizeHint()

代码如下(PS 我用的是 PyQt5)

import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, pyqtSignal, QSize

class AdjustableTextEdit(QtWidgets.QTextEdit):

    td_size_sig=pyqtSignal(QSize)
    def __init__(self,parent=None):
        super(AdjustableTextEdit,self).__init__(parent)

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.textChanged.connect(self.resizeTextEdit)
        self.document().documentLayout().documentSizeChanged.connect(
                self.resizeTextEdit)

    def resizeTextEdit(self):

        docheight=self.document().size().height()
        margin=self.document().documentMargin()
        self.setMinimumHeight(docheight+2*margin)
        self.setMaximumHeight(docheight+2*margin)
        return

    def resizeEvent(self,e):
        super(AdjustableTextEdit,self).resizeEvent(e)
        self.td_size_sig.emit(QSize(self.sizeHint().width(),
            self.maximumHeight()))
        return

class MainFrame(QtWidgets.QFrame):

    def __init__(self,parent=None):
        super(MainFrame,self).__init__(parent)

        ha=QtWidgets.QHBoxLayout(self)
        self.tree=QtWidgets.QTreeWidget(self)
        ha.addWidget(self.tree)

        self.addTextEditWidget('very small text edit')
        self.addTextEditWidget("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas et mauris in felis tempus molestie eu sit amet sapien. Proin dapibus pretium ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque feugiat semper sem a accumsan. Nulla sollicitudin enim quis velit blandit posuere. Ut fringilla vulputate dolor, a accumsan lectus gravida a. Sed convallis facilisis mi et ullamcorper. Integer consectetur aliquet odio sit amet posuere.")

        self.show()

    def addTextEditWidget(self,text):

        textEdit = AdjustableTextEdit()
        textEdit.setText(text)

        itemWidget = QtWidgets.QTreeWidgetItem()
        itemWidget.setText(0, "")

        self.tree.addTopLevelItem(itemWidget)
        self.tree.setItemWidget(itemWidget, 0, textEdit)
        textEdit.td_size_sig.connect(lambda size: itemWidget.setSizeHint(0,size))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ui = MainFrame()
    sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多