You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5自定义QTextEdit自动伸缩异常:窗口未同步调整求助

问题解决:PyQt5实现随内容伸缩的QTextEdit并同步窗口尺寸

问题背景

需要实现自定义QTextEdit控件:输入换行时高度自动增加,删除内容时高度缩小。当前代码运行后,QTextEdit尺寸变化时窗口大小固定,导致上方聊天区域控件被异常拉伸,目标是让窗口随QTextEdit尺寸同步调整,避免其他控件变形。

解决方案

核心调整方向:

  • 为上方聊天区域的QScrollArea设置合理尺寸策略,确保垂直方向仅在窗口有多余空间时扩展,而非被压缩
  • 修改CustomTextEdit的高度控制逻辑,用最小高度替代固定高度,允许窗口整体调整尺寸
  • 触发顶层窗口布局更新,确保控件尺寸变化被正确传递

修改后的完整代码

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys

class App(QWidget):
    def __init__(self):
        super().__init__()

        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.layout)

        self.init_ui()

    def init_ui(self):
        ### ChatWidget ###
        chat_widget = QWidget(self)
        chat_widget.setObjectName("chatbox")
        chat_widget.setStyleSheet("#chatbox {background-color: black; border: 0;}")

        chat_widget.scroll_area = QScrollArea(self)
        chat_widget.scroll_area.setWidgetResizable(True)
        chat_widget.scroll_area.setWidget(chat_widget)
        chat_widget.scroll_area.setStyleSheet("""
        QScrollArea {
        }
        QScrollBar:vertical {
            background-color: black;
            color: white;
        }
        """)

        # 关键修改:设置ScrollArea尺寸策略,垂直方向为Expanding并保留最小高度
        chat_widget.scroll_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        chat_widget.setMinimumHeight(449)
        chat_widget.setMinimumWidth(300)
        chat_widget.scroll_area.setMinimumHeight(453)
        chat_widget.scroll_area.setMinimumWidth(333)

        self.layout.addWidget(chat_widget.scroll_area)
        ###

        ### CustomTextEdit ###
        self.text_edit = CustomTextEdit(5, self)
        self.layout.addWidget(self.text_edit)
        self.text_edit.setStyleSheet("""
        font-size: 12pt;
        """)
        QTimer().singleShot(5, self.text_edit.update_height)
        ###

class CustomTextEdit(QTextEdit):
    def __init__(self, max_lines=5, parent=None):
        super().__init__(parent)
        self.max_lines = max_lines
        # 关键修改:调整尺寸策略,垂直方向设为Minimum以支持窗口动态调整
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.document().contentsChanged.connect(self.update_height)

        # 初始设置最小高度而非固定高度
        self.setMinimumHeight(self.fontMetrics().height())

    def update_height(self):
        document_height = self.document().size().height()
        line_height = self.fontMetrics().lineSpacing()

        text_layout = self.document().documentLayout()
        block = self.document().begin()
        num_lines = 0
        while block.isValid():
            layout = block.layout()
            num_lines += layout.lineCount()
            block = block.next()

        desired_height = document_height + self.contentsMargins().top() + self.contentsMargins().bottom()

        if num_lines > self.max_lines:
            self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            # 超过最大行数时固定高度,避免无限增高
            self.setFixedHeight(int(line_height * self.max_lines + self.contentsMargins().top() + self.contentsMargins().bottom()))
        else:
            self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            # 未超过时设置最小高度,允许窗口扩展
            self.setMinimumHeight(int(desired_height))
            # 触发顶层窗口调整,同步尺寸变化
            if self.parent():
                self.parent().adjustSize()

    def scroll_to_bottom(self):
        scrollbar = self.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app_widget = App()
    app_widget.show()
    sys.exit(app.exec_())

关键修改说明

  1. 聊天区域ScrollArea配置:将尺寸策略设为(Expanding, Expanding)并保留最小高度,确保它仅在窗口有额外空间时扩展,不会被QTextEdit的尺寸变化压缩。
  2. CustomTextEdit高度控制:
    • 初始化用setMinimumHeight替代setFixedHeight,允许控件高度动态调整
    • 未超过最大行数时设置最小高度,让窗口可以整体放大
    • 超过最大行数时固定高度并显示滚动条,限制控件高度上限
  3. 窗口同步调整:在update_height中调用parent().adjustSize(),确保顶层窗口感知控件尺寸变化并同步更新自身大小。

内容的提问来源于stack exchange,提问作者ExUltra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:07:20