[英]Why the application crashes when QPushButton::paintEvent is followed by QPainter::fillRect?
我通過子類化QPushButton
並處理paintEvent
實現圓形按鈕。 我想顯示用戶設置的文本,然后畫一個圓。
調用QPushButton::paintEvent
方法后,應用程序在QPainter::fillRect
崩潰。 如果未調用QPushButton::paintEvent
,則不會崩潰,但不會顯示按鈕文本。
這是我的代碼:
class CRoundAnimatingBtn : public QPushButton
{
Q_OBJECT
public:
explicit CRoundAnimatingBtn(QWidget *parent = nullptr) : QPushButton(parent) {}
protected:
void resizeEvent(QResizeEvent *) { setMask(QRegion(rect(), QRegion::Ellipse)); }
void paintEvent(QPaintEvent * e) {
QPainter painter(this);
QPointF center(width()/2, height()/2);
QRadialGradient radialGradient(center, qMin(width(), height())/2, center);
QPushButton::paintEvent(e); // Application crashes if this is called
if (isDown()) {
radialGradient.setColorAt(0.0,Qt::transparent);
radialGradient.setColorAt(0.79, Qt::transparent);
radialGradient.setColorAt(0.80, Qt::gray);
radialGradient.setColorAt(0.95, Qt::black);
radialGradient.setColorAt(0.90, Qt::gray);
radialGradient.setColorAt(0.91, Qt::transparent);
} else {
radialGradient.setColorAt(0.0,Qt::transparent);
radialGradient.setColorAt(0.84, Qt::transparent);
radialGradient.setColorAt(0.85, Qt::gray);
radialGradient.setColorAt(0.90, Qt::black);
radialGradient.setColorAt(0.95, Qt::gray);
radialGradient.setColorAt(0.96, Qt::transparent);
}
painter.fillRect(rect(), radialGradient); // Application crashes here
}
};
如何解決當機問題?
首先創建一個畫家,將QPaintDevice *device
傳遞給QPainter
的構造函數,該構造函數調用 QPainter::begin
:
QPainter painter(this);
然后,調用paintEvent
的基類實現:
QPushButton::paintEvent(e);
在完成第一個繪畫器之前,它會在同一繪畫器上創建一個新的繪畫器QStylePainter p
:
void QPushButton::paintEvent(QPaintEvent *)
{
QStylePainter p(this);
QStyleOptionButton option;
initStyleOption(&option);
p.drawControl(QStyle::CE_PushButton, option);
}
最后,您嘗試使用以下第一個畫家QPainter painter
進行繪制:
painter.fillRect(rectangle, radialGradient);
重要提示:不允許這種方法,因為QPainter::begin
的文檔明確指出:
警告:油漆設備一次只能由一位油漆工油漆。
考慮到這一點,我建議您通過移動QPushButton::paintEvent(e);
來避免同時擁有兩個活動繪畫者QPushButton::paintEvent(e);
到CRoundAnimatingBtn::paintEvent
開始(在此事件處理程序中的所有其他內容之前)。
注意:如果您放置QPushButton::paintEvent(e);
在CRoundAnimatingBtn::paintEvent
,默認實現會覆蓋您的自定義繪圖,因此它將不可見。
這是CRoundAnimatingBtn::paintEvent
樣子:
void paintEvent(QPaintEvent * e) {
QPushButton::paintEvent(e);
QPainter painter(this);
QPointF center(width()/2, height()/2);
QRadialGradient radialGradient(center, qMin(width(), height())/2, center);
...
painter.fillRect(rect(), radialGradient);
}
該示例產生以下結果:
如您所見,文本與您的自定義圖形一起顯示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.