Qt/Vista webinar

Naren Karattup (our product manager) and I did a webinar two weeks back titled “Bringing C++ to Vista: Leveraging Your C++ Code-Base to Create Native Windows® Vista™ Applications”. If you missed it, you can now see it offline here. From the webcast link “We recommend the following operating systems: Windows XP SP2, and Mac OS X 10.4″. Sigh. Nevertheless, once you register, you should be able to see the slides.

twitter

Styling QSlider, QHeaderView

QSlider
I have been avoiding QSlider for sometime now. Sliding the QSlider would have been straightforward if the code was correct :) . You need this teeny weeny patch against 4.3 (If you are using a week old 4.3 snapshot, you are good). Comments inline.


QSlider::groove:horizontal {
border: 1px solid #999999;
height: 8px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);
}
QSlider::handle:horizontal {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f8f8f);
border: 1px solid #5c5c5c;
width: 18px;
margin: -2px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */
border-radius: 3px;
}

Here’s how it looks:
Slider

If you require more control, play around with something like this (note that this is a vertical slider):

QSlider::groove:vertical {
background: red;
position: absolute; /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */
left: 4px; right: 4px;
}
QSlider::handle:vertical {
height: 10px;
background: green;
margin: 0 -4px; /* expand outside the groove */
}
QSlider::add-page:vertical {
background: white;
}
QSlider::sub-page:vertical {
background: pink;
}

QHeaderView
I thought I will have a go at something that looks like the header view in this plasmoid and show some advanced usage of the new pseudo states but I gotta run (and this posts been sitting as a draft for way too long).


QHeaderView::section {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop: 0.5 #505050, stop: 0.6 #434343, stop:1 #656565);
color: white;
padding-left: 4px;
border: 1px solid #6c6c6c;
}

Here’s how it looks:
Header view

twitter

Styling the tab widget

Today we will look at the styling of one of the most complex widgets (when it comes to styling) in Qt – The QTabWidget. Fasten your seat belts so you don’t get blown away ;)

Comments inline.


QTabWidget::pane { /* The tab widget frame */
border-top: 2px solid #C2C7CB;
}
QTabWidget::tab-bar {
left: 5px; /* move to the right by 5px */
}
/* Style the tab using the tab sub-control. Note that it reads QTabBar _not_ QTabWidget */
QTabBar::tab {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);
border: 2px solid #C4C4C3;
border-bottom-color: #C2C7CB; /* same as the pane color */
border-top-left-radius: 4px;
border-top-right-radius: 4px;
min-width: 8ex;
padding: 2px;
}
QTabBar::tab:selected, QTabBar::tab:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fafafa, stop: 0.4 #f4f4f4, stop: 0.5 #e7e7e7, stop: 1.0 #fafafa);
}
QTabBar::tab:selected {
border-color: #9B9B9B;
border-bottom-color: #C2C7CB; /* same as pane color */
}
QTabBar::tab:!selected {
margin-top: 2px; /* make non-selected tabs look smaller */
}

This is how it looks:

Tab widget take one

“But but but… I want overlapping tabs!”. Negative margins to the rescue. Add this to the style sheet above.

/* IMPORTANT: 8< Add the code above here 8< */
QTabBar::tab:selected {
/* expand/overlap to the left and right by 4px */
margin-left: -4px;
margin-right: -4px;
}
QTabBar::tab:first:selected {
margin-left: 0; /* the first selected tab has nothing to overlap with on the left */
}
QTabBar::tab:last:selected {
margin-right: 0; /* the last selected tab has nothing to overlap with on the right */
}
QTabBar::tab:only-one {
margin: 0; /* if there is only one tab, we don't want overlapping margins */
}

Here’s how it looks:

Tab widget with overlapping tabs

You can also play around with fonts and colors. For example,

QTabBar::tab:selected { font: bold; color: green; }

You can move the tab bar to the center and adjust the pane using something like,

/* 8< remove the tab-bar rule and the margin-top rule in the first stylesheet */
QTabWidget::tab-bar { alignment: center; }
QTabWidget::pane { position: absolute; top: -0.5em; }

Tab Widget with centered tabs

Note that the above style sheets style assumes the tab bar to be at the top. You can use the :left, :right, :top, :bottom pseudo states for the position of the tab bar. There is also, :next-selected to indicate the next tab is selected, :previous-selected to indicate the previous tab is selected, :middle for a tab that is not the first or the last (same as :!first:!last). With some creative use of the above pseudo states, you can “merge” adjacent tab borders like in Plastique. And of course, you can use border-images to have the tabs curve in to the tab pane.

