Qt Style Sheets and Custom Painting Example: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
(clean-up)
(6 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[Category:snippets]] [toc align_right="yes" depth="2"]
[[Category:snippets]]
 
= Qt Style Sheets and Custom Painting Example =
 
== Introduction ==
== Introduction ==


This example demonstrates:<br /># use of qt style sheets<br /># use of Q_PROPERTY<br /># how to combine 1 and 2 with custom painting
This example demonstrates:
# use of qt style sheets
# use of Q_PROPERTY
# how to combine 1 and 2 with custom painting


In this example we have some custom widget that has reimplemented paintEvent function and inside, some custom painting is performed. We'll see how to set custom colors for for shapes and lines via Qt Style Sheet mechanism. Thanks to it, we can easily change the colors inside the .qss file without recompiling the program.
In this example we have some custom widget that has reimplemented paintEvent function and inside, some custom painting is performed. We'll see how to set custom colors for for shapes and lines via Qt Style Sheet mechanism. Thanks to it, we can easily change the colors inside the .qss file without recompiling the program.
Line 11: Line 11:
== Example Source code ==
== Example Source code ==


'''swidget.h'''<br /><code><br />#ifndef SWIDGET_H<br />#define SWIDGET_H
'''swidget.h'''
<code>
#ifndef SWIDGET_H
#define SWIDGET_H
 
#include <QWidget>
 
class SWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor DESIGNABLE true)
Q_PROPERTY(QColor rectColor READ getRectColor WRITE setRectColor DESIGNABLE true)
 
public:
explicit SWidget(QWidget *parent = 0);
~SWidget();
 
QColor getLineColor() const;
void setLineColor( QColor c );
 
QColor getRectColor() const;
void setRectColor( QColor c );
 
protected:
void paintEvent( QPaintEvent *e );
 
private:
QColor lineColor;
QColor rectColor;
};
 
#endif // SWIDGET_H
</code>
'''swidget.cpp'''
<code>
#include "swidget.h"


#include &lt;QWidget&amp;gt;
#include <QPainter>
#include <QDebug>


class SWidget : public QWidget<br />{<br /> Q_OBJECT<br /> Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor DESIGNABLE true)<br /> Q_PROPERTY(QColor rectColor READ getRectColor WRITE setRectColor DESIGNABLE true)
SWidget::SWidget(QWidget *parent) :
QWidget(parent)
{
}


public:<br /> explicit SWidget(QWidget *parent = 0);<br /> ~SWidget();
SWidget::~SWidget()
{
}


QColor getLineColor() const;<br /> void setLineColor( QColor c );
void SWidget::paintEvent( QPaintEvent *e )
{
QPainter p(this);
p.setPen( getLineColor() );
p.drawLine( 0,0, size().width(), size().height() );
p.setPen( getRectColor() );
p.drawRect( 5,5, size().width()–10, size().height()-10 );
}


QColor getRectColor() const;<br /> void setRectColor( QColor c );
QColor SWidget::getLineColor() const
{
return lineColor;
}


protected:<br /> void paintEvent( QPaintEvent *e );
void SWidget::setLineColor( QColor c )
{
qDebug() << "FUNCTION";
lineColor = c;
}


private:<br /> QColor lineColor;<br /> QColor rectColor;<br />};
QColor SWidget::getRectColor() const
{
return rectColor;
}


#endif // SWIDGET_H<br /></code><br />'''swidget.cpp'''<br /><code><br />#include &quot;swidget.h&amp;quot;
void SWidget::setRectColor( QColor c )
{
qDebug() << "FUNCTION";
rectColor = c;
}
</code>
'''main.cpp'''
<code>
#include <QApplication>
#include "mainwindow.h"
#include "swidget.h"


#include &lt;QPainter&amp;gt;<br />#include &lt;QDebug&amp;gt;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);


SWidget::SWidget(QWidget *parent) :<br /> QWidget(parent)<br />{<br />}
//create widget
SWidget *w = new SWidget();


SWidget::~SWidget()<br />{<br />}
//open and set style sheet
QFile f( "sheet.qss" );
if( f.open( QFile::ReadOnly ) )
{
QString ssheet = QLatin1String( f.readAll() );
a.setStyleSheet( ssheet );
}


