QPainter fillRect 在网格单元格中小部件的几何形状
QPainter fillRect over geometry of widget in grid cell
我已经着手自定义 QPushButton
小部件,以便在单击时小部件上方会出现动画闪烁的白色。这适用于我位于网格单元格 (0, 0) 中的按钮。至于我位于 (2, 0) 的按钮,它似乎根本没有绘制矩形。在我上传的这个视频中可以看到这种行为,以及相应的 qDebug
输出(按钮名称和几何形状)。单击时闪光出现在 "Registry" 上,但不出现在 "Exit" 上:
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)
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.
我已经着手自定义 QPushButton
小部件,以便在单击时小部件上方会出现动画闪烁的白色。这适用于我位于网格单元格 (0, 0) 中的按钮。至于我位于 (2, 0) 的按钮,它似乎根本没有绘制矩形。在我上传的这个视频中可以看到这种行为,以及相应的 qDebug
输出(按钮名称和几何形状)。单击时闪光出现在 "Registry" 上,但不出现在 "Exit" 上:
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)
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.