我需要将文本追加到QPlainTextEdit
不添加新行的文本,但两种方法appendPlainText()
和appendHtml()
实际上增加了新的段落。
我可以做手工用QTextCursor
:
QTextCursor text_cursor = QTextCursor(my_plain_text_edit->document());
text_cursor.movePosition(QTextCursor::End);
text_cursor.insertText("string to append. ");
这一工程,但我也需要不断滚动在底部,如果它是在追加前底部。
我试图从Qt的源文件副本的逻辑,但我坚持就可以了,因为有实际QPlainTextEditPrivate
使用类,我找不到这样做没有它的方法:比如说,我没有看到法verticalOffset()
在QPlainTextEdit
。
其实,这些来源包括许多怪异(在第一次看,至少)的东西,我不知道如何实现这一点。
这里的源代码append()
http://code.qt.io/cgit/qt/qt.git/tree/src/gui/widgets/qplaintextedit.cpp#n2763
我只是引述我发现这里:
http://www.jcjc-dev.com/2013/03/qt-48-appending-text-to-qtextedit.html
我们只需将光标移动到在的QTextEdit内容的结尾并使用insertPlainText。 在我的代码,它看起来像这样:
myTextEdit->moveCursor (QTextCursor::End);
myTextEdit->insertPlainText (myString);
myTextEdit->moveCursor (QTextCursor::End);
就如此容易。 如果你的应用需要保持光标所在是追加文本之前,你可以使用QTextCursor::position()
和QTextCursor::setPosition()
方法,或
仅仅复制光标改变其位置之前[QTextCursor QTextEdit::textCursor()]
,然后设置作为光标[void QTextEdit::setTextCursor(const QTextCursor & cursor)]
。
下面是一个例子:
QTextCursor prev_cursor = myTextEdit->textCursor();
myTextEdit->moveCursor (QTextCursor::End);
myTextEdit->insertPlainText (myString);
myTextEdit->setTextCursor (&prev_cursor);
目前的答案是不是我的选择。 这是很多simplier到没有新线,或与下面的方法添加HTML。
//logs is a QPlainTextEdit object
ui.logs->moveCursor(QTextCursor::End);
ui.logs->textCursor().insertHtml(out);
ui.logs->moveCursor(QTextCursor::End);
好吧,我不知道如果我的解决办法其实是“好”,但它似乎为我工作:我只是做了新的类QPlainTextEdit_My
继承自QPlainTextEdit
,并增加了新的方法appendPlainTextNoNL()
appendHtmlNoNL()
insertNL()
请注意:阅读PARAMS评论check_nl
和check_br
认真,这是很重要的! 我花了几个小时搞清楚为什么我的小部件很慢,当我追加文本没有新的段落。
/******************************************************************************************
* INCLUDED FILES
*****************************************************************************************/
#include "qplaintextedit_my.h"
#include <QScrollBar>
#include <QTextCursor>
#include <QStringList>
#include <QRegExp>
/******************************************************************************************
* CONSTRUCTOR, DESTRUCTOR
*****************************************************************************************/
QPlainTextEdit_My::QPlainTextEdit_My(QWidget *parent) :
QPlainTextEdit(parent)
{
}
QPlainTextEdit_My::QPlainTextEdit_My(const QString &text, QWidget *parent) :
QPlainTextEdit(text, parent)
{
}
/******************************************************************************************
* METHODS
*****************************************************************************************/
/* private */
/* protected */
/* public */
/**
* append html without adding new line (new paragraph)
*
* @param html html text to append
* @param check_nl if true, then text will be splitted by \n char,
* and each substring will be added as separate QTextBlock.
* NOTE: this important: if you set this to false,
* then you should append new blocks manually (say, by calling appendNL() )
* because one huge block will significantly slow down your widget.
*/
void QPlainTextEdit_My::appendPlainTextNoNL(const QString &text, bool check_nl)
{
QScrollBar *p_scroll_bar = this->verticalScrollBar();
bool bool_at_bottom = (p_scroll_bar->value() == p_scroll_bar->maximum());
if (!check_nl){
QTextCursor text_cursor = QTextCursor(this->document());
text_cursor.movePosition(QTextCursor::End);
text_cursor.insertText(text);
} else {
QTextCursor text_cursor = QTextCursor(this->document());
text_cursor.beginEditBlock();
text_cursor.movePosition(QTextCursor::End);
QStringList string_list = text.split('\n');
for (int i = 0; i < string_list.size(); i++){
text_cursor.insertText(string_list.at(i));
if ((i + 1) < string_list.size()){
text_cursor.insertBlock();
}
}
text_cursor.endEditBlock();
}
if (bool_at_bottom){
p_scroll_bar->setValue(p_scroll_bar->maximum());
}
}
/**
* append html without adding new line (new paragraph)
*
* @param html html text to append
* @param check_br if true, then text will be splitted by "<br>" tag,
* and each substring will be added as separate QTextBlock.
* NOTE: this important: if you set this to false,
* then you should append new blocks manually (say, by calling appendNL() )
* because one huge block will significantly slow down your widget.
*/
void QPlainTextEdit_My::appendHtmlNoNL(const QString &html, bool check_br)
{
QScrollBar *p_scroll_bar = this->verticalScrollBar();
bool bool_at_bottom = (p_scroll_bar->value() == p_scroll_bar->maximum());
if (!check_br){
QTextCursor text_cursor = QTextCursor(this->document());
text_cursor.movePosition(QTextCursor::End);
text_cursor.insertHtml(html);
} else {
QTextCursor text_cursor = QTextCursor(this->document());
text_cursor.beginEditBlock();
text_cursor.movePosition(QTextCursor::End);
QStringList string_list = html.split(QRegExp("\\<br\\s*\\/?\\>", Qt::CaseInsensitive));
for (int i = 0; i < string_list.size(); i++){
text_cursor.insertHtml( string_list.at(i) );
if ((i + 1) < string_list.size()){
text_cursor.insertBlock();
}
}
text_cursor.endEditBlock();
}
if (bool_at_bottom){
p_scroll_bar->setValue(p_scroll_bar->maximum());
}
}
/**
* Just insert new QTextBlock to the text.
* (in fact, adds new paragraph)
*/
void QPlainTextEdit_My::insertNL()
{
QScrollBar *p_scroll_bar = this->verticalScrollBar();
bool bool_at_bottom = (p_scroll_bar->value() == p_scroll_bar->maximum());
QTextCursor text_cursor = QTextCursor(this->document());
text_cursor.movePosition(QTextCursor::End);
text_cursor.insertBlock();
if (bool_at_bottom){
p_scroll_bar->setValue(p_scroll_bar->maximum());
}
}
我很困惑,因为在原来的代码也有更复杂的计算atBottom
:
const bool atBottom = q->isVisible()
&& (control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
<= viewport->rect().bottom());
和needScroll
:
if (atBottom) {
const bool needScroll = !centerOnScroll
|| control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
> viewport->rect().bottom();
if (needScroll)
vbar->setValue(vbar->maximum());
}
但我的简单的解决办法似乎工作过。
像任何字符串:
QTextEdit *myTextEdit = ui->textEdit;
myTextEdit->moveCursor (QTextCursor::End);
myTextEdit->insertPlainText (myString+"\n");
我想它和它的工作。
文章来源: How to append text to QPlainTextEdit without adding newline, and keep scroll at the bottom?