I've gone about customizing the QPushButton
widget such that an animated flash of white appears above the widget when clicked. This works fine for the button I have located in cell (0, 0) of my grid. As for my button located at (2, 0) it appears that it doesn't paint a rect at all. This behavior can be seen in this video I've uploaded, with the corresponding qDebug
output (button name & geometry). The flash appears over "Registry" when clicked, but not "Exit":
https://youtu.be/j5gE_5jeMtg
Now for the code (if you see something that can be optimized, please feel free to provide me some tips):
pushbutton.h
#ifndef PUSHBUTTON
#define PUSHBUTTON
#include <QtCore>
#include <QPushButton>
#include <QPainter>
class PushButton : public QPushButton
{
Q_OBJECT
public:
explicit PushButton(QString text, QWidget *parent = 0);
protected:
virtual void paintEvent(QPaintEvent *);
public slots:
void OnClick();
void OnTick();
private:
enum States
{
NONE = 0,
RESET,
DRAW
} state = NONE;
QTimer *timer;
float delta = 0.0f;
};
#endif
pushbutton.cpp
#include "pushbutton.h"
PushButton::PushButton(QString text, QWidget *parent) : QPushButton(text, parent)
{
timer = new QTimer(this);
QObject::connect(this, SIGNAL(clicked(bool)), this, SLOT(OnClick()));
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(OnTick()));
}
void PushButton::paintEvent(QPaintEvent *e)
{
QPushButton::paintEvent(e);
if(state == States::NONE)
{
return;
}
QPainter painter(this);
if(state == States::RESET)
{
state = States::NONE;
painter.eraseRect(geometry());
update();
}
else
{
painter.fillRect(geometry(), QColor(200, 200, 200, 200 * (delta < 1.0f ? delta : 2.0f - delta)));
}
}
void PushButton::OnClick()
{
qDebug() << text() << geometry();
state = States::DRAW;
delta = 0.0f;
timer->start(20);
}
void PushButton::OnTick()
{
delta += 0.2f;
if(delta > 2.0f)
{
state = States::RESET;
timer->stop();
}
update();
}
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
registryButton = new PushButton("Registry");
exitButton = new PushButton("Exit");
registryButton->setStyleSheet("* { font-size: 16pt; font-family: Segoe360;"
"border: none;"
"color: rgba(240, 240, 240, 255);"
"background: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 rgba(160, 169, 212, 255), stop:1 rgba(137, 151, 216, 255)); }");
exitButton->setStyleSheet("* { font-size: 16pt; font-family: Segoe360;"
"border: none;"
"color: rgba(240, 240, 240, 255);"
"background: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 rgba(191, 78, 78, 255), stop:1 rgba(199, 53, 53, 255)); }");
ui->gridLayout->addWidget(registryButton, 0, 0, Qt::AlignTop);
ui->gridLayout->addWidget(exitButton, 2, 0, Qt::AlignBottom);
}
My only assumption toward this behavior is that there is more to working with grids than I'm aware of.
Check the difference between geometry()
and e->rect()
. It works with e->rect()
.
qDebug() << "paint" << text() << geometry() << e->rect();
painter.fillRect(e->rect(), QColor(200, 200, 200, 200 * (delta < 1.0f ? delta : 2.0f - delta)));
Output:
paint "Registry" QRect(0,0 381x24) QRect(0,0 381x24)
paint "Exit" QRect(0,217 381x24) QRect(0,0 381x24)
QPaintEvent::rect()
: Returns the rectangle that needs to be updated.
QWidget::geometry()
: This property holds the geometry of the widget relative to its parent and excluding the window frame.