如何在不添加换行符的情况下将文本附加到QPlainTextEdit,并在底部保持滚动?

时间:2012-11-26 06:52:57

标签: c++ qt newline qplaintextedit

我需要在不向文字添加换行符的情况下将文字附加到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

的源代码

4 个答案:

答案 0 :(得分:24)

我只想引用我在这里找到的内容:

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);

答案 1 :(得分:10)

目前的答案对我来说不是一个选择。使用以下方法添加没有新行的html要简单得多。

//logs is a QPlainTextEdit object
ui.logs->moveCursor(QTextCursor::End);
ui.logs->textCursor().insertHtml(out);
ui.logs->moveCursor(QTextCursor::End);

答案 2 :(得分:4)

好吧,我不确定我的解决方案是否真的“好”,但它似乎对我有用:我刚刚从QPlainTextEdit_My继承了新的QPlainTextEdit个类,并添加了新的方法{ {1}},appendPlainTextNoNL()appendHtmlNoNL()

请注意:仔细阅读有关params insertNL()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

但我的简单解决方案似乎也有效。

答案 3 :(得分:0)

像任何字符串一样:

<script src="http://s7.addthis.com/js/300/addthis_widget.js#pubid=ra-xxxxx&async=1" type="text/javascript">

我尝试了它并且有效。