2011-09-01 13 views
24

Ho diversi widget personalizzati nel mio progetto corrente. Desidero applicare loro fogli di stile e quando lo faccio all'interno di Qt Creator, sembra funzionare. Tuttavia, quando si esegue il programma, non viene utilizzato alcun foglio di stile. I fogli di stile per i widget Qt funzionano normalmente.Qt. Foglio di stile per widget personalizzati

Qualcuno ha qualche consiglio? ecco un codice rilevante.

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.cpp

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

Qualsiasi aiuto sarà apprezzato.

Il widget è visibile- ho impostato un suggerimento che mi ha mostrato (è proprio dello stesso colore del suo QScrollArea seduto).

Jec

+0

Puoi mostrare il foglio di stile corrispondente? – alexisdm

+0

foglio di stile = background: rgb (170, 0, 255); \ nborder: 2px solid black; – jecjackal

+5

Dopo aver cercato l'interwebs per diverse ore, ho scoperto questo http://developer.qt.nokia.com/forums/viewthread/7340 Il codice a cui si fa riferimento in quella pagina era richiesto per il funzionamento del foglio di stile. – jecjackal

risposta

45

ho avuto un problema simile ed è stato risolto con il commento di jecjackal. Come ha detto sjwarner, sarebbe molto più evidente nella forma di una risposta. Quindi lo fornirò. Per il beneficio di eventuali futuri spettatori. Ancora una volta, non è la mia risposta! Apprezzo il jecjackal per questo!

Come si dice in fogli di stile di riferimento del Qt, l'applicazione di stili CSS per widget personalizzati ereditati dal QWidget richiede reimplementare paintEvent() in questo modo:

void CustomWidget::paintEvent(QPaintEvent *) 
{ 
    QStyleOption opt; 
    opt.init(this); 
    QPainter p(this); 
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); 
} 

senza farlo tuoi widget personalizzati supporterà solo lo sfondo , sfondo-clip e proprietà di origine di sfondo.

È possibile leggere qui: Qt Stylesheets reference nella sezione "Elenco dei widget di Stylable" -> QWidget.

4

Per completezza, lo stesso problema è presente in PyQt. È possibile applicare un foglio di stile a un QWidget sottoclasse con l'aggiunta di codice simile:

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) 
8

C'è una risposta molto più facile che scrivere il proprio paintEvent: sottoclasse QFrame invece di QWidget e funzionerà subito:

class WidgetUnits : public QFrame 
{ 
    Q_OBJECT 
.... 
+1

Ho trovato questo modo molto meno invadente di risolvere il problema. È abbastanza facile trovare/sostituire quella riga per ciascun widget personalizzato, oltre a farlo nella parte del contatore di file cpp sostituendo QWidget (parent) con QFrame (parent) all'interno del costruttore predefinito. – Yattabyte

3

Ho avuto lo stesso problema con campagna. Pubblichiamo la mia soluzione solo per completezza. È quasi come in PyQt come proposto da Pieter-Jan Busschaert. unica differenza è che devi chiamare initFrom invece di 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) 

Un altra cosa è necessario assicurarsi è che si definisce il widget personalizzato nel file css seguente modo:

FreeDockWidget{...} 

e non come spesso consigliato

QDockWidget#FreeDockWidget{...} 
0

Calling setAttribute(Qt::WA_StyledBackground, true) per il widget personalizzato ha lavorato per me.

Problemi correlati