简体   繁体   English

在QT C ++中淡出小部件

[英]Fading away widget in QT C++

I want to make a simple QWidget which is a simple rectangle fade away. 我想制作一个简单的QWidget,它是一个简单的矩形消失。 The main problem is that the paint event paint at the same place every time in fact making the effect opposite, it make the colour stronger. 主要问题是油漆事件每次涂在同一个地方实际上使效果相反,它使颜色更强。 Is there any way of achieving this functionality? 有没有办法实现这个功能? Could you maybe provide some simple example? 你能提供一些简单的例子吗?

My code: ` 我的代码:`

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    void paintEvent(QPaintEvent*);
    ~Widget();

private:
    Ui::Widget *ui;
    int alfa;
    int i;
    QTimer time;

};

#endif // WIDGET_H

` `

and the cpp: 和cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QColor>
#include <QPainter>
#include <QBrush>
#include <QTimer>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent,Qt::Popup | Qt::FramelessWindowHint),
    ui(new Ui::Widget),
    time()
{
    ui->setupUi(this);
    setAttribute(Qt::WA_NoSystemBackground, true);
    setAttribute(Qt::WA_TranslucentBackground, true);
    setAttribute(Qt::WA_PaintOnScreen);
    time.setInterval(500);
    time.start();
    connect(&time,SIGNAL(timeout()),this,SLOT(update()));
    alfa=100;
    i=0;

}

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    int rectBase = height();

    QColor c(255,0,255);
    alfa=alfa-(i*10);
    c.setAlpha(alfa);
    qDebug()<<c.alpha();
    i++;

    painter.setBrush(QBrush(c));
    painter.drawRect(0, 0, width(),height());


}

Widget::~Widget()
{
    delete ui;
}

You shouldn't rely on QWidget::paintEvent() to change your alpha level, since it can be called less or more than you want (multiple update() calls may result in only one paintEvent() and paintEvent() may be called when you don't expect it). 你不应该依赖QWidget::paintEvent()来改变你的alpha级别,因为它可以被调用少于或多于你想要的(多次update()调用可能只会导致一个paintEvent()paintEvent()被调用当你不指望它)。

So a more reliable way to get to the result, is have a separate slot where you decrease the alpha level and then call update() . 因此,获得结果的更可靠方法是使用单独的插槽来降低alpha级别,然后调用update() Your class definition might look like this: 您的类定义可能如下所示:

class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget( QWidget * inParent );

private:
    void paintEvent(QPaintEvent *);

private slots:
    void animate();

private:
    QTimer * mTimer;
    int mAlpha;
};

And the declaration: 声明:

Widget::Widget( QWidget * inParent )
    :
      QWidget( inParent ),
      mTimer( new QTimer( this ) ),
      mAlpha( 255 )
{
    setAttribute(Qt::WA_NoSystemBackground, true);
    setAttribute(Qt::WA_TranslucentBackground, true);
    setAttribute(Qt::WA_PaintOnScreen);
    mTimer->setInterval( 40 );
    mTimer->setSingleShot( false );
    connect( mTimer, SIGNAL(timeout()), this, SLOT(animate()) );
    mTimer->start();
}

void
Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setBrush( QColor(255,0,255,mAlpha ) );
    painter.drawRect(rect());
}

void
Widget::animate()
{
    if ( mAlpha > 0 )
    {
        mAlpha -= 3;
    }
    else
    {
        mTimer->stop();
    }
    update();
}

Notice that I did decrease the interval of the timer. 请注意,我确实减少了计时器的间隔。 You only called an update() every half a second. 你每隔半秒就调用一次update() That typically does not result in a smooth animation. 这通常不会产生平滑的动画。

I get a warning with this code on Kubuntu Linux, under Qt5: 在Qt5下,我在Kubuntu Linux上收到此代码的警告:

QWidget::paintEngine: should no longer be called QWidget :: paintEngine:不应该再被调用

The originating line is in qWarning("QWidget::paintEngine: Should no longer be called"); 原始行在qWarning("QWidget::paintEngine: Should no longer be called"); , in src/widgets/kernel/qwidget_qpa.cpp and discussed a bit in this ticket: ,在src / widgets / kernel / qwidget_qpa.cpp中,并在此票证中讨论了一下:

https://qt.gitorious.org/qt/qtbase-harmattan/commit/3037525 https://qt.gitorious.org/qt/qtbase-harmattan/commit/3037525

You can get the warning to stop by removing the setAttribute(Qt::WA_PaintOnScreen); 您可以通过删除setAttribute(Qt::WA_PaintOnScreen);来获取停止警告setAttribute(Qt::WA_PaintOnScreen); , so I did that. 所以我这样做了。 After taking that line out, it works for me--although your subtraction model is strange. 取出那条线后,它对我有用 - 虽然你的减法模型很奇怪。 You are modifying the alpha as well as changing the subtraction value on each iteration; 您正在修改alpha以及在每次迭代时更改减法值; you probably didn't intend both. 你可能不打算两者兼而有之。 So either change it to: 所以要么改为:

QColor c (255, 0, 255);
alfa = alfa - 10;
if (alfa >= 0) {
    c.setAlpha(alfa);
} else {
    time.stop();
}

...or: ...要么:

QColor c(255,0,255);
if (alfa - i * 10 >= 0) {
    c.setAlpha(alfa - i * 10);
    i++;
} else {
   time.stop();
}

Etc. (See also @PrisonMonkeys note on your timer not necessarily being the only source of update() calls.) Regarding getting these warnings to be more vocal so you don't miss them, you might look at The Essential Noisy Debug Hook For Qt , which I should update. 等等(另请参阅@PrisonMonkeys关于你的计时器的说明不一定是update()调用的唯一来源。)关于让这些警告更加直言不讳,你不要错过它们,你可能会看看The Essential Noisy Debug Hook For Qt ,我应该更新。

If with the change, an alpha blended window doesn't work on your platform at all, you should mention explicitly what your circumstance is...as it is working for me. 如果进行了更改,Alpha混合窗口根本不适用于您的平台,您应该明确提到您的情况......因为它对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM