在Qt框架中如何实现自动扩展的QPlainTextEdit组件?
PySide6 实现方案
要实现初始一行高度、输入时自动适配内容高度且无滚动条的QPlainTextEdit,核心思路是监听文本变化,动态计算内容所需高度并调整组件尺寸,同时禁用滚动条。
代码示例
from PySide6.QtWidgets import QApplication, QPlainTextEdit, QWidget, QVBoxLayout from PySide6.QtGui import QFontMetrics from PySide6.QtCore import Qt class AutoResizePlainTextEdit(QPlainTextEdit): def __init__(self, parent=None): super().__init__(parent) # 禁用滚动条 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 初始设置为一行高度 self.setFixedHeight(self._get_line_height()) # 监听文本变化信号 self.textChanged.connect(self._adjust_height) def _get_line_height(self): # 获取单行文本的高度,加少量内边距优化显示 fm = QFontMetrics(self.font()) return fm.lineSpacing() + 4 def _adjust_height(self): # 让文档宽度适配组件视口,确保高度计算准确 doc = self.document() doc.setTextWidth(self.viewport().width()) content_height = doc.size().height() # 最小高度保持一行 min_height = self._get_line_height() self.setFixedHeight(max(int(content_height) + 8, min_height)) if __name__ == "__main__": app = QApplication([]) window = QWidget() layout = QVBoxLayout(window) text_edit = AutoResizePlainTextEdit() layout.addWidget(text_edit) window.show() app.exec()
关键细节
- 禁用滚动条避免内容被截断或出现滚动区域
- 初始高度基于字体行高计算,保证空状态为一行
- 文本变化时通过文档尺寸计算内容总高度,动态调整组件固定高度
- 添加额外内边距是为了避免文本紧贴组件边缘,提升视觉体验
C++ 实现方案
逻辑与PySide6一致,通过子类化QPlainTextEdit实现自动高度调整。
代码示例
#include <QApplication> #include <QPlainTextEdit> #include <QFontMetrics> #include <QVBoxLayout> #include <QWidget> class AutoResizePlainTextEdit : public QPlainTextEdit { Q_OBJECT public: explicit AutoResizePlainTextEdit(QWidget *parent = nullptr) : QPlainTextEdit(parent) { // 禁用滚动条 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 初始设置为一行高度 setFixedHeight(getLineHeight()); // 绑定文本变化信号 connect(this, &QPlainTextEdit::textChanged, this, &AutoResizePlainTextEdit::adjustHeight); } private: int getLineHeight() { // 计算单行文本高度,添加内边距 QFontMetrics fm(font()); return fm.lineSpacing() + 4; } private slots: void adjustHeight() { QTextDocument *doc = document(); doc->setTextWidth(viewport()->width()); qreal contentHeight = doc->size().height(); int minHeight = getLineHeight(); setFixedHeight(qMax(static_cast<int>(contentHeight) + 8, minHeight)); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget window; QVBoxLayout *layout = new QVBoxLayout(&window); AutoResizePlainTextEdit *textEdit = new AutoResizePlainTextEdit; layout->addWidget(textEdit); window.show(); return a.exec(); } #include "main.moc"
关键细节
- 同样通过禁用滚动条消除滚动区域
- 利用
QTextDocument的尺寸计算内容高度,确保组件高度完全适配文本 - 初始高度基于字体行高设置,保证空状态下的一行显示
内容的提问来源于stack exchange,提问作者Dmitry Kabanov
相关产品推荐
相关产品推荐

