Stylesheet für eigenes Widget?

Alles rund um die Programmierung mit Qt
Antworten
Developer
Beiträge: 8
Registriert: 17. Juli 2013 11:16

Stylesheet für eigenes Widget?

Beitrag von Developer »

Hallo allerseits,

ich entwickle erst seit kurzem Anwendungen mit Qt und habe schon mehrfach gesehen, dass man Widgets mit Stylesheets modifizieren kann. Ich möchte auf meiner GUI ein eigenes Widget benutzen, dass ich über das paintEvent auch selbst zeichne. Ist es möglich, dass ich dieses so programmieren kann, dass es sein Aussehen genauso flexibel durch Stylesheets anpassen kann?

lg
Developer
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: Stylesheet für eigenes Widget?

Beitrag von sigvdr »

Auch dein eigenes Widget ist ja von QWidget abgeleitet.
Weil aber die Stylesheets schon in QWidget enthalten sind kannst du die auch im eigenen Widget nutzen.
z.B. Für die Textausgabe QWidget::font() verwenden
Für Farben QWidget::palette() verwenden
Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Re: Stylesheet für eigenes Widget?

Beitrag von Uwe »

Developer hat geschrieben:Ist es möglich, dass ich dieses so programmieren kann, dass es sein Aussehen genauso flexibel durch Stylesheets anpassen kann?
Zunächst mal kannst Du konfigurieren, was die Basisklasse Deines Widgets an Möglichkeiten mitbringt. So richtig Klasse ist das aber auch nicht, da es keine Getter gibt, über die man den StyleSheet auswerten kann d.h die Werte stehen nur in der Implementierung der Basisklasse zur Verfügung.. z.B. kannst Du den "border-radius" für Klassen, die von QFrame abgeleitet sind, zwar setzen, beim Zeichnen Deines Widgets fehlt Dir dann aber die Information, dass Du in den Ecken aufpassen musst ( falls Dein Widget das benötigt ).

Erweitern kannst Du das System über Properties, die Du dann auch im StyleSheet setzten kannst. Diese Werte stehen Dir so natürlich auch in Deinem abgeleiteten Widget zur Verfügung.

Falls das paintEvent Deines Widgets teuer ist solltest Du beachten, dass die Update Regions in den PaintEvents grundsätzlich ein komplettes Neuzeichnen einfordern, sobald Du einen StyleSheet verwendest. Das kann z.B auch bei Remote/X11 eine Rolle spielen.

Uwe
Developer
Beiträge: 8
Registriert: 17. Juli 2013 11:16

Re: Stylesheet für eigenes Widget?

Beitrag von Developer »

Uwe hat geschrieben:
Developer hat geschrieben:Erweitern kannst Du das System über Properties, die Du dann auch im StyleSheet setzten kannst. Diese Werte stehen Dir so natürlich auch in Deinem abgeleiteten Widget zur Verfügung.
Ich habe zum Test in meiner Widget Klasse jetzt einfach mal eine Property namens backgroundColorTest eingebaut und Setter- und Gettermethoden implementiert. Wenn ich über die setProperty Methode einen Farbwert setze, funktioniert es. Wenn ich nun im Stylesheet backgroundColorTest:red eingebe, dann passiert nichts. Muss ich bei den Properties irgendetwas einstellen, damit diese auch im Stylesheet verfügbar sind? Andererseits könnte ich mir auch vorstellen, dass ich das Stylesheet auch einfach nur falsch gesetzt habe, da ich damit noch überhaupt nicht vorher gearbeitet habe. Ich habe lediglich unter "Design" im QtCreator mein Widget selektiert und dann bei den Eigenschaften unter Stylesheet den besagten Text eingegeben. Kann mir jemand weiterhelfen?
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: Stylesheet für eigenes Widget?

Beitrag von sigvdr »

und dann bei den Eigenschaften unter Stylesheet den besagten Text eingegeben.
und wie kommt der "Text" ins Property?

Gruß Sig
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: Stylesheet für eigenes Widget?

Beitrag von sigvdr »

Aus den Qt Hilfstexten
QWidget Supports only the background, background-clip and background-origin properties.
If you subclass from QWidget, you need to provide a paintEvent for your custom QWidget as below:
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
The above code is a no-operation if there is no stylesheet set.
Warning: Make sure you define the Q_OBJECT macro for your custom widget.
Developer
Beiträge: 8
Registriert: 17. Juli 2013 11:16

Re: Stylesheet für eigenes Widget?

Beitrag von Developer »

