为什么要增加一个透明背景才能执行paintevent函数?

时间:2021-08-26 19:00:48
先贴代码,
只要窗体发送变化,或者是update(),就会去执行paintevent函数,可是这里
为什么要添加透明QWidget,相应的paintEvent才能执行,单步调试发现,如果屏蔽透明QWidget那部分代码,paintevent函数不执行,定时器再刷新,应该每1s去执行一次paintevent函数才对?
为什么?谢谢
SmartRoom::SmartRoom(QFrame *parent) :
    QFrame(parent)
{
        setup();

        if(objectName().isEmpty())
        {
            setObjectName(QString::fromUtf8(UHomePageName));
        }

        setWindowFlags(Qt::FramelessWindowHint);
        QPalette palette;
        backWidget = new QWidget(this);
        backWidget->setObjectName("backWidget");
        //backWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        backWidget->move(0,0);
        backWidget->resize(SCREEN_W,SCREEN_H);
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/funmenu/blackbottom.png")));
        this->setPalette(palette);
        backWidget->setAutoFillBackground(true);




     //为什么要添加透明QWidget,相应的paintEvent才能执行
        tranWidget = new QWidget(backWidget);
        tranWidget->setObjectName("tranWidget");
        tranWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/tran.png")));
        backWidget->setPalette(palette);
        tranWidget->setAutoFillBackground(true);


        //通过定时器刷新页面占用cpu资源太高90%,准备改用QPropertyAnimation动画框架
        timer = new QTimer(this);
        connect(timer,SIGNAL(timeout()),this,SLOT(update()));
        timer->start(1000);
        angle = 0;






}



void SmartRoom::paintEvent(QPaintEvent *)
{

    qDebug()<<"SmartRoom::paintEvent";
    angle += 10;
        if(angle>=360)
            angle = 0;



    QPainter painter(this);
    QPixmap pix;
    pix.load("img/funmenu/colorring.png");
    painter.translate(SCREEN_W/2,SCREEN_H/2);           //背景图片的中心作为新的原点
    painter.translate(-pix.width()/2,-pix.height()/2);  //左上角平移成新的原点(0,0)
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawPixmap(0,0,pix.width(),pix.height(),pix);

    QPainter painter2(this);
    QPixmap pix2;
    pix2.load("img/funmenu/ring.png");
    painter2.translate(SCREEN_W/2,SCREEN_H/2); //让图片的中心作为旋转的中心
    painter2.rotate(-angle); //顺时针旋转90度
    painter2.setRenderHint(QPainter::Antialiasing);
    painter2.drawPixmap(pix.width()/2-10,0,pix2.width(),pix2.height(),pix2);

    QPainter painter3(this);
    QPixmap pix3;
    pix3.load("img/funmenu/home.png");
    painter3.translate(SCREEN_W/2,SCREEN_H/2);
    painter3.translate(-pix3.width()/2,-pix3.height()/2);  //左上角平移成新的原点(0,0)
    painter3.setRenderHint(QPainter::Antialiasing);
    painter3.drawPixmap(0,0,pix3.width(),pix3.height(),pix3);

    qDebug()<<"SmartRoom::paintEvent";

}

2 个解决方案

#1


我这样理解可以吗?
如果在构造函数里这样
SmartRoom::SmartRoom(QFrame *parent) :
    QFrame(parent)
{

/*
        setup();

        if(objectName().isEmpty())
        {
            setObjectName(QString::fromUtf8(UHomePageName));
        }

        setWindowFlags(Qt::FramelessWindowHint);
        QPalette palette;
        backWidget = new QWidget(this);
        backWidget->setObjectName("backWidget");
        //backWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        backWidget->move(0,0);
        backWidget->resize(SCREEN_W,SCREEN_H);
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/funmenu/blackbottom.png")));
        this->setPalette(palette);
        backWidget->setAutoFillBackground(true);




     //为什么要添加透明QWidget,相应的paintEvent才能执行
        tranWidget = new QWidget(backWidget);
        tranWidget->setObjectName("tranWidget");
        tranWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/tran.png")));
        backWidget->setPalette(palette);
        tranWidget->setAutoFillBackground(true);



*/





}


