ariya
Qt
Graphics Dojo
Posted by ariya
 in Qt, Graphics Dojo
 on Sunday, July 13, 2008 @ 14:27

Distorting the geometry of an image with a specific periodic pattern can give the illusion of being underwater. This trick was for example employed in the very first version of Quake, either to oscillate the water surface or to modify the view when you jump inside the water. Apparently, it is not difficult to do that, even with pixel-per-pixel manipulation of QImage.

Check out the code from the usual place:

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/underwater

It is recommended to build the program and see the effect by yourself, the following screenshot can hardly describe the animation. As usual, once the example is running (it would show the included bridge picture), you can change the picture by dragging an image (from local disk or a web browser, e.g. Flickr or Picasa Web) and dropping it on the main window.

Qt for doing underwater effect

Note: the snappers picture is from james_wicks, distributed under the Creative Commons Attribution 2.0 Generic.

Friedemann Kleint
Qt
 in Qt
 on Monday, July 07, 2008 @ 09:01

Hi there. Introducing myself, my name is Friedemann Kleint, and I am one of the trolls hacking away at Qt Designer at the Berlin Office.

Today, I would like to draw your attention to the QFormLayout class. This is a special layout class suited to the common descriptive label - control arrangement found in many dialogs. It thas been developed in cooperation between Brisbane, Oslo and Berlin.

A typical form layout looks like this:

QFormLayout example 1

QFormLayout example 2

Note how the layout takes care of the label alignment according to the platform style. By the way, did you know that you can open several previews in different styles in Designer to compare them?

At first sight, QFormLayout looks like an ordinary grid. However, the layout also has policies for wrapping rows when it shrinks. For example, when setting the property rowWrapPolicy to WrapLongRows, we might get:

QFormLayout’s wrapping policy in effect

Let’s first have a look at the code. You might have created a such dialogs using QGridLayout, previously. This required some housekeeping of the current row. This is no longer necessary with QFormLayout using the addRow() convencience function. You don’t have to explicitly create the label, either:

QFormLayout *formLayout = new QFormLayout;
formLayout->addRow("Name", new QLineEdit);

For completeness, there is a setWidget() function which allows you to address single cells. It takes a row parameter and an ItemRole enumeration, which can be one of QFormLayout::LabelRole or QFormLayout::FieldRole.

In Qt Designer, you can create such arrangements as would in the case of a QGridLayout; you place the controls on a form and choose “Lay Out in a Form Layout”.

Hint: If you have existing .ui files containing such 2-column grid layouts and want to migrate them to the form layout, it might be sufficient to just replace the layout element <layout class="QGridLayout" name="gridLayout" ></layout> by something like <layout class="QFormLayout" name="formLayout" ></layout> (after making a backup copy, of course ;-) ).

It is also possible to create arrangements with controls that span the 2 columns. This let’s you add controls with long labels (for example QComboBox) or QGroupBox elements. It can also be used to partition the form layout into sections by using spanning QLabel elements:

A form layout arrangement with spanning labels

In code, you would use the addRow() overload that takes just one QWidget* parameter.

In the upcoming 4.5 release, this functionality will also be available in Designer. Lonesone widgets on a QFormLayout get an active left/right resize handle that let’s you change the span:

Changing the span of a QFormLayout element in Designer

The per-cell API of the QFormLayout uses the SpanningRole enumeration value of ItemRole to handle these rows.

Summarizing, the QFormLayout should be used whereever the typical descriptive label - control arrangement occurs. The dialog will then look correctly on a all platforms.

ariya
Qt
Graphics Dojo
Posted by ariya
 in Qt, Graphics Dojo
 on Saturday, July 05, 2008 @ 19:48

Time for another fresh example for the Graphics Dojo. This time I present a small tool that does nothing but showing the famous HSV cylinder. To give some realism, subtle blurred reflection is also added but can be easily disabled. Manual full-scene anti-aliasing is provided by the usual multisampling approach. Everything is done using pure QImage per-pixel manipulation along with some tricks, no OpenGL (or even its GLSL) is involved.

HSV Pie

For the code, check it out using:

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/hsvpie

Note that the tool is not optimized for speed (evidenced by lots of setPixel() calls) so there is definitely room for improvement. Some possible further enhancements left as exercises for the readers are interactivity (mouse dragging to change e.g. the depth of the pie) and threaded rendering (so that the application remains responsive, just adapt the Mandelbrot example).

Have some dojo-fun!