twitter

Styling QProgressBar and QScrollBar

Qt 4.3 Style Sheets, as you most likely know, introduces styling of most widgets. The documentation is a quite silent when it comes to providing “style templates” – templates that you can just copy/paste and get started with styling the widget. Today, I started creating templates for QProgressBar and QScrollBar. All this will become a part of 4.3.1 Style Sheet documentation.

QProgressBar

QProgressBar:horizontal {
border: 1px solid gray;
border-radius: 3px;
background: white;
padding: 1px;
}
QProgressBar::chunk:horizontal {
background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, stop: 0 green, stop: 1 white);
}

Here’s what you get:
Progress Bar with no chunk width

You say “Oh sweet, but I want WindowsXP like progress bars. And the label needs to be outside since its easier to read”. Yeah, sure.

QProgressBar:horizontal {
border: 1px solid gray;
border-radius: 3px;
background: white;
padding: 1px;
text-align: right;
margin-right: 4ex;
}
QProgressBar::chunk:horizontal {
background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, stop: 0 green, stop: 1 white);
margin-right: 2px; /* space */
width: 10px;
}

Right aligned text in progress bar

Note that you need set the height for vertical progress bars. You can use “:indeterminate” for indeterminate progress bars. And there’s a small bug which breaks text alignment (fixed in 4.3.1).

QScrollBar


QScrollBar:horizontal {
border: 2px solid green;
background: cyan;
height: 15px;
margin: 0px 20px 0 20px;
}
QScrollBar::handle:horizontal {
background: gray;
min-width: 20px;
}
QScrollBar::add-line:horizontal {
background: blue;
width: 20px;
subcontrol-position: right;
subcontrol-origin: margin;
}
QScrollBar::sub-line:horizontal {
background: white;
width: 20px;
subcontrol-position: left;
subcontrol-origin: margin;
}
QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal {
width: 3px;
height: 3px;
background: pink;
}
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
background: none;
}

Here’s the awful but didactic screenshot:
Scroll bar

Style sheets are so powerful that you can actually place those add-line, remove-line button anywhere!

QScrollBar:horizontal {
border: 2px solid green;
background: cyan;
height: 15px;
margin: 0px 40px 0 0px;
}
QScrollBar::handle:horizontal {
background: gray;
min-width: 20px;
}
QScrollBar::add-line:horizontal {
background: blue;
width: 16px;
subcontrol-position: right;
subcontrol-origin: margin;
border: 2px solid black;
}
QScrollBar::sub-line:horizontal {
background: magenta;
width: 16px;
subcontrol-position: top right;
subcontrol-origin: margin;
border: 2px solid black;
position: absolute;
right: 20px;
}
QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal {
width: 3px;
height: 3px;
background: pink;
}
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
background: none;
}

Advanced styling of QScrollBar

For vertical scroll bars, you will need to replace width with height and use up-arrow and down-arrow. That said, remove those boring borders, slap in a few border-images, gradients and background color and it’s simple to create beautiful custom scroll bars.

twitter

Lineedit with a clear button

It looks like people have taken a deep liking to having line edits with a clear button. Like the one Aaron made. Since many seem to have missed that post, here’s my take on a QLineEdit with a clear button.

lineedit.h
lineedit.cpp

The code is fairly trivial. So, I won’t bother explaining. The clear button appears only when the line edit has text. Here’s how it looks,

Line edit with no text,
Line edit with no text

Line edit with some text (clear button appears)
Line edit with some text

Line edit with lotsa text (text doesn’t go underneath clear button)
Line edit with lots of text

Update: I got a question asking how to implement the search line edit with a menu, like in thunderbird. The clear button is a QToolButton. Just set a menu :) To move it to the left, just use padding-left and move the clear button appropriately.

twitter

Backgrounds, Pseudo states – Qt 4.3 Style Sheets

Since I will be posting lot of Style sheets, I figured this is about the right time to point out that Qt 4.3 Designer has a built-in CSS Syntax validator and highlighter. Just right click on any widget and “Edit Stylesheet…”. (screenshot here.)

Background
Qt 4.3 introduces support for background images in any QAbstractScrollArea derivative. This means you can set a background-image on a QTextEdit, QTextBrowser or any of the item views. Use background-attachment to fix or scroll the background-image w.r.t the viewport.


