我已经定制了QPushButton小部件,以使其在单击时在小部件上方出现白色的动画闪烁。对于我位于网格单元格(0,0)中的按钮,此方法很好用。至于我位于(2,0)的按钮,似乎根本没有绘制矩形。这种行为可以在我上传的视频中看到,并带有相应的qDebug输出(按钮名称和几何形状)。单击时,闪光灯会显示在“注册表”上方,但不会出现在“退出”上方:
https://youtu.be/j5gE_5jeMtg

现在查看代码(如果您看到可以优化的内容,请随时向我提供一些提示):

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);
}

我对这种行为的唯一假设是,使用网格的工作比我所知道的更多。

最佳答案

检查geometry()e->rect()之间的区别。它与e->rect()一起使用。

qDebug() << "paint" << text() << geometry() << e->rect();
painter.fillRect(e->rect(), QColor(200, 200, 200, 200 * (delta < 1.0f ? delta : 2.0f - delta)));

输出:
paint "Registry" QRect(0,0 381x24) QRect(0,0 381x24)
paint "Exit" QRect(0,217 381x24) QRect(0,0 381x24)

07-28 01:33