Qt Stylesheets Tutorial

Stylesheets add spicy flavor to your boring Qt GUIs.

For a long time, Qt has allowed you to decorate your GUIs with CSS’ish style sheets. Inspired by the web, stylesheets are a great way to stylize your Qt GUI, but it seems that few people use them. In this tutorial, we’ll create an example dialog in Qt using Designer and stylesheets. This tutorial assumes that you can get around in Qt Designer, and that you understand a little about Qt layouts.

Step 1 Create a new empty form, named MyLoginForm.

Step 2 Add a QFrame to your form, and apply a vertical layout to your form (any layout will work actually: vertical, horizontal or grid). Give your form about 30 pixels of layout margin around its perimeter. Name the QFrame “mainFrame”. When dealing with stylesheets, it’s convenient to name your widgets in Designer, even if you don’t plan to use them by name in your code (we won’t be writing any code besides CSS in this tutorial).

Step 3 In Designer’s object inspector, right-click on the top-level entry in the tree (called “MyLoginForm”), and select “Change styleSheet…” from the menu. You’ll get a little editor dialog like this:

This is where we specify the style sheet for our form. You can put a style sheet on any widget in your form, but I prefer to do all my stylizing at the parent widget (“MyLoginForm” in this case). I prefer to do it this way because you’ll never have to go hunting to find your style sheet — it’s all in one place in your form. Since stylesheets cascade down to the child widgets, you can stylize any widget in your form from this point.

Side note: “CSS” stands for “Cascading Style Sheets”

Let’s type in some CSS into the style sheet editor, like this:

#MyLoginForm {
background: gray;
}


#mainFrame {
border: 3px solid gray;
border-radius: 40px;
background: white;
}

After clicking OK on the editor dialog, you should see this:

If your’s doesn’t look like this, you may have forgotten to change the parent widget’s name to “MyLoginForm” or the QFrame’s name to “mainFrame” (yes, capitalization does matter — Qt stylesheets are case sensitive). Or you may have mistyped something into the CSS dialog.

One cool feature is that you get to preview the style changes right as you make them. You don’t have to compile, save, or run anything. Designer does a very good job of showing your stylesheet changes live (WYSIWYG for you old-timers).

Let me explain what we just did. In CSS, a pound sign, ‘#’, in front of a name is how we stylize an individual widget by that name. In our example, #MyLoginForm identifies the parent widget (i.e., the background area). All we did there is give it a gray background with background: gray;.

For #mainFrame, we gave it a thick gray border, a white background, and rounded corners.

Step 4 Let’s add some widgets to make this dialog actually do something. Drag and drop a pair of QLineEdits, QLabels, and a single QPushButton on the form inside “mainFrame” and arrange them roughly like this:

Step 5 Now apply a grid layout to “mainFrame”. Just select “mainFrame” by clicking on it (taking care not to accidentally select one of the QLineEdits or QLabels instead). Then click the grid layout button in Designer’s toolbar (optionally, you can go to the menu bar and click “Form” -> “Lay Out in a Grid”, or just press Ctrl+5 for you keyboard hackers).

Then give your layout some margin. I used 50 pixels of margin and 15 pixels for both vertical and horizontal spacing.

This is what you should have now:

Step 6 Let’s stylize those boring QPushButton and QLineEdits. Add this to the style sheet for MyLoginForm:

QLineEdit {
padding: 1px;
border-style: solid;
border: 2px solid gray;
border-radius: 8px;
}


QPushButton {
color: white;
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #88d, stop: 0.1 #99e, stop: 0.49 #77c, stop: 0.5 #66b, stop: 1 #77c);
border-width: 1px;
border-color: #339;
border-style: solid;
border-radius: 7;
padding: 3px;
font-size: 10px;
padding-left: 5px;
padding-right: 5px;
min-width: 50px;
max-width: 50px;
min-height: 13px;
max-height: 13px;
}

Notice that we didn’t use the pound sign this time. When you omit the pound sign, you are specifying a “class” of widgets to stylize instead of a single widget by name. So in this case, we stylized all widgets of type “QLineEdit” and “QPushButton” (and any widget that may inherit from those widgets too).

That gives the QPushButton a cool gradient look and rounds the edges of the QLineEdits, like this:

Step 7 Now let’s make that boring white background a gradient instead. Replace the “background: white;” line in the “#mainFrame” section with this instead:

background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #eef, stop: 1 #ccf);

Now you should see this:

Step 8 Since stylizing is all about detail and little tweaks, let’s mess a bit with the label font and the background color by changing the background for “#MyLoginForm” to “background: white”, and adding this:

QLabel {
font-weight: bold;
font-size: 15px;
}

Now we get our finished product:

Isn’t it great how much you can do in Designer with style sheets? There are even things you can do with style sheets that can’t be done without writing lots of yucky C++ code. For example, you can change the border style of just a single side of a QFrame.

Oddities

There is one gotcha to keep in mind when using style sheets: Once you use a style sheet, it will often override other properties, like the “font” property or the “frameStyle” property. Keep this in mind when Designer changes properties you didn’t expect.

The other oddity with style sheets is that there’s no way to “include” external style sheet files into your widget’s style sheet. This means that you can’t have a common style sheet that gets applied to your entire application like you can in the web. I have a Qt patch that allows you to do this, but so far the Trolls haven’t done anything with it (to my knowledge). This would be immensely useful.

Cross Platform Note
A style sheet tutorial wouldn’t be complete without a comment on cross-platform issues. The dialog we just designed will look exactly the same on Linux, Windows, and Mac OS X because we stylized it so aggressively. If you want your widgets to look native on each platform, you should generally use style sheets sparingly, but if your goal is to have a consistent look across all platforms, style sheets are your best friend.

Conclusion

Now that I have discovered the power of style sheets in Qt, I use them whenever possible. What cool things have you done with Qt style sheets?

83 comments to “Qt Stylesheets Tutorial”

You can leave a reply or Trackback this post.
  1. http://Todd%20Firkins says: -#1

    I don’t even have a blog, so yours is definitely better than mine!

    Great tip, I was going nuts trying to figure out how to set a background image on a QDialog that did not affect all the child widgets. This did the trick and inspired further tinkering. Thanks!

  2. http://Barani%20Kumar%20V says: -#1

    Very good work

    Thanks

  3. http://Ismael%20Olusola says: -#1

    Thanks for this really helped alot. May I ask is there anyway to link a QT which one started with the form layout with the QML (QT Quick) method. I am trying to use see if I can use methods that are available to both types.

    Sorry i am just a beginner and just started finding my way around.

  4. hi,

    how I can remove the margin between mainwindow and the frame, this happend when you put the frame in “lay out in a grid”

    that’s all I hope your help

  5. http://public says: -#1

    thx very much, it’s very useful for me.
    u’re EXCELLENT

  6. http://tmcb says: -#1

    Your patch to import css files into designer sounds great! How can we partition the Qt powers to incorporate your patch into a future Qt release?

  7. http://cheyanne says: -#1

    Hi, i tried to apply a background image using
    #grapicsView {
    border: 3px solid gray;
    border-radius: 40px;
    background-image: url(:/Qt_robotino/image/kinect.png)
    }
    when i preview everything works out fine, but when i run my program, everything came out except for the image, what went wrong ?

  8. Cheyanne, did you add kinect.png to your project’s .qrc file at the path of /Qt_robotino/image ?

  9. And did you remember to add the .qrc file to the RESOURCES in your .pro file?

  10. http://cheyanne says: -#1

    image/kinect.png

    this is my .qrc file. Is is correct?

  11. http://cheyanne says: -#1

    and yeap, i added it inside .pro file as well, RESOURCES += qtimage.qrc

  12. That looks incorrect, because you are referring to the image as :/Qt_robotino/image/kinect.png, which would mean that you need a prefix of “Qt_robotino” in your .qrc file.

  13. http://cheyanne says: -#1

    changed it to this, but its still not working. everything is displayed except for the image.

    image/kinect.png

  14. http://cheyanne says: -#1

    i mean added the prefix already

  15. There’s definitely something wrong with your .qrc configuration somewhere.

  16. thanks a lot from France.
    Every tutorial I read make me think that Qt is a great tool

  17. Hi Dave,

    this is for sure a reference tutorial, still now.

    Nevertheless, I have spent hours to figure out why the mainfraime allways stay in white with no border. This is strange as when I copy paste your code in the “stylesheet” designe editor, this is fine. But at runtime the frame is rounded and white, no border.

    If you have any idea, for my brain’s sake

    PS : I also found that I need to do a “recompile” instead of compile to have changes applied from my outside stylesheet.

  18. Mouha: Does your mainFrame have rounded corners, or is it just a solid white rectangle with no border, shape or color?

    Also, are you compiling your stylesheet using a .qrc file? That would explain why you have to recompile your application to get it to take effect.

  19. http://Rooney says: -#1

    Hello Dave!

    I’m having similar problems as Linda (see 2010-02-01).

    I use a global style sheet for my application and it works as it should if I use the Qt types like
    QCheckBox {
    spacing: 5px;
    }

    I don’t use the Qt Designer at all, building my user interface directly in C++. If I want to apply a style to a specified checkbox using its name, does not work. Do you have any idea? I’m using Qt 4.7.4.

    #myCheckBox {
    spacing: 5px;
    }

    myCheckBox = new QCheckBox(tr(“Hello World”));

    I even tried to reload the style sheet immediately after the checkbox has been created, but this doesn’t succeed either.

    Regards,
    Rooney

  20. http://Rooney says: -#1

    Upps, found the error… It may help others as well.

    It works if the object name is set in code. Obviously this is not done automatically if building the user interface directly in C++.

    myCheckBox ->setObjectName(“myCheckBox “);

  21. Rooney,

    You need to call this in C++:

    myCheckBox->setObjectName(“myCheckBox”);

    That’s how the style sheet system will identify the widget.

  22. http://pramod says: -#1

    Is there any way to remove the style sheet after it has been set? I’m looking for the inverse of the setStyleSheet() method. Thanks!

  23. pramod, yes, pass an empty string to setStyleSheet().

  24. http://Pratik says: -#1

    Just came across the page when I was looking for QT style-sheets. Extremely well organized and nice explanation. Good work. Keep it up.

  25. http://lukiasz says: -#1

    Thanks for this great tutorial! I’d never thought how cute Qt can be :) Here are mine results: http://s17.postimage.org/t9q8x6um7/Przechwytywanie.png

    And corresponding css:

    #MainWindow {
    background: #38395a;
    }

    #frame {
    border: 1px solid gray;
    border-radius: 7px;
    background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #38395a, stop: 1 #141529);
    }
    QLabel {
    font-size: 14px;
    font-variant:small-caps;
    font-family: courier;
    color: white;
    }

    #label {
    font-weight: bold;
    font-size: 20px;
    color: white;
    }

    QLineEdit {
    padding: 1px;
    border-style: solid;
    border: 1px solid ;
    color: white;
    border-radius: 2px;
    border-color: #141529;
    background-color: #6d6d80;
    }

    QPushButton {
    color: white;
    background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #88d, stop: 0.1 #444450, stop: 0.49 #444450, stop: 0.5 #3c3c46, stop: 1 #1f1f24);
    border-width: 1px;
    border-color: #141529;
    border-style: solid;
    border-radius:4;
    padding: 3px;
    font-size: 14px;
    font-variant:small-caps;
    font-family: courier;
    padding-left:5px;
    padding-right: 5px;
    min-width: 50px;
    max-width: 50px;
    min-height: 13px;
    max-height: 13px;
    }

  26. http://Mardi says: -#1

    Hi Dave,

    That was a nice Tutorial… ::thumb up::

    I try to add simple background image on Qwidget main object. it can display when I try to preview it (alt + shit + R), but..
    I could not see the backgound image when I try to run build and ‘test’ running my application.

    can you help me with this confusing?

    Regards

  27. http://Danny says: -#1

    Hi,

    I dont normally post on these type of things but this is an outstanding tutorial. Nice and clear, clean and just works. You my sir are what’s called a legend !

    Thanks

  28. http://Chris says: -#1

    Oddity of qt… Can’t include an external stylesheet…
    OK, but you can load a stylesheet as a string and apply that. Therefore you can have your css in an external file and modify it without recompiling. One day I might even have a settings tab in my app allowing the user to browse for a stylesheet! But in the meantime:

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    QFile qss(“style.css”);
    qss.open(QFile::ReadOnly);
    this->setStyleSheet(qss.readAll());
    qss.close();

    ui->setupUi(this);
    }

    Simple as that.

  29. But you can’t preview it in designer, which sucks.

  30. http://Pardeep%20Sharma says: -#1

    Hi,
    I want to set stylesheet for whole QApplication in qt. but i want that user select from many stylesheet file at run time & theme style sheet apply. so how can i do that. please help me for that…

  31. http://vivek says: -#1

    QComboBox radious effect also on dropdown button ???????

  32. It’s not that easy and perfect as it seems. Just because there is no systematization in controls style. Also cascading makes a lot of troubles.

    There should be methods to change everything you can set by style with code. But when you use code for dynamic changing of control looks you will have a lot of troubles too. For example you can’t change background color for all widgets with one way for all. And you can’t control a lot of things you can set by styles.
    At least it looks not that easy to find what you need.

    Dynamic and animation is the other weak place. I think Qt goes the wrong way with it. I’ve spend a day trying to paint my controls in red. or put a border around when I wanted to highlight necessary fields dynamically;

    And actually there is no flexible decision for it.
    because calling setStyleSheet for every control and parse style every time is not a decision I think.

  33. Hi, the tutorial is quite enlightening and it has answered a lot of my question on qt widget style sheet but i’d like to know how to put background image, i dont know how to go about the resources icon on the stylesheet.

Comment pages