void SWidget::paintEvent( QPaintEvent *e )<br />{<br /> QPainter p(this);<br /> p.setPen( getLineColor() );<br /> p.drawLine( 0,0, size().width(), size().height() );<br /> p.setPen( getRectColor() );<br /> p.drawRect( 5,5, size().width()–10, size().height()<s>10 );<br />}
w->show();
<br />QColor SWidget::getLineColor() const<br />{<br /> return lineColor;<br />}
<br />void SWidget::setLineColor( QColor c )<br />{<br /> qDebug() &lt;&lt; ''FUNCTION'';<br /> lineColor = c;<br />}
<br />QColor SWidget::getRectColor() const<br />{<br /> return rectColor;<br />}
<br />void SWidget::setRectColor( QColor c )<br />{<br /> qDebug() &lt;&lt; ''FUNCTION'';<br /> rectColor = c;<br />}<br /></code><br />'''main.cpp'''<br /><code><br />#include &lt;QtGui/QApplication&amp;gt;<br />#include &quot;mainwindow.h&amp;quot;<br />#include &quot;swidget.h&amp;quot;
<br />int main(int argc, char *argv[])<br />{<br /> QApplication a(argc, argv);
<br /> //create widget<br /> SWidget *w = new SWidget();
<br /> //open and set style sheet<br /> QFile f( &quot;sheet.qss&amp;quot; );<br /> if( f.open( QFile::ReadOnly ) )<br /> {<br /> QString ssheet = QLatin1String( f.readAll() );<br /> a.setStyleSheet( ssheet );<br /> }
<br /> w</s>&gt;show();


return a.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code><br />'''sheet.qss'''<br /><code><br />SWidget<br />{<br /> qproperty-lineColor: yellow;<br /> qproperty-rectColor: red;<br />}<br /></code>
return a.exec();
}
</code>
'''sheet.qss'''
<code>
SWidget
{
qproperty-lineColor: yellow;
qproperty-rectColor: red;
}
</code>


== Code Walkthrough ==
== Code Walkthrough ==


We need to define our custom widget and assign new properties for further. In this case we need two custom color properties. One for line color and one for rectangle color.<br /><code><br />class SWidget : public QWidget<br />{<br /> Q_OBJECT<br /> Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor DESIGNABLE true)<br /> Q_PROPERTY(QColor rectColor READ getRectColor WRITE setRectColor DESIGNABLE true)<br /></code>
We need to define our custom widget and assign new properties for further. In this case we need two custom color properties. One for line color and one for rectangle color.
<code>
class SWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor DESIGNABLE true)
Q_PROPERTY(QColor rectColor READ getRectColor WRITE setRectColor DESIGNABLE true)
</code>
 
Methods required by new properties:
<code>
QColor getLineColor() const;
void setLineColor( QColor c );
 
QColor getRectColor() const;
void setRectColor( QColor c );
</code>
 
We'll reimplement the paintEvent
<code>
protected:
void paintEvent( QPaintEvent *e );
</code>
 
Private members will hold our Q_PROPERTY values
<code>
private:
QColor lineColor;
QColor rectColor;
</code>
 
swidget.cpp
Paint event reimplementation. Drawing of line that goes across the widget and rectangle is performed in paintEvent for simplicty.
<code>
void SWidget::paintEvent( QPaintEvent *e )
{
QPainter p(this);
p.setPen( getLineColor() );
p.drawLine( 0,0, size().width(), size().height() );
p.setPen( getRectColor() );
p.drawRect( 5,5, size().width()–10, size().height()-10 );
}
</code>
 
Define the setters and getters for lineColor and rectColor properties.
NOTE: we're using qDebug() to make sure that our setters are being called in further widget restyling.
<code>
QColor SWidget::getLineColor() const
{
return lineColor;
}
 
void SWidget::setLineColor( QColor c )
{
qDebug() << "FUNCTION";
lineColor = c;
}
 
QColor SWidget::getRectColor() const
{
return rectColor;
}


Methods required by new properties:<br /><code><br /> QColor getLineColor() const;<br /> void setLineColor( QColor c );
void SWidget::setRectColor( QColor c )
{
qDebug() << "FUNCTION";
rectColor = c;
}
</code>


QColor getRectColor() const;<br /> void setRectColor( QColor c );<br /></code>
Let's go into main.cpp now.
We'll create very simple gui app that will show our custom widget:
<code>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);


We'll reimplement the paintEvent<br /><code><br />protected:<br /> void paintEvent( QPaintEvent *e );<br /></code>
//create widget
SWidget *w = new SWidget();
</code>


Private members will hold our Q_PROPERTY values<br /><code><br />private:<br /> QColor lineColor;<br /> QColor rectColor;<br /></code>
Open the sheet.qss file that holds qproperties for this application. If open is succeedded get data in QString '''ssheet''' and apply stylle sheet to QApplication object.
<code>
QFile f( "sheet.qss" );
if( f.open( QFile::ReadOnly ) )
{
QString ssheet = QLatin1String( f.readAll() );
a.setStyleSheet( ssheet );
}
</code>