Henrik Hartz
Qt
WebKit
Itemviews
Posted by Henrik Hartz
 in Qt, WebKit, Itemviews
 on Thursday, July 03, 2008 @ 11:03

Hi there. This is my first blog post, so I guess introductions are in order; My name is Henrik Hartz, and work as a Specialist with Product Management in Troll^W Qt Software. In Product Management I do all kinds of stuff, ranging from working with requirements, specifications, product releases, meeting customers, thinking about the future of Qt, the list goes on.. Recently I’ve had the pleasure of focusing on WebKit.

WebKit is a fantastic technology. Being able to stick web content into your application is simply amazing, there’s just about anything out there you can show! And, a lot of people know HTML, so making use of this to add content to your application enables you to (ab)use your Graphic Designer buddies.

But, WebKit is so much more than just a way to show HTML in your app. You can actually do anything a browser can - and much more! Experimenting with WebKit over the last couple of months I’ve made an example that a lot of people seem to be interested in; Using WebKit to host a Google Maps component.

I wanted to show where our offices are located in the world. So, I started with a simple QStandardItemModel that would read in addresses from a txt file. In the constructor, we read in the text file - using the first field of the comma separated line as the display role, and the rest as the address stored in the UserRole;

QStringList addressLines = address.split(",");

QStandardItem *item = new QStandardItem;
this->insertRow(this->rowCount(),item);

item->setData(addressLines.takeFirst(), Qt::DisplayRole);
item->setData(addressLines.join(",").trimmed(),Qt::UserRole);

With this model in place, we simply set it on the list view of our GUI design (yeah, I like using Qt Designer - it’s fast!);

ui.treeView->setModel(new AddressModel(this));

In the GUI we’ve also placed a web view, which is pointed to a web page under our control. This page shows a Google Maps control. So here is the GUI with the address list and QtWebKit component;

GUI design

This doesn’t do much on it’s own - so we promote the QWebView class to a custom component “Map”, defined by map.h in Qt Designer. This component has some additional services that allow us to update the map, specifically;

void geoCode(const QString &address);

What we want is to update the map based on the entries in the list view when they are clicked. We do this in a slot method connected to the clicked signal of my view. Here we can access the data of the item being clicked, extract the address and ask the map component to geo-code it;

void MainWindow::showItem(const QModelIndex &idx)
{
ui.map->geoCode( idx.data( Qt::UserRole).toString() );
}

The geoCode method will use QtWebKit’s capability of calling JavaScript functions in the web environment. Here we’ll use the Google Maps API to get Google to return a coordinate of the specified address in CSV format, using the asynchronous QNetworkAccessManager::get(const QNetworkRequest &amp;request) API;

void Map::geoCode(const QString &address)
{
QString requestStr( tr("http://maps.google.com/maps/geo?q=%1&amp;output=%2&amp;key=%3")
.arg(address)
.arg("csv")
.arg("GOOGLE_MAPS_KEY") );

manager->get( QNetworkRequest(requestStr) );
}

In another method connected to the QNetworkManager::finished(QNetworkReply*) signal, we parse out the coordinate returned in CSV format from Google, and pass it to a method which updates the map component appropriately;

void Map::loadCoordinates()
{
QStringList scriptStr;
scriptStr
< < "var map = new GMap2(document.getElementById(\"map\"));"
< < "var bounds = new GLatLngBounds;"
< < "var markers = [];"
< < "map.setCenter( new GLatLng(0,0),1 );";

int num=-1;
foreach( QPointF point, coordinates ) {
scriptStr < < QString("markers[%1] = new GMarker(new GLatLng(%2, %3));")
.arg(++num)
.arg(point.x())
.arg(point.y());
}

scriptStr
< < "for( var i=0; i<markers.length; ++i ) {"
< < " bounds.extend(markers[i].getPoint());"
< < " map.addOverlay(markers[i]);"
< < "}"
< < "map.setCenter(bounds.getCenter());";

this->page()->mainFrame()->evaluateJavaScript( scriptStr.join("\n") );
}

In the final call, we tell QtWebKit to evaluate the JavaScript we have synthesized, and the web view updates with the appropriate location;

Qt Software Address book

The snippets shown here are simplified to some extent, but you can find the complete source code here. Please remember to put the HTML for the map component on a server you control - and replace the GOOGLE_MAPS_KEY with your own key (you need to register and bind to a domain for it to work) in both map.cpp and index.html.

Enjoy!

