最近做开放项目时,遇到了这样一个需求:使用QTextEdit编辑文本,随着编辑文本的变化,窗口高度自适应拉伸。
实现该功能的核心思想:响应QTextEdit::textChanged消息,实时获取QTextEdit高度,当编辑框内容的高度超过最小值时,需要修改QTextEdit的高度。
对于TextEdit编辑框自动拉伸的功能,很多博友也有记录,今天主要是针对踩坑经验分析,为大家分享!
首先看一下实现效果~
接下来,详细讲述如何实现该功能吧!
VS2017 + Qt5.14.2
默认拖出来的控件,当编辑的文本高度超出可视化区域后会出现垂直滚动条。为了不显示右侧滚动条,需要将滚动条属性关闭。
因为要随着文本的变化而改变编辑框的高度,所以,需要在QTextEdit::textChanged中实时获取编辑框中内容的实际高度。
需要记录两个高度值:
当控件的高度实时变化时,清空所有文本需要恢复到默认高度。
定义变量:m_nEditDefaultHeight;
在每次进行文本变化时,需要与上次的高度进行对比,只有在高度变化时才需要更新控件的区域,减少了交互。适用于widget窗口中控件较多、层级较多时,页面刷新不及时问题。这里请大家一定要注意,很好提高性能的方法!
定义变量:m_nEditLastHeight;
获取内容变化时,编辑框内容的高度值。
int nHeight = ui.editContent->document()->size().height();
当获取的高度值小于初始高度值时,不做任何处理。
if (nHeight < m_nEditDefaultHeight)
{
//当前编辑框的内容高度 < 最小值时
nHeight = m_nEditDefaultHeight;
}
当前内容高度大于默认值时,并且与上一次记录的最新高度值(m_nEditLastHeight)不一致时,再进行控件变化。
if (nHeight == m_nEditLastHeight)
{
//当前内容高度,和上次记录高度一致时,不做处理
}
else
{
//当前输入的高度超过文本展示最小值时,更新高度
m_nEditLastHeight = nHeight;
QRect rectOldContent = ui.editContent->geometry();
ui.editContent->setGeometry(rectOldContent.left(), rectOldContent.top(), rectOldContent.width(), nHeight);
}
以上就是简单的实现方式,实时的改变Edit的高度。
这一部分就是我在开发过程中遇到的踩坑问题。
QString qsContent = QStringLiteral("测试文本!");
ui.editContent->setPlainText(qsContent);
int nHeight = ui.editContent->document()->size().rheight();
此时nHeight就是实际编辑内容的高度值。需要注意,这里是rheight(),与响应消息中仅有一个字母之差!
这个问题,遇到的举手~
是不是问题1的代码写的不对?No!代码没问题,有问题的是调用时机不对!
当需要展示编辑框的父窗口未显示时,直接调用问题1的这块代码,获取的nHeight一定是0。
例如:QTestWidget中需要展示该编辑框的自适应功能。
那么写法一定是如下方式,一定要先show出窗口来。
QTestWidget *widget = new QTestWidget(this);
widget->show();
widget->功能设置();
很多人在获取不到有效高度值时,都会下意识的认为,是不是没有自适应大小的原因?
其实在实现之初我也应用了该功能:
ui.editContent->setPlainText("需要展示的文本");
QTextDocument *doc = m_editContent->document();
doc->adjustSize();
int nHeight = doc->size().rheight();
但是当窗口中控件较多,进行控件焦点切换时,你就会发现,编辑框中的文本会莫名其妙的自动换行,而且实时输入文本时,也会自动换行。展示效果真是让人匪夷所思!
doc->adjustSize();慎写!
以上就是我在实现QTextEdit高度实时拉伸时遇到的坑以及功能实现,希望对大家有所帮助!
我是糯诺诺米团,一名C++开发程序媛~