sigvdr hat geschrieben:und wie kommt der "Text" ins Property?
Anscheinend ja nicht von selbst, das ist ja das Problem :( .
sigvdr hat geschrieben:Aus den Qt Hilfstexten: QWidget Supports only the background, background-clip and background-origin properties. [...]
Heißt das soviel wie, dass es garnicht möglich ist, eigenen Properties über Stylesheets Werte zuzuweisen?
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: Stylesheet für eigenes Widget?

Beitrag von sigvdr »

Hallo,

QString QWidget::styleSheet() liefert dir wieder in deinem paintEvent das vorher definierte "backgroundColorTest:red", das musst du halt auswerten.

Möglicherweise zeigst du uns wie dein paintEvent bisher aussieht.

Gruß Sig
Developer
Beiträge: 8
Registriert: 17. Juli 2013 11:16

Re: Stylesheet für eigenes Widget?

Beitrag von Developer »

Meine Header-Datei sieht grob so aus:

Code: Alles auswählen

class MeinWidget : public QWidget
{
   Q_OBJECT
   Q_PROPERTY(QColor backgroundColorTest READ backgroundColorTest WRITE setBackgroundColorTest)

public:
   explicit MeinWidget(QWidget *parent = 0);
   ~MeinWidget();   
   void setBackgroundColorTest(QColor color);     // setter function   
   QColor backgroundColorTest();                  // getter function

protected:
   void paintEvent(QPaintEvent *);

private:
   QColor m_bgtest;

};

inline void MeinWidget::setBackgroundColorTest(QColor color)
{
   m_bgtest = color;
}

inline QColor MeinWidget::backgroundColorTest()
{
   return m_bgtest;
}
Und meine paintEvent() Methode:

Code: Alles auswählen

void MeinWidget::paintEvent(QPaintEvent *)
{
   QPainter painter(this);
   QRect rect(0,0, this->width()-1, this->height()-1);
   QBrush brush;
   brush.setStyle(Qt::SolidPattern);
   brush.setColor(m_bgtest);
   painter.fillRect(rect, brush);
}
Ich dachte halt, dass man über ein Stylesheet die Property setzen kann, und dann würde das ganze da ja auch schon funktionieren.
sigvdr
Beiträge: 100
Registriert: 1. Juli 2008 19:29

Re: Stylesheet für eigenes Widget?

Beitrag von sigvdr »

Sieht nach Übungscode aus um zu testen was geht. Deshalb noch ein paar ergänzende Anmerkungen.

1. Nicht selbst machen was Qt schon kann:
autoFillBackground : bool This property holds whether the widget background is filled automatically.
If enabled, this property will cause Qt to fill the background of the widget before invoking the paint event. The color used is defined by the QPalette::Window color role from the widget's palette.
2. Dein Widget könnte auch von QFrame, QGroupbox, QLabel .... abgeleitet werden wenn dir damit schon ein Teil der "Darstellung" abgenommen wird.

3. In QPalette::Window color role wäre eigentlich in QWidget schon die Hintergrundfarbe (abhängig vom Stylesheet) definiert. MeinWidget::setStyleSheet("background-color: red;")

Wenn das alles nicht reicht, dann musst du wirklich den Inhalt von MeinWidget::styleSheet() auswerten.

Gruß Sig (Offline für die nächsten Tage)
Developer
Beiträge: 8
Registriert: 17. Juli 2013 11:16

Re: Stylesheet für eigenes Widget?

Beitrag von Developer »

sigvdr hat geschrieben:2. Dein Widget könnte auch von QFrame, QGroupbox, QLabel .... abgeleitet werden wenn dir damit schon ein Teil der "Darstellung" abgenommen wird.
Ok, ich habe nun mal versucht eine Klasse für einen simplen Button zu erzeugen und habe dabei von QLabel abgeleitet.
Ich habe nun folgendes Stylesheet:

Code: Alles auswählen

MeinWidget
{
   background-color: red; 
   color: blue;
}
MeinWidget:hover
{
   background-color: green;
   color : blue;
}
Funktioniert so weit auch gut. Jetzt finde ich, dass der Hover-Effekt etwas prompt kommt. Gibt es eine möglichkeit, dass die Farben ineinander übergehen, statt direkt zu kommen? Bei meinen bisherigen Versuchen habe ich das in meiner paintEvent Methode realisiert, da ich ja sowieso das ganze Widget selbst gezeichnet hatte. Wie kann ich das bei einem abgeleiteten Widget realisieren?

Edit:
Ich habe hier Bezüglich des Problems eine neue Frage gestellt...
Antworten