как изменить цвет метки при пересечении с изображением в qt?

У меня есть Qlabel с белым текстом на черном фоне. На этом экране я создаю белый прямоугольник, который меняет размер с помощью:

QGraphicsRectItem* rect;
rect->setRect(0, START_HEIGHT, 0+variable, HEIGHT);

Вызывая функцию, которая изменяет значение «переменной» и воссоздает прямоугольник, я изменяю его размер. Этот прямоугольник белый, и когда он достигает метки, последний исчезает (белое на белом).

Я хотел бы знать, как сделать черный цвет текста внутри метки, когда он пересекает прямоугольник (только пересечение, поскольку, если вся метка станет черной, будет видна только часть над прямоугольником).< /сильный>

Вот пример, который я нашел в Google (ищу PorterDuff, который, похоже, делает что-то подобное на Android). Это другое, но может быть хорошим примером для визуализации того, что я хотел бы получить.

введите здесь описание изображения

Заранее спасибо, если у вас есть какое-то решение или какие-то подсказки =)

Изменить: вот минимальный и воспроизводимый пример.

#include "mainwindow.h"
#include "./ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->label->raise();
ui->label->setText("CCC");

//set scene
    scene= new QGraphicsScene();
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView->setStyleSheet("background: transparent;");
    ui->graphicsView->setFrameShadow(QFrame::Raised);


timers = new QTimer(this);
connect(timers, &QTimer::timeout, this,&MainWindow::grow_my_child);
timers->start(10);
}
void MainWindow::grow_my_child()
{
static int x=0;
rect = new QGraphicsRectItem();

rect->setBrush(Qt::white);
rect->setPen(Qt::NoPen);

scene->addItem(rect);

rect->setVisible(true);
rect->setRect(0,0,0+x,200);
x++;

if(x ==500){
   timers->stop();
}
}

и заголовок:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <Qlabel>
#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>
#include <QTimer>
#include <QDebug>
#include <QPen>
#include <QFontDatabase>
#include <QSize>
#include <QDateTime>
#include <QParallelAnimationGroup>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();

private:
Ui::MainWindow *ui;
QTimer * timers;
QGraphicsScene* scene;
QGraphicsRectItem* rect;
void grow_my_child();

};
#endif // MAINWINDOW_H

В файле .ui есть только метка и элемент graphicview (имя не изменено), а фон черный

Результат, когда прямоугольник достигает метки: введите здесь описание изображения

Текст "CCC", и я хотел бы визуализировать это наполовину черным, а наполовину белым.


person Seriousl Lancerl    schedule 11.05.2020    source источник
comment
Я добавил пример, если нужна другая информация, пожалуйста, спросите, и я постараюсь сделать все более понятным.   -  person Seriousl Lancerl    schedule 11.05.2020
comment
Есть ли причина, по которой вы используете QLabel вместо QGraphicsTextItem?   -  person thibsc    schedule 11.05.2020
comment
Не совсем, я новичок в QT, могу ли я решить свою проблему с QGraphicsTextItem?   -  person Seriousl Lancerl    schedule 11.05.2020
comment
Если вы используете QGraphicsScene, лучше использовать QGraphicsItem, потому что он предназначен для этого. Вы абсолютно хотите, чтобы CCC был полностью белым? Потому что у меня есть решение, но текст немного серый из-за растровой операции   -  person thibsc    schedule 11.05.2020
comment
Если он немного серый, это может быть нормально, на самом деле мой вариант использования говорит, что он должен быть белым или похожим, но он хочет, чтобы он был полностью виден во время пересечения. Если вы опубликуете это как ответ, я могу проголосовать за вас как за лучший ответ   -  person Seriousl Lancerl    schedule 11.05.2020


Ответы (1)


Вы можете создать собственную реализацию для изменения QPainter::compositionMode() вашего вещь:

class TextItem : public QGraphicsTextItem
{
public:
    TextItem(const QString &text, QGraphicsItem *parent = nullptr)
        : QGraphicsTextItem(text, parent){ setZValue(100); }
    TextItem(QGraphicsItem *parent = nullptr)
        : QGraphicsTextItem(parent){ setZValue(100); }
private:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override {
        painter->setCompositionMode(QPainter::CompositionMode_Difference);
        QGraphicsTextItem::paint(painter, option, widget);
    }
};

С этим классом вам нужно просто написать несколько строк:

// Add your rectangle
QGraphicsRectItem *rectitem = scene->addRect(-50, -50, 100, 50, QPen(Qt::white), Qt::white);
// Make your rectangle movable for test with your mouse
rectitem->setFlag(QGraphicsItem::ItemIsMovable, true);

// Add your text
TextItem *txtitem = new TextItem("CCC");
txtitem->setFont(QFont("Ubuntu", 50, 80));
txtitem->setDefaultTextColor(Qt::white);
scene->addItem(txtitem);

Теперь, переместив прямоугольник, вы получите что-то вроде этого:

введите здесь описание изображения

person thibsc    schedule 11.05.2020
comment
Я попробовал это, и это работает отлично. Я немного изучу, что вы там сделали, но я очень ценю вашу помощь, спасибо =). Хорошего дня - person Seriousl Lancerl; 11.05.2020