在Qt中擦除半透明小部件的绘制区域

时间:2013-12-30 22:28:21

标签: c++ qt repaint

我遇到了必须擦除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();
}

在具有纯色背景的小部件上,效果非常好,产生一个矩形。

enter image description here

但是,当背景设置为setAttribute(Qt::WA_TranslucentBackground);时,会发生以下情况。

enter image description here

之前绘制的矩形未被“删除”

有没有办法擦除半透明背景上先前绘制的矩形,若然,怎么办?

另外,对于“奖励积分”,为什么这种效果会发生在半透明的背景而不是固体背景上?

1 个答案:

答案 0 :(得分:3)

具有WA_TranslucentBackground属性的小部件不会自动清除其背景。你必须:

  1. 将构图模式从默认SourceOver更改为Source

  2. 使用透明画笔明确清除旧矩形

  3. 绘制新矩形。

  4. 下面是一个工作示例,在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"