可编辑多色QLineEdit [英] Editable multi-color QLineEdit

查看:168
本文介绍了可编辑多色QLineEdit的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道你可以改变线条编辑的颜色,只要所有的文字是相同的颜色,但是是否可以为字符分配不同的颜色?

I know that you can change the color of a line edit, so long as all the text is the same color, but is it possible to assign different colors to characters? That is, some characters are red, and some are black, or simply every character has a different color.

这里有一个类似的问题 - 如何在QLineEdit中改变部分文本的颜色? / a>,但在我的情况下有一个额外的约束--QLineEdit必须保留编辑时的颜色位置,而输入的新文本假定一些默认颜色。另一个问题没有这个约束。

There is a similar question here - How can I change color of part of the text in QLineEdit?, but in my case there is an additional constraint - the QLineEdit must preserve color positions when edited, while new text that is entered assumes some default color. The other question does not have that constraint.

有一个答案这有点有用,但是颜色从文本中分离 - 当你编辑线编辑,恰好在给定位置的符号假定位置的颜色和格式。也就是说,格式不固定到文本。以下是2个截图,可以看到我在说什么:

It does have an answer that is somewhat useful, however the colors are detached from the text - as you edit the line edit, whichever symbol that happens to be at a given position assumes that position's colors and formatting. That is, the formatting is not anchored to the text. Here are 2 screenshots to see what I'm talking about:


我将努力解决这个缺点,当我准备好时,我将结果作为答案发布。

I will be working on a solution to that shortcoming myself, and when I'm ready, I'll post the results as an answer.

我将通过订阅 textEdited()信号,或直接处理输入事件。

I'll do that either by subscribing to the textEdited() signal, or by directly handling the input events. Each time the text is changed, I'll sync the color positions to it.

在此期间,如果有人知道我遗漏了一个可笑的简单解决方案,

In the meantime, if anyone know of a ridiculously easy solution that I've missed, or an easier approach to the problem, please feel free to share it.

推荐答案

我终于实现了它,通过跟踪光标位置,最后一个选择开始和长度,以及最后一个文本大小。当发出 textEdited()信号时,我使用它们来确定已经插入和/或删除了什么文本,然后重放插入和/或删除颜色数组,以便将其同步到文本。

I finally implemented it, by tracking the cursor position, the last selection start and length, and the last text size. When a textEdited() signal is emitted, I use them to figure out what text has been inserted and/or deleted, and then I replay the insertion and/or deletion in the color array in order to sync it to the text.

您可以指定用于用户插入的文本的颜色。如果不指定它,系统默认将使用,这将根据系统主题而有所不同。

You can specify the color to be used for text inserted by the user. If you don't specify it, the system default will be used, which will vary depending on the system theme.

唯一的问题是 it doesn' t支持撤消,因为我不知道如何区分 textEdited()信号是否由撤消操作引起。

The only problem is that it doesn't support Undo, because I have no idea how to distinguish if a textEdited() signal is caused by an Undo operation or not.

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

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

:)

这篇关于可编辑多色QLineEdit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