全部屏蔽,什么都不做,这样可以执行paintevent函数,好比在最底层(this)层显示,如果打开这段代码
        setWindowFlags(Qt::FramelessWindowHint);
        QPalette palette;
        backWidget = new QWidget(this);
        backWidget->setObjectName("backWidget");
        //backWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        backWidget->move(0,0);
        backWidget->resize(SCREEN_W,SCREEN_H);
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/funmenu/blackbottom.png")));
        this->setPalette(palette);
        backWidget->setAutoFillBackground(true);

在1280*800的窗口上增加一个黑色背景层,运行的话不能执行paintevent函数,应该最底层(this)被backWidget遮住了,不在可视区域,所以没有执行paintevent,但是为什么在backWidget上增加一个透明层tranWidget 就可以执行paintevent了呢?
现在好比有三层 最底层(this) 中间层(backWidget) 最上层(tranWidget ) ,这三层的分辨率都一样1280*800
我的目的只想在黑色背景上绘制一个图案,如果修改QPainter painter(this);中的this,改成QPainter painter(backWidget);
想直接在backWidget绘制图形,但是还是不会显示,QPainter painter(this)中的绘制设备this应该可以修改吧?谢谢
void SmartRoom::paintEvent(QPaintEvent *)
{





    QPainter painter(this);
    QPixmap pix;
    pix.load("img/funmenu/colorring.png");
    painter.translate(SCREEN_W/2,SCREEN_H/2);           //背景图片的中心作为新的原点
    painter.translate(-pix.width()/2,-pix.height()/2);  //左上角平移成新的原点(0,0)
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawPixmap(0,0,pix.width(),pix.height(),pix);



    qDebug()<<"SmartRoom::paintEvent";

}

#2


this->setPalette(palette);?

#1


我这样理解可以吗?
如果在构造函数里这样
SmartRoom::SmartRoom(QFrame *parent) :
    QFrame(parent)
{

/*
        setup();

        if(objectName().isEmpty())
        {
            setObjectName(QString::fromUtf8(UHomePageName));
        }

        setWindowFlags(Qt::FramelessWindowHint);
        QPalette palette;
        backWidget = new QWidget(this);
        backWidget->setObjectName("backWidget");
        //backWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        backWidget->move(0,0);
        backWidget->resize(SCREEN_W,SCREEN_H);
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/funmenu/blackbottom.png")));
        this->setPalette(palette);
        backWidget->setAutoFillBackground(true);




     //为什么要添加透明QWidget,相应的paintEvent才能执行
        tranWidget = new QWidget(backWidget);
        tranWidget->setObjectName("tranWidget");
        tranWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/tran.png")));
        backWidget->setPalette(palette);
        tranWidget->setAutoFillBackground(true);



*/





}


全部屏蔽,什么都不做,这样可以执行paintevent函数,好比在最底层(this)层显示,如果打开这段代码
        setWindowFlags(Qt::FramelessWindowHint);
        QPalette palette;
        backWidget = new QWidget(this);
        backWidget->setObjectName("backWidget");
        //backWidget->setGeometry(QRect(0,0,SCREEN_W,SCREEN_H));
        backWidget->move(0,0);
        backWidget->resize(SCREEN_W,SCREEN_H);
        palette.setBrush(QPalette::Background,QBrush(QPixmap("img/funmenu/blackbottom.png")));
        this->setPalette(palette);
        backWidget->setAutoFillBackground(true);

在1280*800的窗口上增加一个黑色背景层,运行的话不能执行paintevent函数,应该最底层(this)被backWidget遮住了,不在可视区域,所以没有执行paintevent,但是为什么在backWidget上增加一个透明层tranWidget 就可以执行paintevent了呢?
现在好比有三层 最底层(this) 中间层(backWidget) 最上层(tranWidget ) ,这三层的分辨率都一样1280*800
我的目的只想在黑色背景上绘制一个图案,如果修改QPainter painter(this);中的this,改成QPainter painter(backWidget);
想直接在backWidget绘制图形,但是还是不会显示,QPainter painter(this)中的绘制设备this应该可以修改吧?谢谢
void SmartRoom::paintEvent(QPaintEvent *)
{





    QPainter painter(this);
    QPixmap pix;
    pix.load("img/funmenu/colorring.png");
    painter.translate(SCREEN_W/2,SCREEN_H/2);           //背景图片的中心作为新的原点
    painter.translate(-pix.width()/2,-pix.height()/2);  //左上角平移成新的原点(0,0)
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawPixmap(0,0,pix.width(),pix.height(),pix);



    qDebug()<<"SmartRoom::paintEvent";

}

#2


this->setPalette(palette);?