Стирание закрашенных областей из полупрозрачных виджетов в Qt

Я столкнулся с проблемой необходимости стирать ранее нарисованные области в виджете Qt.

Основная идея состоит в том, что пользователь выбирает область экрана, щелкая и перетаскивая мышь, и прямоугольник рисуется над выбранной областью.

Заголовок

class ClearBack : public QWidget
{
Q_OBJECT
public:
explicit ClearBack(const QPoint &startingPos);

bool eventFilter(QObject *obj, QEvent *event);
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *event);

signals:
void regionSelected(const QRect &);

private:
QRect currentRegion;
};

Реализация

ClearBack::ClearBack(const QPoint &startingPos)
{
setBackgroundRole(QPalette::Base);
installEventFilter(this);
currentRegion.setTopLeft(startingPos);
currentRegion.setBottomRight(startingPos);
this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
this->showMaximized();
}

void ClearBack::paintEvent(QPaintEvent * event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::black);
painter.drawRect(currentRegion);
}

void ClearBack::mouseMoveEvent(QMouseEvent *event)
{
QPoint currentPos(event->globalX(), event->globalY());
currentRegion.setBottomRight(currentPos);
this->repaint();
}

На виджете, который имеет сплошной фон, эффект работает довольно хорошо, создавая один прямоугольник.

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

Тем не менее, когда фон установлен на setAttribute(Qt::WA_TranslucentBackground); происходит следующее.

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

Прямоугольники, которые были нарисованы ранее, не «стираются»

Есть ли способ стереть ранее нарисованные прямоугольники на полупрозрачном фоне, и если да, то как?

Также и для «бонусных баллов», почему этот эффект возникает на полупрозрачном фоне, а не на сплошном?

2

Решение

Виджеты с WA_TranslucentBackground атрибут не очищает свои фоны автоматически. Ты должен:

  1. Изменить режим композиции по умолчанию SourceOver в Source,

  2. Ясно очистить старый прямоугольник с помощью прозрачной кисти,

  3. Нарисуйте новый прямоугольник.

Ниже приведен рабочий пример, протестированный в Qt 5. Вы должны нажать мышь, чтобы нарисовать начальный прямоугольник и перетащить его; программа завершается, когда вы отпускаете мышь.

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QMouseEvent>

class ClearBack : public QWidget
{
Q_OBJECT
QRect m_currentRegion, m_lastRegion;
public:
explicit ClearBack(const QPoint &startingPos) :
m_currentRegion(startingPos, startingPos)
{
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
showMaximized();
}
Q_SIGNAL void regionSelected(const QRect &);
protected:
void paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(Qt::transparent, 3));
painter.drawRect(m_lastRegion);
m_lastRegion = m_currentRegion;
painter.setPen(Qt::black);
painter.drawRect(m_currentRegion);
}
void mouseMoveEvent(QMouseEvent *event) {
m_currentRegion.setBottomRight(event->globalPos());
update();
}
void mouseReleaseEvent(QMouseEvent *) {
emit regionSelected(m_currentRegion);
}
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ClearBack back(QPoint(200,200));
a.connect(&back, SIGNAL(regionSelected(QRect)), SLOT(quit()));
return a.exec();
}

#include "main.moc"
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]