我正在制作一個應用程式并QTextBrowser用于顯示訊息。它應該決議 ascii 顏色,所以我的類 ( say MessageBoard) 是從QTextBrowser. 我可以MessageBoard在插入之前替換 ascii 顏色代碼并根據 ascii 代碼設定的文本顏色。
但是插入文本的方法有很多種QTextBrowser,所以MessageBoard應該能夠準確檢測文本插入的位置以及它的長度。
問題是,QTextBrowser(通過QTextEdit)僅提供 textChanged 信號,但無法獲取發生更改的位置。
那么有沒有辦法得到它或者我錯過了什么?
我已經解決了這個問題,但這是我遇到的問題(參見 main.cpp)。留言板.h
#ifndef MESSAGEBOARD_H
#define MESSAGEBOARD_H
#include <QTextBrowser>
#define AC_BLACK "\u001b[30m"
#define AC_RED "\u001b[31m"
#define AC_GREEN "\u001b[32m"
#define AC_YELLOW "\u001b[33m"
#define AC_BLUE "\u001b[34m"
#define AC_MAGENTA "\u001b[35m"
#define AC_CYAN "\u001b[36m"
#define AC_WHITE "\u001b[37m"
#define AC_RESET "\u001b[0m"
using AsciiStringPos = std::pair<int /*index*/,int /*length*/>;
class MessageBoard : public QTextBrowser
{
public:
MessageBoard(QWidget *parent = nullptr);
void appendText(const QByteArray &text);
~MessageBoard();
private:
std::pair<AsciiStringPos,QColor> find_ascii(const QByteArray &text, int starts_from);
private:
std::map<QByteArray, QColor> m_colors;
};
#endif // MESSAGEBOARD_H
留言板.cpp
#include "MessageBoard.h"
#include <QRegularExpression>
#include <climits>
MessageBoard::MessageBoard(QWidget *parent)
: QTextBrowser(parent),
m_colors({
{QByteArray(AC_BLACK) , Qt::black},
{QByteArray(AC_RED) , Qt::red},
{QByteArray(AC_GREEN) , Qt::green},
{QByteArray(AC_YELLOW) , Qt::yellow},
{QByteArray(AC_BLUE) , Qt::blue},
{QByteArray(AC_MAGENTA) , Qt::magenta},
{QByteArray(AC_CYAN) , Qt::cyan},
{QByteArray(AC_WHITE) , Qt::white}
})
{
m_colors.insert({QByteArray(AC_RESET) , textColor()});
}
void MessageBoard::appendText(const QByteArray &text)
{
int index = 0;
QTextCursor text_cursor = textCursor();
text_cursor.movePosition(QTextCursor::End);
auto res = find_ascii(text,0);
while(res.first.first != -1) //color string's index
{
text_cursor.insertText(text.mid(index,res.first.first - index));//append text before the color
QTextCharFormat format;
format.setForeground(res.second); //set color to charformat
text_cursor.setCharFormat(format); //set charformat
index = res.first.first //color string started from
res.first.second; //color string length
res = find_ascii(text,index); //find next color
}
text_cursor.insertText(text.mid(index));
}
std::pair<AsciiStringPos, QColor> MessageBoard::find_ascii(const QByteArray &text, int starts_from)
{
QByteArray first_color;
int min_index = INT_MAX;
for(const auto &p : m_colors)
{
int index = text.indexOf(p.first,starts_from);
if(index != -1 && min_index > index)
{
min_index = index;
first_color = p.first;
}
}
if(first_color.isNull())
return {{-1,0},m_colors[QByteArray(AC_RESET)]};
else
return {{min_index,first_color.length()},m_colors[first_color]};
}
MessageBoard::~MessageBoard()
{
}
主程式
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MessageBoard w;
//appendText is manually created, so I can parse text before inserting.
w.appendText(AC_GREEN "This is written with " AC_RED " Ascii " AC_GREEN " escaped words." AC_RESET);
//append, can't do the same because I don't know the location where it was inserted.
w.append(AC_MAGENTA "This won't be written in magenta.");
w.appendText(AC_CYAN "This will be written in cyan" AC_RESET);
w.zoomIn(5);
w.show();
return a.exec();
}
輸出影像
uj5u.com熱心網友回復:
我已經解決了。我將QDocument的contentsChange信號與MessageBoard2stextInserted插槽連接起來。每當插入任何文本時,我都會復制它們并將其從檔案中洗掉,然后決議其 ascii 顏色代碼并根據代碼設定顏色。然后我插入文本,更改文本顏色,插入文本,我通過回圈遞回地進行。這是我的代碼
MessageBoard2.h #ifndef MESSAGEBOARD2_H #define MESSAGEBOARD2_H
#include <QTextBrowser>
#define AC_BLACK "\u001b[30m"
#define AC_RED "\u001b[31m"
#define AC_GREEN "\u001b[32m"
#define AC_YELLOW "\u001b[33m"
#define AC_BLUE "\u001b[34m"
#define AC_MAGENTA "\u001b[35m"
#define AC_CYAN "\u001b[36m"
#define AC_WHITE "\u001b[37m"
#define AC_RESET "\u001b[0m"
class MessageBoard2 : public QTextBrowser
{
private:
class SearchResults{
private:
struct result_t{
std::size_t index;
std::size_t length;
QColor color;
};
std::vector<result_t> vec;
std::size_t iterator;
public:
SearchResults() : iterator(0){}
bool hasMatch() const {return !vec.empty();}
bool hasNext() const {return iterator < vec.size();}
const result_t &next() {return vec[iterator ];}
friend class ::MessageBoard2;
};
public:
MessageBoard2(QWidget *parent = nullptr);
~MessageBoard2();
SearchResults find_ascii(const QString &text, int starts_from);
private slots:
void textInserted(int pos, int sub, int add);
void parseAndInsert(const QString &text);
private:
bool m_should_react; //prevent recursive calls
QTextDocument *m_document;
std::map<QString, QColor> m_colors;
};
#endif // MESSAGEBOARD2_H
留言板2.cpp
#include "MessageBoard2.h"
#include <QRegularExpressionMatch>
#include <QTextBlock>
MessageBoard2::MessageBoard2(QWidget *parent) :
QTextBrowser(parent),
m_colors({
{QStringLiteral(AC_BLACK) , Qt::black},
{QStringLiteral(AC_RED) , Qt::red},
{QStringLiteral(AC_GREEN) , Qt::green},
{QStringLiteral(AC_YELLOW) , Qt::yellow},
{QStringLiteral(AC_BLUE) , Qt::blue},
{QStringLiteral(AC_MAGENTA) , Qt::magenta},
{QStringLiteral(AC_CYAN) , Qt::cyan},
{QStringLiteral(AC_WHITE) , Qt::white}
}),
m_should_react(true)
{
m_colors.insert({QStringLiteral(AC_RESET),textColor()});
m_document = document();
connect(m_document,&QTextDocument::contentsChange,this,&MessageBoard2::textInserted);
}
MessageBoard2::~MessageBoard2()
{
}
void MessageBoard2::textInserted(int pos, int sub, int add)
{
if(m_should_react && add > 0)
{
QTextCursor text_cursor = textCursor();
text_cursor.setPosition(pos);
text_cursor.setPosition(pos add,QTextCursor::KeepAnchor);
QString text = text_cursor.selectedText();
m_should_react = false;
text_cursor.removeSelectedText();
setTextCursor(text_cursor);
parseAndInsert(text);
m_should_react = true;
}
}
void MessageBoard2::parseAndInsert(const QString &text)
{
int index = 0;
QTextCursor text_cursor = textCursor();
text_cursor.movePosition(QTextCursor::End);
SearchResults results = find_ascii(text,0);
while(results.hasNext()) //color string's index
{
const SearchResults::result_t &result = results.next();
text_cursor.insertText(text.mid(index,result.index - index));//append text before the color
QTextCharFormat format;
format.setForeground(result.color);
text_cursor.setCharFormat(format);
index = result.index //color string started from
result.length; //color string length
}
text_cursor.insertText(text.mid(index));
}
MessageBoard2::SearchResults MessageBoard2::find_ascii(const QString &text, int starts_from)
{
QRegularExpressionMatchIterator itr = QRegularExpression("\u001b\\[\\d m").globalMatch(text);
SearchResults results;
while(itr.hasNext())
{
QRegularExpressionMatch match = itr.next();
auto it = m_colors.find(match.captured());
if(it != m_colors.end())
{
SearchResults::result_t result;
result.index = match.capturedStart();
result.length = match.capturedLength();
result.color = it->second;
results.vec.push_back(result);
}
std::cout << std::endl;
}
return results;
}
主程式
#include "MessageBoard2.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MessageBoard2 w;
//execpt setPlainText function, I can parse the strings and set color accordingly.
w.textCursor().insertText(AC_GREEN "This is written with " AC_RED " Ascii " AC_GREEN " escaped words." AC_RESET);
w.insertPlainText(AC_MAGENTA "This will be written in magenta.");
w.append(AC_CYAN "This will be written in cyan" AC_RESET);
w.zoomIn(5);
w.show();
return a.exec();
}
輸出影像
uj5u.com熱心網友回復:
如果我很好地理解您的要求,我想您可能想使用此信號https://doc.qt.io/qt-5/qtextdocument.html#contentsChange
您將可以訪問QTextDocument此https://doc.qt.io/qt-5/qtextedit.html#document-prop
uj5u.com熱心網友回復:
我希望當我們收到信號“textChanged”時,可以使用“ toplainText() ”函式來獲取文本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/386155.html
上一篇:ldd--version和ldd-r-va.out的輸出不匹配
下一篇:在哪里使用std::span?