swidget.cpp<br />Paint event reimplementation. Drawing of line that goes across the widget and rectangle is performed in paintEvent for simplicty.<br /><code><br />void SWidget::paintEvent( QPaintEvent *e )<br />{<br /> QPainter p(this);<br /> p.setPen( getLineColor() );<br /> p.drawLine( 0,0, size().width(), size().height() );<br /> p.setPen( getRectColor() );<br /> p.drawRect( 5,5, size().width()–10, size().height()<s>10 );<br />}<br /></code>
Show widget and enter main event loop.
<br />Define the setters and getters for lineColor and rectColor properties.<br />NOTE: we're using qDebug() to make sure that our setters are being called in further widget restyling.<br /><code><br />QColor SWidget::getLineColor() const<br />{<br /> return lineColor;<br />}
<code>
<br />void SWidget::setLineColor( QColor c )<br />{<br /> qDebug() &lt;&lt; ''FUNCTION'';<br /> lineColor = c;<br />}
w->show();
<br />QColor SWidget::getRectColor() const<br />{<br /> return rectColor;<br />}
<br />void SWidget::setRectColor( QColor c )<br />{<br /> qDebug() &lt;&lt; ''FUNCTION'';<br /> rectColor = c;<br />}<br /></code>
<br />Let's go into main.cpp now.<br />We'll create very simple gui app that will show our custom widget:<br /><code><br />int main(int argc, char *argv[])<br />{<br /> QApplication a(argc, argv);
<br /> //create widget<br /> SWidget *w = new SWidget();<br /></code>
<br />Open the sheet.qss file that holds qproperties for this application. If open is succeedded get data in QString '''ssheet''' and apply stylle sheet to QApplication object.<br /><code><br /> QFile f( &quot;sheet.qss&amp;quot; );<br /> if( f.open( QFile::ReadOnly ) )<br /> {<br /> QString ssheet = QLatin1String( f.readAll() );<br /> a.setStyleSheet( ssheet );<br /> }<br /></code>
<br />Show widget and enter main event loop.<br /><code><br /> w</s>&gt;show();


return a.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>
return a.exec();
}
</code>


Inside sheet.qss we're defining line and rectangle color for SWidget<br /><code><br />SWidget<br />{<br /> qproperty-lineColor: yellow;<br /> qproperty-rectColor: red;<br />}<br /></code>
Inside sheet.qss we're defining line and rectangle color for SWidget
<code>
SWidget
{
qproperty-lineColor: yellow;
qproperty-rectColor: red;
}
</code>


Please note that all SWidget widget we'll be styled in the same way.
Please note that all SWidget widget we'll be styled in the same way.


In Case that we have:<br /><code><br />SWidget *w = new SWidget();<br />SWidget *w2 = new SWidget();<br /></code><br />and want custom look of each of them, we need to add names for them:<br /><code><br />w-&gt;setObjectName(&quot;w1&amp;quot;);<br />w2-&gt;setObjectName(&quot;w2);<br /></code>
In Case that we have:
<code>
SWidget *w = new SWidget();
SWidget *w2 = new SWidget();
</code>
and want custom look of each of them, we need to add names for them:
<code>
w->setObjectName("w1");
w2->setObjectName("w2);
</code>


Noe, sheet.qss may look like this:<br /><code><br />SWidget#w1<br />{<br /> qproperty-lineColor: yellow;<br /> qproperty-rectColor: red;<br />}<br />SWidget#w2<br />{<br /> qproperty-lineColor: blue;<br /> qproperty-rectColor: white;<br />}<br /></code>
Noe, sheet.qss may look like this:
<code>
SWidget#w1
{
qproperty-lineColor: yellow;
qproperty-rectColor: red;
}
SWidget#w2
{
qproperty-lineColor: blue;
qproperty-rectColor: white;
}
</code>

Revision as of 01:46, 24 March 2016

Introduction

This example demonstrates:

  1. use of qt style sheets
  2. use of Q_PROPERTY
  3. how to combine 1 and 2 with custom painting

In this example we have some custom widget that has reimplemented paintEvent function and inside, some custom painting is performed. We'll see how to set custom colors for for shapes and lines via Qt Style Sheet mechanism. Thanks to it, we can easily change the colors inside the .qss file without recompiling the program.

Example Source code

swidget.h

#ifndef SWIDGET_H
#define SWIDGET_H

#include <QWidget>

class SWidget : public QWidget
{
 Q_OBJECT
 Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor DESIGNABLE true)
 Q_PROPERTY(QColor rectColor READ getRectColor WRITE setRectColor DESIGNABLE true)

public:
 explicit SWidget(QWidget *parent = 0);
 ~SWidget();

QColor getLineColor() const;
 void setLineColor( QColor c );

QColor getRectColor() const;
 void setRectColor( QColor c );

protected:
 void paintEvent( QPaintEvent *e );

private:
 QColor lineColor;
 QColor rectColor;
};

