QPlainTextEdit 一行有多种颜色
QPlainTextEdit with multiple colours on a line
tl;博士:
QPlainTextEdit::appendPlainText(QString)
将换行符附加到我的文本小部件。 QPlainTextEdit::insertPlainText(QString)
似乎不受 setCurrentCharFormat()
.
的影响
有没有办法在不插入换行符的情况下在收听当前 QTextCharFormat
的同时追加文本
详情
我有一个“终端”样式的小部件,它从子进程的标准输出中获取文本并将其显示在 QPlainTextEdit
。
在我有颜色内容之前,我可以简单地这样做:
void ProcessWidget::appendText(QString text)
{
m_textedit->appendPlainText(text);
}
文本中使用转义符 '3'
后跟颜色来显示颜色。我可以检测颜色并适当地设置调色板:
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('3');
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()
,找到的每种新颜色都会给我一个新行。
我尝试将 appendPlainText()
替换为:
m_textedit->moveCursor (QTextCursor::End);
m_textedit->insertPlainText(text);
m_textedit->moveCursor (QTextCursor::End);
然后在末尾添加 '\n'
。但在那种情况下,我再也得不到任何颜色了。我也试过 appendHtml()
但这似乎没有什么不同。
对于这些情况,最简单的方法是使用 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('3'), 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("3redDateTime: %1 3blueDate:%2 3greenTime:%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"
tl;博士:
QPlainTextEdit::appendPlainText(QString)
将换行符附加到我的文本小部件。 QPlainTextEdit::insertPlainText(QString)
似乎不受 setCurrentCharFormat()
.
有没有办法在不插入换行符的情况下在收听当前 QTextCharFormat
的同时追加文本
详情
我有一个“终端”样式的小部件,它从子进程的标准输出中获取文本并将其显示在 QPlainTextEdit
。
在我有颜色内容之前,我可以简单地这样做:
void ProcessWidget::appendText(QString text)
{
m_textedit->appendPlainText(text);
}
文本中使用转义符 '3'
后跟颜色来显示颜色。我可以检测颜色并适当地设置调色板:
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('3');
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()
,找到的每种新颜色都会给我一个新行。
我尝试将 appendPlainText()
替换为:
m_textedit->moveCursor (QTextCursor::End);
m_textedit->insertPlainText(text);
m_textedit->moveCursor (QTextCursor::End);
然后在末尾添加 '\n'
。但在那种情况下,我再也得不到任何颜色了。我也试过 appendHtml()
但这似乎没有什么不同。
对于这些情况,最简单的方法是使用 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('3'), 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("3redDateTime: %1 3blueDate:%2 3greenTime:%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"