QTextEdit, QListView {
background-color: white;
background-image: url(/tmp/draft.png);
background-attachment: scroll;
}

Here’s how the QTextEdit looks when you are at beginning of the document,
Unscrolled QTextEdit

The background-image scrolls as you scroll,
Scrolled QTextEdit

CSS3 brings a lot of new background properties. Their usefulness is debatable but we implemented them for sake of completeness :) . Here’s a really whacky example,

QTextEdit {
margin: 5px;
border: 2px solid green;
padding: 3px;
background-color: white;
background-image: url(/tmp/draft.png);
background-origin: content;
background-clip: border;
background-attachment: scroll;
background-repeat: repeat-y;
background-position: top right;
}

Pseudo States
Qt 4.3 almost triples the number of Pseudo States. Well, they should really be called Pseudo classes now but our documentation team prefers sticking to the 4.2 terminology to avoid confusion. Orientation, direction, position and many UI properties of widgets that are useful in styling like “default”, “flat”, “no-frame”, “read-only” have been added.

We also added support for negation using “!” (CSS3 recommends ::not).


QPushButton:flat:default:!focus:!hover {
/* applies to a flat default push button that does not have focus or hover state. */
}

twitter

Qt 4.3 and Style Sheets

There’s been a tremendous amount of action in the Qt Style Sheet world for 4.3. I have been extremely busy managing the release, but now with 4.3.0 out, I have all the time to blog about the Style Sheet features we have added for 4.3 :) .

To start with, have you noticed Style Sheet documentation lately? 4.3 brings a whole new bunch of Pseudo States, Sub-controls. The widget documentation explains in detail how to style each and every widget. For 4.3.1, our doc team is working on a shiny new example and more detailed text in the documentation.

Over the coming weeks, I will go over each enhancement in detail. I will start with my personal favorite – specifying gradients in Style Sheets. Gradients are specified in ObjectBoundingMode (Thanks, Zack!).

Try this,

QPushButton {
border-radius: 6px;
border: 2px solid #8f8f91;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #f6f7fa, stop: 1 #dadbde);
}

QPushButton:pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dadbde, stop: 1 #f6f7fa);
}

This is how it looks (default and pressed):
Push Button with gradient background

First thing to notice, the notorious border-radius bug is fixed. The background is now clipped when specifying a border-radius. Second, all colors are now Brushes. A Brush can be a color (as in 4.2) or gradients or a palette entry. It follows that we can specify the text color as a gradient too,


QGroupBox {
color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 lightblue, stop: 1 navy);
}

GroupBox with gradient title

Since I am too lazy to take more screenshots :) , Here’ some more stuff to try,

QListWidget, QLineEdit {
selection-background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 lightblue, stop: 1 navy);
}

twitter

Qt 4.3.0 released

We just released 4.3.0. The What’s new page gives a comprehensive list of new features in Qt 4.3. One of the things about the open development process we have at Trolltech is that it leaves no room for surprise :) . So sorry, there is not a single surprise feature that we have not blogged or publicized already that I can mention in this post.

By popular demand, our changelog now mentions the public task number (wherever possible). You can use the trasktracker to get more information about the change. We will keep up this trend for future releases.

The other day all of Oslo dev met up at the terrace for some cake :) Here’s the 4.3 Oslo development team (click on the image and hover over the faces to see names).

Oslo development team

Here’s our Berlin team (click on the image and hover over the faces to see names)

Berlin development team

Hope you have as much fun using 4.3.0 as much as we had developing it.

Update 1: Added missing team members to picture
Update 2: Added Roberto and corrected Sam’s picture

twitter

Qt Single Source Package

There we have it – A single source package that you can use to compile Qt on any platform. The zip package is for users who prefer Windows line endings in Qt source files. In contrast, the tar.gz package contains Unix line endings. The tar.bz2 packages are, ummm, a mistake (they will die shortly).

The term “all” is a bit misleading since the package contains only sources of Qt/X11, Qt/Win and Qt/Mac (and does not contain Qtopia Core). Thus, the name of the package is subject to change before the final 4.3.0 release.

We haven’t quite found the time to test shadow builds for 4.3. This doesn’t mean that they do not work. It only means that they are completely unsupported :)

Commercial customers, please contact our support department to get access to the “all” commercial package. Note that you will have access to this package only if you have X11, Windows AND Mac licenses.

Update: Updated note for commercial customers.

twitter