[英]Editable multi-color QLineEdit
我知道您可以更改行編輯的顏色,只要所有文本都是相同的顏色,但是可以為字符分配不同的顏色嗎? 也就是說,有些字符是紅色的,有些是黑色的,或者只是每個字符都有不同的顏色。
這里有一個類似的問題 - 如何在QLineEdit中更改部分文本的顏色? ,但在我的情況下還有一個額外的約束 - QLineEdit必須在編輯時保留顏色位置,而輸入的新文本假定某些默認顏色。 另一個問題沒有那個限制。
它確實有一個有用的答案 ,但顏色與文本分離 - 當您編輯行編輯時,恰好在給定位置的符號假定該位置的顏色和格式。 也就是說, 格式不會錨定到文本 。 這是2個截圖,看看我在說什么:
我將自己解決這個缺點,當我准備好時,我會將結果作為答案發布。
我會通過訂閱textEdited()
信號或直接處理輸入事件來做到這一點。 每次更改文本時,我都會將顏色位置同步到它。
與此同時,如果有人知道我錯過了一個非常簡單的解決方案,或者更容易解決問題,請隨時分享。
我最終通過跟蹤光標位置,最后一個選擇開始和長度以及最后一個文本大小來實現它。 當發出textEdited()
信號時,我使用它們來確定插入和/或刪除了哪些文本,然后重放顏色數組中的插入和/或刪除,以便將其同步到文本。
您可以指定用於用戶插入的文本的顏色。 如果未指定,將使用系統默認值,具體取決於系統主題。
唯一的問題是它不支持Undo ,因為我不知道如何區分textEdited()
信號是否是由Undo操作引起的。
ColorLineEdit.h
#ifndef COLORLINEEDIT_H
#define COLORLINEEDIT_H
#include <QLineEdit>
class ColorLineEdit : public QLineEdit
{
Q_OBJECT
public:
explicit ColorLineEdit(QWidget *parent = 0);
void setCharColors(const QList<QColor> &colors = QList<QColor>());
void setColorForInsertedText(const QColor &colorForInsertedText) { this->colorForInsertedText = colorForInsertedText; }
signals:
private slots:
void onSelectionChanged();
void onTextEdited(const QString &text);
private:
int lastTextSize;
QList<QColor> colors;
QColor colorForInsertedText;
int lastSelectedTextSize;
int lastSelectionStart;
};
#endif // COLORLINEEDIT_H
ColorLineEdit.cpp
#include "colorlineedit.h"
#include <QTextLayout>
ColorLineEdit::ColorLineEdit(QWidget *parent) :
QLineEdit(parent)
{
connect(this, SIGNAL(selectionChanged()), SLOT(onSelectionChanged()));
connect(this, SIGNAL(textEdited(QString)), SLOT(onTextEdited(QString)));
lastSelectedTextSize = 0;
lastSelectionStart = -1;
lastTextSize = 0;
}
void ColorLineEdit::setCharColors(const QList<QColor> &colors)
{
// See http://stackoverflow.com/questions/14417333/how-can-i-change-color-of-part-of-the-text-in-qlineedit.
QList<QInputMethodEvent::Attribute> attributes;
int size = colors.size();
attributes.reserve(size);
for (int ii = 0; ii < size ; ii++) {
if (colors[ii].isValid()) {
QTextCharFormat charFormat;
charFormat.setForeground(QBrush(colors[ii]));
const int start = ii - cursorPosition();
const int length = 1;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, charFormat));
}
}
QLineEdit::inputMethodEvent(&QInputMethodEvent(QString(), attributes));
lastTextSize = text().size();
this->colors = colors;
}
void ColorLineEdit::onSelectionChanged()
{
lastSelectionStart = selectionStart();
lastSelectedTextSize = selectedText().size();
}
void ColorLineEdit::onTextEdited(const QString &text)
{
if (!lastSelectedTextSize) {
// We don't have a selection, so it's either
// an insertion or deletion, but not both.
int delta = text.size() - lastTextSize;
if (delta > 0) {
// User has inserted text.
int pos = cursorPosition() - delta;
for (int ii = 0; ii < delta; ii++) {
colors.insert(pos, colorForInsertedText);
}
} else {
// User has erased text.
int pos = cursorPosition();
colors.erase(colors.begin() + pos, colors.begin() + pos - delta);
}
} else {
// There was a selection, so we have both removed
// and inserted text.
int pos = lastSelectionStart;
int removedCount = lastSelectedTextSize;
int insertedCount = cursorPosition() - pos;
colors.erase(colors.begin() + pos, colors.begin() + pos + removedCount);
for (int ii = 0; ii < insertedCount; ii++) {
colors.insert(pos, colorForInsertedText);
}
}
setCharColors(colors);
}
樣品用法
#include "colorlineedit.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ColorLineEdit lineEdit;
QList<QColor> colors;
colors.append(Qt::red);
colors.append(Qt::red);
colors.append(Qt::red);
colors.append(Qt::red);
lineEdit.setText("abcd");
lineEdit.setColorForInsertedText(Qt::blue);
lineEdit.setCharColors(colors);
lineEdit.show();
return a.exec();
}
:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.