web-dev-qa-db-de.com

Wie füge ich Text an QPlainTextEdit an, ohne Zeilenumbrüche hinzuzufügen, und halte den Bildlauf unten weiter?

Ich muss Text an QPlainTextEdit anfügen, ohne dem Text eine neue Zeile hinzuzufügen, aber beide Methoden appendPlainText() und appendHtml() fügen tatsächlich einen neuen Absatz hinzu.

Ich kann das manuell mit QTextCursor machen:

QTextCursor text_cursor = QTextCursor(my_plain_text_edit->document());
text_cursor.movePosition(QTextCursor::End);

text_cursor.insertText("string to append. ");

Das funktioniert, aber ich muss auch weiter unten scrollen, wenn es vor dem Anhängen unten war.

Ich habe versucht, die Logik aus Qts Quellen zu kopieren, aber ich bin dabei geblieben, weil dort tatsächlich QPlainTextEditPrivate-Klasse verwendet wird und ich den Weg nicht finden kann, ohne dasselbe zu tun: Ich sehe die Methode verticalOffset() nicht in QPlainTextEdit.

Tatsächlich enthalten diese Quellen viele seltsame (zumindest auf den ersten Blick) Dinge, und ich habe keine Ahnung, wie ich das implementieren soll.

Hier ist der Quellcode von append(): http://code.qt.io/cgit/qt/qt.git/tree/src/gui/widgets/qplaintextedit.cpp#n2763

26
Dmitry Frank

Ok, ich bin nicht sicher, ob meine Lösung eigentlich "Nice" ist, aber es scheint für mich zu funktionieren: Ich habe gerade eine neue Klasse QPlainTextEdit_My von QPlainTextEdit geerbt und neue Methoden appendPlainTextNoNL(), appendHtmlNoNL(), insertNL() hinzugefügt.

Bitte beachten Sie: Lesen Sie die Kommentare zu den Parametern check_nl und check_br sorgfältig durch. Dies ist wichtig! Ich habe mehrere Stunden damit verbracht, herauszufinden, warum mein Widget so langsam ist, wenn ich Text ohne neue Absätze anhebe.

/******************************************************************************************
 * 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());
   }
}

Ich bin verwirrt, weil es im Originalcode viel kompliziertere Berechnungen von atBottom gibt:

const bool atBottom =  q->isVisible()
                       && (control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
                           <= viewport->rect().bottom());

und needScroll:

if (atBottom) {
    const bool needScroll =  !centerOnScroll
                             || control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
                             > viewport->rect().bottom();
    if (needScroll)
        vbar->setValue(vbar->maximum());
}

Aber meine einfache Lösung scheint auch zu funktionieren.

4
Dmitry Frank

Ich zitiere einfach, was ich hier gefunden habe:

http://www.jcjc-dev.com/2013/03/qt-48-appending-text-to-qtextedit.html


Wir müssen nur den Cursor an das Ende des Inhalts in QTextEdit bewegen und insertPlainText verwenden. In meinem Code sieht das so aus:

myTextEdit->moveCursor (QTextCursor::End);
myTextEdit->insertPlainText (myString);
myTextEdit->moveCursor (QTextCursor::End);

So einfach ist das. Wenn Ihre Anwendung den Cursor an der Stelle halten muss, an der er sich vor dem Anhängen des Texts befunden hat, können Sie die Methoden QTextCursor::position() und QTextCursor::setPosition() verwenden, oder

kopieren Sie einfach den Cursor, bevor Sie seine Position [QTextCursor QTextEdit::textCursor()] ändern, und setzen Sie diese dann als Cursor [void QTextEdit::setTextCursor(const QTextCursor & cursor)]

Hier ist ein Beispiel:

QTextCursor prev_cursor = myTextEdit->textCursor();
myTextEdit->moveCursor (QTextCursor::End);
myTextEdit->insertPlainText (myString);
myTextEdit->setTextCursor (&prev_cursor);
23
david

Die aktuelle Antwort war für mich keine Option. Es war viel einfacher, HTML mit der folgenden Methode ohne neue Zeilen einzufügen.

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

Wie jede Saite:

    QTextEdit *myTextEdit = ui->textEdit;
    myTextEdit->moveCursor (QTextCursor::End);
    myTextEdit->insertPlainText (myString+"\n");

Ich habe es versucht und es hat funktioniert.

0
Nabil