Feuille de style Qt pour widget personnalisé
j'ai plusieurs widgets personnalisés dans mon projet actuel. Je souhaite appliquer des feuilles de style à eux et lorsque je le fais à L'intérieur de Qt Creator, il semble fonctionner. Cependant, lors de l'exécution du programme, aucune feuille de style n'est utilisée. Les feuilles de style des widgets Qt fonctionnent normalement.
quelqu'un aurait-il des conseils? voici quelques codes pertinents.
WidgetUnits.h
#ifndef WIDGETUNITS_H
#define WIDGETUNITS_H
#include <QList>
#include <QWidget>
#include <QPainter>
#include <Widgets/JECButton.h>
#include <Unit.h>
#include <Time.h>
namespace Ui
{
class WidgetUnits;
}
class WidgetUnits : public QWidget
{
Q_OBJECT
public:
explicit WidgetUnits(QWidget *parent = 0);
~WidgetUnits();
void setNumTimes(const int& numTimes);
public slots:
void updatePictures(const Time* time);
protected:
void paintEvent(QPaintEvent *event);
private:
void checkNewQueue(const QList<QList<Unit*>*>* units);
Ui::WidgetUnits *ui;
const int pictureWidth; // The width of the Unit pictures.
const int pictureHeight; // The height of the Unit pictures.
QList<QList<JECButton*>*> buttonPictures; // The Units' pictures. The outer QList stores the QList of pictures for a given tick.
// The inner QList stores the JECButtons for the specific tick.
};
WidgetUnits.rpc
#include "WidgetUnits.h"
#include "ui_WidgetUnits.h"
WidgetUnits::WidgetUnits(QWidget *parent):
QWidget(parent),
ui(new Ui::WidgetUnits),
pictureWidth(36),
pictureHeight(36)
{
ui->setupUi(this);
}
WidgetUnits::~WidgetUnits()
{
delete ui;
}
void WidgetUnits::updatePictures(const Time *time)
{
// Only showing units that started to get built this turn.
checkNewQueue(time->getUnits());
checkNewQueue(time->getBuildings());
checkNewQueue(time->getUpgrades());
// Updating the position of the remaining pictures (after some were removed).
// Checking the maximum number of Units made in one tick.
int maxNewQueue = 0;
for (int a = 0; a < buttonPictures.length(); ++a)
{
if (buttonPictures.at(a)->length() > maxNewQueue)
{
maxNewQueue = buttonPictures.at(a)->length();
}
}
if (buttonPictures.length() > 0)
{
this->setGeometry(0, 0, buttonPictures.length() * 130,
maxNewQueue * (pictureWidth + 10) + 20);
QList<JECButton*>* tickButtons = 0;
for (int a = 0; a < buttonPictures.length(); ++a)
{
tickButtons = buttonPictures.at(a);
for (int b = 0; b < tickButtons->length(); ++b)
{
tickButtons->at(b)->move(a * 130, b * (pictureHeight + 10));
}
}
}
update();
}
void WidgetUnits::checkNewQueue(const QList<QList<Unit *> *> *units)
{
if (units != 0)
{
const Unit* currentUnit = 0;
JECButton* currentButton = 0;
for (int a = 0; a < units->length(); ++a)
{
buttonPictures.append(new QList<JECButton*>());
for (int b = 0; b < units->at(a)->length(); ++b)
{
currentUnit = units->at(a)->at(b);
// Verifying that there is an item in the queue and the queue action was started this turn.
if (currentUnit->getQueue() != 0 && currentUnit->getAction()->getTimeStart() == currentUnit->getAction()->getTimeCurrent()
&& (currentUnit->getAction()->getType() == Action::BUILD || currentUnit->getAction()->getType() == Action::TRAIN ||
currentUnit->getAction()->getType() == Action::UPGRADE))
{
buttonPictures.last()->append(new JECButton(this));
currentButton = buttonPictures.last()->last();
QImage* image = new QImage(currentUnit->getQueue()->getUnitBase()->getImage().scaled(pictureWidth, pictureHeight));
currentButton->setImage(*image);
currentButton->setGeometry(0, 0, currentButton->getImage().width(),
currentButton->getImage().height());
currentButton->setColorHover(QColor(0, 0, 225));
currentButton->setColorPressed(QColor(120, 120, 120));
currentButton->setImageOwner(true);
currentButton->setVisible(true);
}
}
}
}
}
void WidgetUnits::setNumTimes(const int &numTimes)
{
// Appending new button lists for added ticks.
for (int a = buttonPictures.length(); a < numTimes; ++a)
{
buttonPictures.append(new QList<JECButton*>());
}
}
void WidgetUnits::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
}
Toute aide sera appréciée.
le widget est visible - j'ai mis un tooltip qu'il m'a montré (sa juste la même couleur de la QScrollArea
sa position assise).
Jec
5 réponses
j'ai eu un problème similaire et il a été résolu en utilisant le commentaire de jecjackal. Comme sjwarner dit, il serait beaucoup plus perceptible dans la forme d'une réponse. Donc je vais le fournir. Pour le bénéfice des futurs spectateurs. Encore une fois, ce n'est pas ma réponse! J'apprécie jecjackal pour ça!
comme il est dit dans la référence des feuilles de style de Qt, appliquer les styles CSS aux widgets personnalisés hérités de QWidget nécessite de réimplémenter paintEvent () de cette façon:
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
sans le faire votre les widgets personnalisés ne supporteront que les propriétés background, background-clip et background-origin.
Vous pouvez le lire ici:Qt feuilles de style de référence dans la section "Liste des Widgets Stylables" -> QWidget.
il y a une réponse beaucoup plus facile que d'écrire la vôtre paintEvent
: sous-classe QFrame
au lieu de QWidget
et il va travailler tout de suite:
class WidgetUnits : public QFrame
{
Q_OBJECT
....
Pour être complet, le même problème est présent dans PyQt. Vous pouvez appliquer une feuille de style à un QWidget sous-classé en ajoutant du code similaire:
def paintEvent(self, pe):
opt = QtGui.QStyleOption()
opt.init(self)
p = QtGui.QPainter(self)
s = self.style()
s.drawPrimitive(QtGui.QStyle.PE_Widget, opt, p, self)
j'ai eu le même problème avec pyside. Je poste ma solution juste pour l'exhaustivité. C'est presque comme dans PyQt comme Pieter-Jan Busschaert l'a proposé. la seule différence est que vous devez appeler init from au lieu de init
def paintEvent(self, evt):
super(FreeDockWidget,self).paintEvent(evt)
opt = QtGui.QStyleOption()
opt.initFrom(self)
p = QtGui.QPainter(self)
s = self.style()
s.drawPrimitive(QtGui.QStyle.PE_Widget, opt, p, self)
Une autre chose que vous devez vous assurer que vous définissez votre widget personnalisé dans votre fichier css de la façon suivante:
FreeDockWidget{...}
et non, comme souvent recommandé
QDockWidget#FreeDockWidget{...}
appel setAttribute(Qt::WA_StyledBackground, true)
pour le widget personnalisé a fonctionné pour moi.