#endif // SWIDGET_H

swidget.cpp

#include "swidget.h"

#include <QPainter>
#include <QDebug>

SWidget::SWidget(QWidget *parent) :
 QWidget(parent)
{
}

SWidget::~SWidget()
{
}

void SWidget::paintEvent( QPaintEvent *e )
{
 QPainter p(this);
 p.setPen( getLineColor() );
 p.drawLine( 0,0, size().width(), size().height() );
 p.setPen( getRectColor() );
 p.drawRect( 5,5, size().width()10, size().height()-10 );
}

QColor SWidget::getLineColor() const
{
 return lineColor;
}

void SWidget::setLineColor( QColor c )
{
 qDebug() << "FUNCTION";
 lineColor = c;
}

QColor SWidget::getRectColor() const
{
 return rectColor;
}

void SWidget::setRectColor( QColor c )
{
 qDebug() << "FUNCTION";
 rectColor = c;
}

main.cpp

#include <QApplication>
#include "mainwindow.h"
#include "swidget.h"

int main(int argc, char *argv[])
{
 QApplication a(argc, argv);

 //create widget
 SWidget *w = new SWidget();

 //open and set style sheet
 QFile f( "sheet.qss" );
 if( f.open( QFile::ReadOnly ) )
 {
 QString ssheet = QLatin1String( f.readAll() );
 a.setStyleSheet( ssheet );
 }

 w->show();

return a.exec();
}

sheet.qss

SWidget
{
 qproperty-lineColor: yellow;
 qproperty-rectColor: red;
}

Code Walkthrough

We need to define our custom widget and assign new properties for further. In this case we need two custom color properties. One for line color and one for rectangle color.

class SWidget : public QWidget
{
 Q_OBJECT
 Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor DESIGNABLE true)
 Q_PROPERTY(QColor rectColor READ getRectColor WRITE setRectColor DESIGNABLE true)

Methods required by new properties:

 QColor getLineColor() const;
 void setLineColor( QColor c );

QColor getRectColor() const;
 void setRectColor( QColor c );

We'll reimplement the paintEvent

protected:
 void paintEvent( QPaintEvent *e );

Private members will hold our Q_PROPERTY values

private:
 QColor lineColor;
 QColor rectColor;

swidget.cpp Paint event reimplementation. Drawing of line that goes across the widget and rectangle is performed in paintEvent for simplicty.

void SWidget::paintEvent( QPaintEvent *e )
{
 QPainter p(this);
 p.setPen( getLineColor() );
 p.drawLine( 0,0, size().width(), size().height() );
 p.setPen( getRectColor() );
 p.drawRect( 5,5, size().width()10, size().height()-10 );
}

Define the setters and getters for lineColor and rectColor properties. NOTE: we're using qDebug() to make sure that our setters are being called in further widget restyling.

QColor SWidget::getLineColor() const
{
 return lineColor;
}

void SWidget::setLineColor( QColor c )
{
 qDebug() << "FUNCTION";
 lineColor = c;
}

QColor SWidget::getRectColor() const
{
 return rectColor;
}

void SWidget::setRectColor( QColor c )
{
 qDebug() << "FUNCTION";
 rectColor = c;
}

Let's go into main.cpp now. We'll create very simple gui app that will show our custom widget:

int main(int argc, char *argv[])
{
 QApplication a(argc, argv);

 //create widget
 SWidget *w = new SWidget();

Open the sheet.qss file that holds qproperties for this application. If open is succeedded get data in QString ssheet and apply stylle sheet to QApplication object.

 QFile f( "sheet.qss" );
 if( f.open( QFile::ReadOnly ) )
 {
 QString ssheet = QLatin1String( f.readAll() );
 a.setStyleSheet( ssheet );
 }

Show widget and enter main event loop.

 w->show();

return a.exec();
}

Inside sheet.qss we're defining line and rectangle color for SWidget

SWidget
{
 qproperty-lineColor: yellow;
 qproperty-rectColor: red;
}

Please note that all SWidget widget we'll be styled in the same way.

In Case that we have:

SWidget *w = new SWidget();
SWidget *w2 = new SWidget();

and want custom look of each of them, we need to add names for them:

w->setObjectName("w1");
w2->setObjectName("w2);

Noe, sheet.qss may look like this:

SWidget#w1
{
 qproperty-lineColor: yellow;
 qproperty-rectColor: red;
}
SWidget#w2
{
 qproperty-lineColor: blue;
 qproperty-rectColor: white;
}