【问题标题】:A QWidget like QTextEdit that wraps its height automatically to its contents?像 QTextEdit 这样的 QWidget 会自动将其高度包装到其内容中吗?
【发布时间】:2012-08-07 17:24:13
【问题描述】:

我正在创建一个带有一些 QTextEdit 小部件的表单。

QTextEdit 的默认高度超过单行文本,并且当内容的高度超过 QTextEdit 的高度时,它会创建一个滚动条来滚动内容。

我想重写此行为以创建一个 QTextEdit,它宁愿将其高度包装到其内容中。这意味着默认高度将为一行,并且在换行或输入新行时,QTextEdit 将自动增加其高度。每当内容高度超过 QTextEdit 的高度时,后者不应创建滚动条而只是增加高度。

我该怎么做呢?谢谢。

【问题讨论】:

    标签: python qt4 pyqt4 qtextedit


    【解决方案1】:

    这几乎就像我前几天回答的一个问题,关于让 QTextEdit 调整其高度以响应内容更改:PySide Qt: Auto vertical growth for TextEdit Widget

    我正在回答而不是标记重复,因为我怀疑您可能想要对此进行更改。如果您希望我扩展此答案,请告诉我:

    另一个问题有多个部分。以下是不断增长的高度小部件的摘录:

    class Window(QtGui.QDialog):
    
        def __init__(self):
            super(Window, self).__init__()
            self.resize(600,400)
    
            self.mainLayout = QtGui.QVBoxLayout(self)
            self.mainLayout.setMargin(10)
    
            self.scroll = QtGui.QScrollArea()
            self.scroll.setWidgetResizable(True)
            self.scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
            self.mainLayout.addWidget(self.scroll)
    
            scrollContents = QtGui.QWidget()
            self.scroll.setWidget(scrollContents)
    
            self.textLayout = QtGui.QVBoxLayout(scrollContents)
            self.textLayout.setMargin(10)
    
            for _ in xrange(5):
                text = GrowingTextEdit()
                text.setMinimumHeight(50)
                self.textLayout.addWidget(text)
    
    
    class GrowingTextEdit(QtGui.QTextEdit):
    
        def __init__(self, *args, **kwargs):
            super(GrowingTextEdit, self).__init__(*args, **kwargs)  
            self.document().contentsChanged.connect(self.sizeChange)
    
            self.heightMin = 0
            self.heightMax = 65000
    
        def sizeChange(self):
            docHeight = self.document().size().height()
            if self.heightMin <= docHeight <= self.heightMax:
                self.setMinimumHeight(docHeight)
    

    【讨论】:

    • 这正是我所需要的。虽然我的搜索词没有遇到这个。谢谢!
    • 另外(我在你的另一篇文章中看不到)我必须连接以下内容,以便在调整 QTextEdit 的大小时将其高度包装到其文档中:self.document().documentLayout().documentSizeChanged.connect(self.wrapHeightToContents)
    • 如果您在我的示例中看到我正在使用更高的不同信号。我不需要任何其他连接
    • @jdi 您连接的信号在c++中受到保护
    • @chacham15:感谢您为任何 c++ 用户指出这一点。幸运的是,这个问题围绕着 python 绑定:-)
    【解决方案2】:

    以下代码将 QTextEdit 小部件设置为内​​容的高度:

    # using QVBoxLayout in this example
    grid = QVBoxLayout()
    text_edit = QTextEdit('Some content. I make this a little bit longer as I want to see the effect on a widget with more than one line.')
    
    # read-only
    text_edit.setReadOnly(True)
    
    # no scroll bars in this example
    text_edit.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
    text_edit.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
    text_edit.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
    
    # you can set the width to a specific value
    # text_edit.setFixedWidth(400)
    
    # this is the trick, we nee to show the widget without making it visible.
    # only then the document is created and the size calculated.
    
    # Qt.WA_DontShowOnScreen = 103, PyQt does not have this mapping?!
    text_edit.setAttribute(103)
    text_edit.show()
    
    # now that we have a document we can use it's size to set the QTextEdit's size
    # also we add the margins
    text_edit.setFixedHeight(text_edit.document().size().height() + text_edit.contentsMargins().top()*2)
    
    # finally we add the QTextEdit to our layout
    grid.addWidget(text_edit)
    

    我希望这会有所帮助。

    【讨论】:

    • 这是一个非常有趣的技巧,但我的一部分认为必须有其他方法。但我的另一部分意识到这可能是实践中最好的方法,因为您不必计算框架宽度等并计算出所有这些。
    • 技术上contentsMargins().top() + contentsMargins().bottom()contentsMargins().top()*2 更正确,尽管这些值通常相同。
    猜你喜欢
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 2023-04-01
    • 2016-04-01
    • 1970-01-01
    • 2021-08-29
    相关资源
    最近更新 更多