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

如何去除PyQt5中QPlainTextEdit组件底部的空白区域

如何去除PyQt5中QPlainTextEdit组件底部的空白区域?

问题复现

以下是能复现该问题的示例代码:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 130)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.plainTextEdit.setStyleSheet("padding:0px;")
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.gridLayout.addWidget(self.plainTextEdit, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.plainTextEdit.setPlainText(_translate("MainWindow", "1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\n1\nlast line."))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

运行效果:
运行效果截图

已尝试的方案

你已经尝试过调整文档边距、计算文本高度并设置固定高度等操作,但未完全解决问题:

# self.main_self.ui_scheduled_transmitions_create_window.review_text.setPlainText("")
self.main_self.ui_scheduled_transmitions_create_window.review_text.setPlainText(review_text)
self.main_self.ui_scheduled_transmitions_create_window.review_text.setDocumentTitle("123")
# if self.main_self.ui_scheduled_transmitions_create_window.review_text.height()<800:
#    self.main_self.ui_scheduled_transmitions_create_window.review_text.setFixedHeight(self.main_self.ui_scheduled_transmitions_create_window.review_text.height())
# else:
#    self.main_self.ui_scheduled_transmitions_create_window.review_text.setFixedHeight(800)

self.main_self.ui_scheduled_transmitions_create_window.review_text.document().setDocumentMargin(0)

# self.main_self.ui_scheduled_transmitions_create_window.review_text.setCenterOnScroll(False)
m =  self.main_self.ui_scheduled_transmitions_create_window.review_text.fontMetrics()
RowHeight = m.lineSpacing()
nRows = self.main_self.ui_scheduled_transmitions_create_window.review_text.document().blockCount()
text_height = RowHeight*nRows

document_format = self.main_self.ui_scheduled_transmitions_create_window.review_text.document().rootFrame().frameFormat()
document_format.setBottomMargin(0)
document_format.setHeight(text_height)
self.main_self.ui_scheduled_transmitions_create_window.review_text.document().rootFrame().setFrameFormat(document_format)
scrollBarHeight=self.main_self.ui_scheduled_transmitions_create_window.review_text.horizontalScrollBar().sizeHint().height()
# scrollBarHeight=0
if text_height+scrollBarHeight>800:
    self.main_self.ui_scheduled_transmitions_create_window.review_text.setFixedHeight(600)
else:
    self.main_self.ui_scheduled_transmitions_create_window.review_text.setFixedHeight(text_height+scrollBarHeight)

解决方案

方法1:精确计算内容高度并调整组件尺寸

问题核心是QPlainTextEdit的文档会预留额外空间,默认行高计算可能忽略文本块的上下边距。通过以下步骤解决:

  • 清除文档、根框架、文本块的所有边距
  • 逐块计算文本总高度
  • 结合水平滚动条高度设置组件固定高度

修改后的代码示例:

def adjust_plain_text_edit_height(plain_text_edit):
    # 清除文档边距
    plain_text_edit.document().setDocumentMargin(0)
    # 清除根框架边距
    frame_format = plain_text_edit.document().rootFrame().frameFormat()
    frame_format.setMargin(0)
    plain_text_edit.document().rootFrame().setFrameFormat(frame_format)
    # 清除文本块边距
    block_format = QtGui.QTextBlockFormat()
    block_format.setTopMargin(0)
    block_format.setBottomMargin(0)
    cursor = QtGui.QTextCursor(plain_text_edit.document())
    cursor.select(QtGui.QTextCursor.Document)
    cursor.mergeBlockFormat(block_format)
    
    # 计算总内容高度
    fm = plain_text_edit.fontMetrics()
    total_height = 0
    block = plain_text_edit.document().firstBlock()
    while block.isValid():
        total_height += fm.lineSpacing()
        block = block.next()
    
    # 考虑水平滚动条的高度(如果显示的话)
    scroll_bar_height = plain_text_edit.horizontalScrollBar().sizeHint().height() if plain_text_edit.horizontalScrollBar().isVisible() else 0
    # 设置固定高度
    plain_text_edit.setFixedHeight(total_height + scroll_bar_height)

# 在setupUi之后调用
ui.setupUi(MainWindow)
adjust_plain_text_edit_height(ui.plainTextEdit)

方法2:重写QPlainTextEdit的sizeHint方法

如果需要组件自动适应内容高度,可以自定义继承类,重写sizeHint方法实现动态适配:

class AutoHeightPlainTextEdit(QtWidgets.QPlainTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.document().setDocumentMargin(0)
        frame_format = self.document().rootFrame().frameFormat()
        frame_format.setMargin(0)
        self.document().rootFrame().setFrameFormat(frame_format)
        
    def sizeHint(self):
        fm = self.fontMetrics()
        total_height = 0
        block = self.document().firstBlock()
        while block.isValid():
            total_height += fm.lineSpacing()
            block = block.next()
        scroll_bar_height = self.horizontalScrollBar().sizeHint().height() if self.horizontalScrollBar().isVisible() else 0
        return QtCore.QSize(self.width(), total_height + scroll_bar_height)

# 使用自定义类替换原有的QPlainTextEdit
# 在setupUi中修改:
self.plainTextEdit = AutoHeightPlainTextEdit(self.centralwidget)

方法1适合静态内容场景,方法2适合内容动态变化时自动调整高度的场景,两种方案都能彻底消除底部空白。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:07:20