代码之家  ›  专栏  ›  技术社区  ›  Stewart

一行上有多种颜色的QPlainTextEdit

  •  0
  • Stewart  · 技术社区  · 6 年前

    医生太长了,读不下去了。

    QPlainTextEdit::appendPlainText(QString) QPlainTextEdit::insertPlainText(QString) 似乎不受影响 setCurrentCharFormat() .

    有没有一种方法可以在收听当前节目时附加文本 QTextCharFormat 不插入换行符

    细节

    我有一个“终端”样式的小部件,它从子进程的stdout中获取文本,并将其显示在 QPlainTextEdit

    在我拥有色彩内容之前,我可以简单地做到:

    void ProcessWidget::appendText(QString text)
    {
        m_textedit->appendPlainText(text);
    }
    

    文本中使用转义字符显示颜色 '\033' 然后是颜色。我可以检测颜色并适当设置托盘:

    void ProcessWidget::appendText(QString text)
    {
        Qt::GlobalColor colour = GetColour(text);
    
        QTextCharFormat tf = m_textedit->currentCharFormat();
        tf.setForeground(QBrush(colour));
        m_textedit->setCurrentCharFormat(tf);
    
        m_textedit->appendPlainText(text);
    }
    

    如果每一行只有一种颜色,这是可行的,但是如果我的颜色在每一行的中间变化,那么我需要更疯狂一点:

    std::map<QString, Qt::GlobalColor>   m_colours;
    QPlainTextEdit*                      m_textedit;
    ...
    
    void ProcessWidget::AppendText(QString text)
    {
        while(true)
        {
            int iColour = text.indexOf('\033');
    
            if (iColour == -1)
                break;
    
            QString pretext = text.mid(0, iColour);
    
            if (!pretext.isEmpty())
            {
                m_textedit->appendPlainText(pretext);
            }
    
            text.remove(0, iColour);
    
            for (auto pair : m_colours)
            {
                if ( text.startsWith(pair.first) )
                {
                    QTextCharFormat tf = m_textedit->currentCharFormat();
                    tf.setForeground(QBrush(pair.second));
                    m_textedit->setCurrentCharFormat(tf);
                    text.remove(0, pair.first.size());
                    break;
                }
            }
        }
    
        if (!text.isEmpty())
        {
            m_textedit->appendPlainText(text);
        }
    }
    

    但是,因为我用 appendPlainText() ,每一种新的颜色都给了我一条新的线。

    添加纯文本() 使用:

    m_textedit->moveCursor (QTextCursor::End);
    m_textedit->insertPlainText(text);
    m_textedit->moveCursor (QTextCursor::End);
    

    '\n' 最后。但是那样的话,我再也没有颜色了。我也试过了 appendHtml() 但这似乎没什么区别。

    1 回复  |  直到 4 年前
        1
  •  3
  •   eyllanesc RAHUL KUMAR    6 年前

    对于这些情况,最简单的方法是使用HTML并插入标记: <font color = "..."> </ font>

    例子:

    #include <QApplication>
    #include <QDateTime>
    #include <QPlainTextEdit>
    #include <QTimer>
    #include <QVBoxLayout>
    #include <QWidget>
    
    const std::map<QString, QColor> m_colours {{"red", QColor(Qt::red)},
                                               {"blue", QColor(Qt::blue)},
                                               {"green", QColor(Qt::green)}
                                              };
    
    class ProcessWidget: public QWidget{
        Q_OBJECT
    public:
        ProcessWidget(QWidget *parent=nullptr):
            QWidget(parent),
            lay{this}
        {
            m_textedit.setReadOnly(true);
            lay.addWidget(&m_textedit);
        }
    public slots:
        void appendText(const QString & text){
            QString html{text};
            int j = 0;
            bool start = true;
            QString textColor;
    
            while ((j = html.indexOf(QChar('\033'), j)) != -1) {
                html.remove(j, 1);
                QColor color;
                for(auto & pair : m_colours){
                    if(html.mid(j).startsWith(pair.first)){
                        color = pair.second;
                        html.remove(j, pair.first.length());
                    }
                }
                if(start){
                    textColor = QString("<font color=\"%1\">").arg(color.name());
                    start = false;
                }
                else
                    textColor = QString("</font><font color=\"%1\">").arg(color.name());
                html.insert(j, textColor);
                j += 1+textColor.length();
            }
            html.append("</font>");
            m_textedit.appendHtml(html);
        }
    private:
        QPlainTextEdit m_textedit;
        QVBoxLayout lay;
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        ProcessWidget w;
        QTimer timer;
        QObject::connect(&timer, &QTimer::timeout, [&w](){
            QString text = QString("\033redDateTime: %1 \033blueDate:%2 \033greenTime:%3")
                    .arg(QDateTime::currentDateTime().toString())
                    .arg(QDate().currentDate().toString())
                    .arg(QTime::currentTime().toString());
            w.appendText(text);
        });
        timer.start(1000);
        w.show();
        return a.exec();
    }
    
    #include "main.moc"
    

    enter image description here