Peinture personnalisée QWidget basée sur une feuille de style valeur pseudo-état
-
28-10-2019 - |
Question
J'ai un QWidget
personnalisé (en fait, dérivé de QAbstractButton
) pour lequel je dois mettre en œuvre ma propre paintEvent
. Comment j'utiliser les feuilles de style?
Par exemple, quelqu'un définit suppose la feuille de style suivante qui s'applique (directement ou par héritage) à ma classe personnalisée:
QAbstractButton { font-weight: bold; background-color: red }
QAbstractButton:checked { background-color: blue }
Dans ma méthode de paintEvent
, comment puis-je obtenir la couleur de fond correct de se présenter pour l'état vérifié?
void MyButton::paintEvent(QPaintEvent */*event*/) {
ensurePolished(); // Don't think this is necessary...
qDebug() << Q_FUNC_INFO << isChecked(); // This is showing the right value
QStylePainter painter(this);
painter.fillRect(rect(), painter.background()); // always red, even if checked
}
Je suppose que je dois quelque chose comme:
if (isChecked()) {
// painter.fillRect(rect(), ???);
//
// style()->drawPrimitive(???, ...);
//
// QStyleOptionButton opt;
// opt.initFrom(this);
// QBrush bg_brush = opt.???
// painter.fillRect(rect(), bg_brush);
//
// ???
} else {
painter.fillRect(rect(), painter.background());
}
Comment puis-je obtenir la brosse à utiliser pour l'arrière-plan contrôlé par l'Etat que Qt résolu des feuilles de style?
La solution
Je ne pouvait savoir comment obtenir la couleur résolue (et rembourrage) l'information, mais a pu travailler autour d'elle en peignant des sous-éléments d'autres widgets dans le mien. Ce n'est pas exactement ce que je voulais faire, et peut ne pas dans d'autres cas (si votre widget ne peut pas être composé par empâtage trucs ensemble que Qt ne sait comment dessiner).
void MyButton::paintEvent(QPaintEvent */*event*/) {
QStylePainter painter(this);
QStyleOptionButton opt;
opt.initFrom(this);
opt.state |= isChecked() ? QStyle::State_On : QStyle::State_Off;
opt.text = text();
painter.drawPrimitive(QStyle::PE_Widget, opt);
QStyleOptionButton label_opt = opt;
label_opt.rect =
style()->subElementRect(QStyle::SE_CheckBoxContents, &opt, this);
painter.drawControl(QStyle::CE_CheckBoxLabel, label_opt);
// ... etc.
}
Je pense toujours qu'il doit y avoir une meilleure façon.