Pregunta

Yo sé que usted puede cambiar el color de una línea de edición, siempre y cuando todo el texto es el mismo color, pero es posible asignar diferentes colores a los personajes?Es decir, algunos personajes son de color rojo, y algunos son de color negro, o simplemente cada personaje tiene un color diferente.

Hay una pregunta similar aquí - ¿Cómo puedo cambiar el color de una parte del texto en QLineEdit?, pero en mi caso no hay una restricción adicional - el QLineEdit debe conservar posiciones de color cuando se editó, mientras que el nuevo texto que se introduce asume un color predeterminado.La otra pregunta no tiene esa restricción.

Es tiene una respuesta que es algo útil, sin embargo, los colores se separan del texto - como se edita la línea de edición, cualquiera sea el símbolo que pasa a ser en una posición dada se supone que la posición de los colores y el formato.Es decir, el formato no está anclado en el texto.Aquí hay 2 capturas de pantalla para ver de qué estoy hablando:

enter image description here enter image description here

Voy a estar trabajando en una solución a ese inconveniente mí mismo, y cuando estoy listo, voy a publicar los resultados como una respuesta.

Voy a hacer eso, ya sea mediante la suscripción del textEdited() de la señal, o directamente mediante el manejo de los eventos de entrada.Cada vez que se cambia el texto, voy a sincronizar las posiciones de color a la misma.

En el ínterin, si alguien sabe de un ridículamente fácil solución que he echado de menos, o un enfoque más sencillo para el problema, por favor siéntase libre para compartir.

¿Fue útil?

Solución

Finalmente me lo aplicaron, mediante el seguimiento de la posición del cursor, la última selección de inicio y la duración, y el último el tamaño del texto.Cuando un textEdited() se emite la señal, yo lo utilizo para averiguar lo que el texto ha sido insertado y/o eliminados, y luego puedo volver a jugar a la inserción y/o eliminación en el color de la matriz con el fin de sincronizar con el texto.

Puede especificar el color que se utiliza para el texto introducido por el usuario.Si no se especifica, el valor predeterminado del sistema va a ser utilizado, el cual variará dependiendo del tema del sistema.

El único problema es que no apoyo Deshacer, porque no tengo idea de cómo distinguir si un textEdited() la señal es causada por una operación de Deshacer o no.


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

El ejemplo de uso

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

enter image description hereenter image description here

:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top