2012-11-26 17 views
23

मुझे पाठ में एक नई लाइन जोड़ने के बिना QPlainTextEdit पर पाठ जोड़ने की आवश्यकता है, लेकिन दोनों विधियों appendPlainText() और appendHtml() वास्तव में नया पैराग्राफ जोड़ता है।न्यूलाइन जोड़ने के बिना QPlainTextEdit में टेक्स्ट कैसे संलग्न करें, और नीचे स्क्रॉल रखें?

मैं QTextCursor साथ मैन्युअल रूप से ऐसा कर सकते हैं:

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

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

यही काम करता है, लेकिन मैं यह भी तल पर स्क्रॉल रखने के लिए अगर यह संलग्न पहले तल पर था की जरूरत है।

मैंने क्यूटी के स्रोतों से तर्क की प्रतिलिपि बनाने की कोशिश की, लेकिन मैं इस पर अटक गया, क्योंकि वास्तव में QPlainTextEditPrivate कक्षा का उपयोग किया जाता है, और मुझे इसके बिना ऐसा करने का तरीका नहीं मिल रहा है: कहें, मुझे विधि नहीं दिखाई दे रही है QPlainTextEdit में verticalOffset()

दरअसल, इन स्रोतों में कई अजीब होते हैं (कम से कम, कम से कम) चीजें, और मुझे नहीं पता कि इसे कैसे कार्यान्वित किया जाए। http://code.qt.io/cgit/qt/qt.git/tree/src/gui/widgets/qplaintextedit.cpp#n2763

उत्तर

2

ठीक है मुझे यकीन है कि अगर मेरे समाधान वास्तव में "अच्छा" है नहीं कर रहा हूँ, लेकिन यह मेरे लिए काम करने लगता है:

यहाँ append() के स्रोत कोड है मैं सिर्फ नए वर्ग QPlainTextEdit_MyQPlainTextEdit से विरासत में मिला दिया, और नई विधियों को जोड़ा appendPlainTextNoNL(), appendHtmlNoNL(), insertNL()

नोट करें: पैरामीटर check_nl और check_br ध्यान के बारे में टिप्पणी पढ़ने, यह महत्वपूर्ण है! मैंने यह पता लगाने में कई घंटे बिताए कि जब मैं नए पैराग्राफ के बिना टेक्स्ट जोड़ता हूं तो मेरा विजेट इतना धीमा क्यों होता है।

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

लेकिन मेरे आसान उपाय भी काम करने लगता है

/****************************************************************************************** 
* 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 की अधिक जटिल गणनाओं संदेह में हूँ।

+1

कम से कम क्यूटी 5.2.1 insertPlainText()/text_cursor.insertText() पर एक नई लाइन का सामना करते समय स्वचालित रूप से ब्लॉक डालने लगता है। – iliis

19

मैं सिर्फ बोली हूँ मैं यहाँ क्या मिला:

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

एक मामूली सुधार, setTextCursor एक QTextCursor लेता है, पॉइंटर नहीं। स्रोत: http://doc.qt.io/qt-4.8/qplaintextedit.html#setTextCursor। आपका लिंक भी नीचे है। – awakenDeepBlue

8

वर्तमान उत्तर मेरे लिए एक विकल्प नहीं था। निम्न विधि के साथ कोई नई लाइन के साथ एचटीएमएल जोड़ने के लिए यह बहुत आसान था।

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

यह उत्तर मेरे लिए एक विकल्प नहीं है, क्योंकि: (1) यह मौजूदा डेटा की स्थिति नीचे नहीं है, भले ही यह नए डेटा पर स्क्रॉलिंग रखता है। यह बहुत परेशान है: जबकि नया डेटा आता है, उपयोगकर्ता डेटा को जांचने में असमर्थ है जो पहले जोड़ा गया था; और (2) जब नया डेटा आता है, तो यह उपयोगकर्ता के चयन को साफ़ करता है। शायद, कुछ मामलों में यह व्यवहार स्वीकार्य है, लेकिन मेरे मामले में, यह बहुत उपयोगकर्ता-असभ्य है। –

-2

किसी भी स्ट्रिंग की तरह:

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

मैं इसे करने की कोशिश की और यह काम किया।

+0

कोड के रूप में इसे प्रारूपित करने के लिए कोड के सामने 4 रिक्त स्थान का उपयोग करें। –

+0

यह उत्तर पहले ही दिया जा चुका है। –