Benjamin Meyer
Qt
Posted by Benjamin Meyer
 in Qt
 on Wednesday, July 02, 2008 @ 14:56

After 4.4.0 was out I set aside some time to go though the feature requests for QTabBar & QTabWidget. After making a list of the most voted for suggestions I have implemented some features that will be in 4.5.0 that should make some developers happy.

In the past ten years the tab widget has gone from being something you see in a settings dialog to the widget that is the central widget of QMainWindow for many applications. Trying to use QTabWidget in the main window as it is in 4.4.0 has a number of shortcomings. One big issue is that if you maximize your application and move your mouse to the far right and try to scroll it wont because the mouse is actually over the 2px frame and not the scrollbar. I present for your enjoyment QTabWidget::documentMode which will only put the frame on the top with the tabs. Another very annoying problem for QTabWidget was that if you wanted to add a context menu or handle any event in the tab bar area you had to subclass both QTabBar and QTabWidget because the empty area was actually owned by QTabWidget and the tab bar widget was only as big as the tabs. Document mode will cause the tab bar widget to take up the entire space above the tab widget which will simplify a lot of code.

Looking around at what features people have implemented in their subclasses of QTabBar many have added some sort of hack to be able to either put a widget on a tab or the ability to paint a button. Doing this right, QTabBar now has a function QTabBar::setTabButton to let you put a widget on the left or right hand side of each tab. Taking this one step further there is also a convenience property
QTabBar::tabsClosable that when enabled will automatically add a close button to each tab. The close button it painted by the style using PE_IndicatorTabClose. When the close button is pressed the signal tabCloseRequested is emitted. Note that the location of the close button is also determined by the style so you can not guarantee that it will always be on the right hand side and the side with the close button should be determined by a call to the style with SH_TabBar_CloseButtonPosition. Custom styles that paint tabs themselves needs to be updated to take into account the space needed for buttons (see QStyleOptionTabV3).

When a tab is closed rather then always selecting the tab to the right there is now a
QTabBar::selectionBehaviorOnRemove property to decide which tab should be selected. The three included values are left, right and the last selected tab.

Another highly requested feature is support for the ability to move tabs. There is even a number of patches floating around out there that add many different moving schemes. A moveTab function was added, but taking it to the next level the property movable has been added which lets you drag the tabs around and as you pass over tabs they slide to their new position (i.e. animated sexiness).

Because animations are hard to describe I made a short video. In the video I first add a QTabWidget to a QMainWindow, turn on document mode, closeable tabs, and the moveable property. Then I preview it in plastique and drag around a few tabs. I start out using cleanlooks so it picks up the Gtk close button and then in plastique you can see it using the default button.

Lastly for applications running in OS X when using document mode the style paints the entire tab bar to match those tabbed applications like Safari and Terminal that are found on OS X. Below is a screenshots of a QTabWidget in a QMainWindow with a QWebView. With OS X it is very clear that the tab widget now goes to the edge of the screen.

osxstyletabbar.png

Hope you all enjoy it. Some of the patches are already in Qt main, but you can find all of these in tonight’s snapshots. Let me know if you notice any issues with the new features.

ariya
Qt
Graphics Dojo
Posted by ariya
 in Qt, Graphics Dojo
 on Sunday, June 29, 2008 @ 01:35

If you play games like Rainbox Six: Vegas or watch movies like Elephant Dream, you will notice the use of the so-called Bloom effect. In fact, Vegas is so bright and surrealist that this game becomes known for its Bloom overuse.

In this Graphics Dojo example, I would like to show how to render an image with the Bloom effect. This extends the previous example from Zack on making real-time glow effect. The technique: create a copy of the image, blur it, increase its brightness and then combine with the original image with a certain composition mode and opacity. Since a picture is worth a 2^10 words, I will let the following screenshot (click to enlarge) speaks for itself.

Bloom effect with Qt

The image on the left side is the original, whereas the right one shows the result of applying Bloom. As you can see, there are few sliders where you can tweak the parameter to achieve the effect that suits your taste. Different composition modes can give (not so radically) different results as well, just play around with it.

How to get it? Just do “svn checkout svn://labs.trolltech.com/svn/graphics/dojo/bloom” followed by the usual “cd bloom && qmake && make && ./bloom”. Once the main window shows up, you can also change the image by using drag-and-drop from a file on your disk or even a link from the web browser (e.g. straight from your Flickr gallery). Have fun!

sroedal
Qt
Graphics View
Graphics Items
Graphics Dojo
Posted by sroedal
 in Qt, Graphics View, Graphics Items, Graphics Dojo
 on Friday, June 27, 2008 @ 13:47

