Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从Qt中的半透明窗口小部件中删除绘制区域_C++_Qt_Repaint - Fatal编程技术网

C++ 从Qt中的半透明窗口小部件中删除绘制区域

C++ 从Qt中的半透明窗口小部件中删除绘制区域,c++,qt,repaint,C++,Qt,Repaint,我面临的问题是必须擦除Qt小部件上先前绘制的区域 其基本思想是,用户通过单击并拖动鼠标来选择屏幕的一个区域,并在所选区域上绘制一个矩形 标题 class ClearBack : public QWidget { Q_OBJECT public: explicit ClearBack(const QPoint &startingPos); bool eventFilter(QObject *obj, QEvent *event); void paintEv

我面临的问题是必须擦除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_半透明背景)时发生以下情况

先前绘制的矩形不会被“擦除”

有没有办法擦除半透明背景上先前绘制的矩形,如果有,如何擦除


另外,对于“奖励积分”,为什么这种效果会出现在半透明背景上而不是实心背景上?

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

  • 将合成模式从默认的
    SourceOver
    更改为
    Source

  • 使用透明笔刷显式清除旧矩形

  • 绘制新矩形

  • 下面是一个工作示例,在Qt 5下测试。您必须按下鼠标来绘制初始矩形并将其拖动;释放鼠标时,程序将退出

    #包括
    #包括
    #包括
    #包括
    类ClearBack:publicqwidget
    {
    Q_对象
    QRect m_currentRegion,m_lastRegion;
    公众:
    显式清背(常量QPoint和startingPos):
    m_currentRegion(启动位置,启动位置)
    {
    setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
    setAttribute(Qt::WA_半透明背景);
    showMaximized();
    }
    Q_选择的信号无效区域(常数&);
    受保护的:
    无效paintEvent(QPaintEvent*){
    油漆工(本);
    painter.setCompositionMode(QPainter::CompositionMode_源);
    painter.setRenderInt(QPainter::抗锯齿);
    setPen(QPen(Qt::transparent,3));
    drawRect画家(m_lastRegion);
    m_lastRegion=m_currentRegion;
    画师:设置笔(Qt::黑色);
    drawRect(m_currentRegion);
    }
    作废mouseMoveEvent(QMouseEvent*事件){
    m_currentRegion.setBottomRight(事件->全局操作系统());
    更新();
    }
    无效mouseReleaseEvent(QMouseEvent*){
    选择发射区域(m_currentRegion);
    }
    };
    int main(int argc,char*argv[])
    {
    质量保证申请a(argc、argv);
    ClearBack(QPoint(200200));
    a、 连接(&back)、信号(区域选择(QRect))、插槽(退出());
    返回a.exec();
    }
    #包括“main.moc”
    
    不透明背景不会将现有屏幕内容用于任何用途。在半透明背景中,绘制的颜色取决于屏幕上的当前颜色。一个常见的解决方案是使用可逆高光,例如XOR或非XOR。这听起来很有趣,你能详细说明一下吗?Qt描述的XOR模式绘制似乎有XOR模式。谢谢@Ben Voigt,我会仔细看一下。