To breathe some new life into the graphics dojo, here’s an example of how to put widgets on top of an OpenGL scene using QGraphicsView. By leveraging the synergy (tounge in cheek) of the OpenGL module and graphics view’s in 4.4 new widget capabilities, the long lacking feature of putting widgets in OpenGL becomes possible. All that’s needed is to set a QGLWidget as viewport on the graphics view, override QGraphicsScene::drawBackground() to do the OpenGL rendering, and add widgets and other graphics items to the graphics scene as usual. The result can be seen in the screenshot below, which shows a simple obj-model viewer application written in just a couple of hundred lines of code:

Widgets on top of an OpenGL scene

The source code is available by “svn checkout svn://labs.trolltech.com/svn/graphics/dojo/modelviewer”. Have fun!

lorn
Qt
Qtopia
KDE
Posted by lorn
 in Qt, Qtopia, KDE
 on Monday, June 23, 2008 @ 04:13

After many moons, I have started to work again on my personal project, Gutenbrowser. It is in need of much maintenance and love.

Since Qt finally has a good webview, QWebView, I can finally start working towards version 1.0! With very little work, gutenbrowser can now show Gutenberg Project etexts that come with images.

Since I have a macmini at home, I can distribute Mac binaries, as well as Windows and a few Linux embedded devices (Openmoko Neo and possibly Nokia’s n8×0’s Qtopia )
and with the help of Petter Reinholdtsen, fix a few bugs and be in the standard Debian distribution.

For those that do not know of the Gutenberg Project, there are over 25,000 free books available!

lorn
Qt
Qtopia
KDE
Posted by lorn
 in Qt, Qtopia, KDE
 on Monday, June 16, 2008 @ 19:55

New Nokia Sign

Well,
I start work for a different company today, namely Nokia. Perhaps you have heard of them? No? Well, they used to make rubber boots but now make phones. Lot’s of them. They have a few employees. Lot’s of them. and now, a few more, thanks to the (more or less) peaceful assimilation of Trolltech.

Am I worried? A bit. The management structure at Nokia is overbearing, not like Trolltech’s lean and mean machine. I doubt I will see the CEO of Nokia getting drunk and wrestling with engineers any time soon. I doubt I will ever be called to a meeting with him to pick my brain about community matters, much less even get an email from him. I liked that about Trolltech. The openness, the friendliness.
Hopefully my boss will stop wearing his shoes so much. He used to go barefoot a lot more than he does now. I liked that about him.

Today, I start work for Nokia, sitting in the same desk (I hope), loging into the same machines (I hope), and continuing my work from yesterday (except today is the BBQ beer fest.. wweeeeeeeeeee!), on the Qtopia SDK, on the n8×0 and Neo devices. I still get to work with the greatest multi licensed cross platform toolkit ever - Qt. I get to use the greatest and Kool Desktop Environment - blackboxqt! heh and also - KDE.

Best of all - I get a new phone and some Nokia schwag.

I, for one, welcome our new Nokia overlords!

lorn
Qt
Qtopia
KDE
Posted by lorn
 in Qt, Qtopia, KDE
 on Monday, June 16, 2008 @ 09:01

Well,
This is my last post as a Trolltech employee. I have worked for Trolltech Pty Ltd, in Australia. since 2003. I can proudly say I helped Qtopia become more open, and fully GPL. It’s been a short 5 or so years, I have seen the Brisbane office grow from around 14 people to around 50, found my wife, had a son and daughter. A lot has happened in the past years. Ran ‘make’ more times that I want to think about. Got Qtopia running on all the devices I could. Yelled and complained and praised till I was blue in the face.

Tomorrow (Tuesday), I will be employed by Nokia, doing the same things I did today (well, maybe the day after next, tomorrow is the obigitory write-off “1st day”, BBQ and beer drinking).

It will be a challenging year ahead, I am sure both Nokia and Trolltech ^H^H^H^H^H^H^H^H Qt Software have things to learn from one another. I am personally wishing Trolltech’s seeds of open source will blossom Nokia into a greater thing.

So tonight, while I am unemployed, am going to live it up! and… uh… well… write some code (having small kids really saps your energy) and get more familiar with scratchbox2. (which thankfully uses a real cross toolchain).

I feel it is a bit like Christmas… So, if you talk to a Troll today, shake his/her hand and tell him/her thanks for making the world a more peaceful place.