APR
16
2004

Qt Quarterly: A Taste of Qt 4

Qt Quarterly is a paper-based newsletter exclusively available to Trolltech's Qt customers. As a courtesy and convenience, a selection of articles are delayed also made available online in HTML format. One of the more interesting articles for KDE developers in this year's first quarter issue is an article by Jasmin Blanchette which gives "A Taste of Qt 4". A Qt 4 technology preview is expected for this summer requesting for feedback and a Qt 4 Beta is planned for the second half of 2004.

Comments

I found this discussion about ruby vs. python iteration styles:

http://www.rubygarden.org/ruby?IterationStyles

He ends with:

"So which way is better? I find it fascinating that both Ruby and Python have almost equivalent power in its iteration, they have just taken different paths to get there."


By Richard Dale at Mon, 2004/04/19 - 5:00am

I find OO to be clearer in cases like this. You ask the list to give you each element in turn. Since each element is an object, you can pass messages to them.

It's not that I find the Python *terrible*, but I think the Ruby just makes a lot more sense. I also get sick of statements like "is the thing that pops right into your head when thinking about the problem.. right?"


By KDE User at Mon, 2004/04/19 - 5:00am

How about?

sum(map(len, list))


By Kosh at Sun, 2004/04/18 - 5:00am

Bing! we have a winner. The simple clarity combined with brevity of this solution is beautiful. I was looking at the list comprehension solutions, and fiddling around with my own... then saw this. And saw the light.

The only part that looks slightly cryptic to a non-Python person may be the map(). But that's okay.

I also find it interesting that while python has the slight reptuation of being more rigidly structured that certain other languages, so many very different Python solutions were given here.


By Tim Middleton at Mon, 2004/04/19 - 5:00am

map is slowly being deprecated though from the language.. because list comprehensions are easier to understand, and are more powerful. I like this construction though :))


By mark dufour at Mon, 2004/04/19 - 5:00am

You can also replace the list comprehension with a map

reduce(lambda x,y:x+y, map (len, li))


By anon at Sat, 2004/04/17 - 5:00am

Haskell:

sum [length s | s <- li]


By mill at Sat, 2004/04/17 - 5:00am

> foreach (QString s, list)
> sum += s.length();

> QList::const_iterator i;
> for (i = list.begin(); i != list.end(); ++i)
> sum += (*i).size();

You fell face-on into the marketing trap :)

For one, you could use it->length() instead of the (*it).length();
For two, if you allow Qt to use non-std-c++ tools, let me show you how the same code looks using lambda functions (from the Boost library, the playground for libraries that are proposed for inclusion in the next C++ std version):

for_each( list.begin(), list.end(),
sum += _1.length() ); // you probably need var() around "sum"

The best thing here is that this is void of redundancy (cf. "QString s" in the Qt foreach). You might wonder why I have to give the seemingly redundant list.begin(), list.end() here, after all "list" should just do, right?

You are free to write a small wrapper around std::for_each() that does exactly that. But the begin/end concept allows the algorithm to work on any range, e.g. this one:

double foo[] = { 1.2, 3.4, 5.6, 7.8, 9.0 };
for_each( foo, foo + 5, sum += _1 );

Not to speak about

sum = accumulate( foo, foo + 5, 0.0 );

which is also an STL algorithm :o

So if you say that C++ is an ugly language b/c of the STL, then let me respond by telling you what the STL is all about. It's about removing redundancy. As with desgin patterns, once you start thinking in algorithms instead of implementation, you are able to tackle more complex problems. In this case, note how we can change the value_type of the containers without changing a single line of the algorithm code. Can't be done with Qt4's foreach(), which is even worse than the full-length STL example they gave, since you can always use "typedef QList Container" to hide the value_type, whereas Qt's foreach _requires_ you to explicitly state the value_type for _every_ for loop. Note also how in the accumulate() example, we said _what_ we do instead of _how_ we do it :)

It's of course easy to make a special case look better. This reminds me of the wannabe physicists that regularly write papers that seemingly convincingly disproof the Einstein theory of relativity. But if you look closer, they pick a single prediction out of the vast array of predictions of the full theory and found another explanation for that since prediction. That their "theory" (in contrast to Einstein's) fail to explain all the other effects that man observes in the universe isn't relevant to them.

Same here. The STL tries to relieve you from writing for loops. for_each() is just one of many STL algorithms. It doesn't matter that you have found a nicer syntax for a for loop if the real goal is to avoid writing them out explicitly in the first place :)


By Marc Mutz at Sat, 2004/04/17 - 5:00am

> For one, you could use it->length() instead of the (*it).length();

You can't. They overloaded the * operator to return the object the iterator points to. However, the -> operator isn't overloaded. I don't really know why, but anyway, it won't work ;)


By Arend jr. at Sat, 2004/04/17 - 5:00am

Oh, yes. I used QValueVector, where it works due to the iterator being value_type*. Which is another problem with Qt containers. They use lists all over the place, where a vector would suffice, and probably yield better performance (less malloc()s, for one). Just look at the implementation of operator[] for QValueList - ugh. (hint: QValueListPrivate::at())


By Marc Mutz at Sat, 2004/04/17 - 5:00am

So if you say that C++ is an ugly language b/c of the STL, then let me respond by telling you what the STL is all about. It's about removing redundancy. As with desgin patterns, once you start thinking in algorithms instead of implementation, you are able to tackle more complex problems. In this case, note how we can change the value_type of the containers without changing a single line of the algorithm code. Can't be done with Qt4's foreach(), which is even worse than the full-length STL example they gave, since you can always use "typedef QList Container" to hide the value_type, whereas Qt's foreach _requires_ you to explicitly state the value_type for _every_ for loop. Note also how in the accumulate() example, we said _what_ we do instead of _how_ we do it :)
--

That's nice. The STL and C++ are still ugly. The claim wasn't that C++ is a useless language. It's that C++, and the STL are ugly. You'll never convince me otherwise, simply because in my opinion, they're not fun to look at.


By KDE User at Sat, 2004/04/17 - 5:00am

Have you ever thought that

int sum = 0;
foreach (QString string, names)
sum += string.length();

is simply more readable than

int sum = 0;
for_each(names.begin(), names.end())
var(sum) += _1.length();

?

Readability is king, because reading code is much more time consuming than writing code! (even though trying to find way to l33t-STL-encrypt a simple loop can indeed cost more time ;)

I guess that's also why foreach (just like C#'s foreach, btw) requires the type of the loop variable. Plus it's perfectly consistent with for and while.

And talking about redundancy: The 'var' is redundant. Unlike the type in the foreach it adds no value when reading the code.

Try teaching a freshman from university the magic of _1, ref(), var() and constant() versus the simple foreach in the example. It becomes much more fun, btw, if next to the _1 a 1 as constant appears - goodbye readability.

STL is not necessarily a good argument when trying to convince for example a C# or Java programmer to use C++ for his next project.


By Anonymous at Sat, 2004/04/17 - 5:00am

Hey, the OP stated that you can of course write wrappers.
So you can do something like this:

-------------------------------------------

struct add_to
{
add_to(int& sum);

void operator()(int add);

int& sum;
};

add_to::add_to(int& sum) : sum(sum)
{
}

void add_to::operator()(int add)
{
sum += add;
}

template
void my_for_each(Tcontainer const& container, Top op)
{
for(typename Tcontainer::const_iterator iter = container.begin(); iter != container.end(); ++iter)
{
op(*iter);
}
}

...

std::vector v;

int sum = 0;
my_for_each(v, add_to(sum) );

-------------------------------------------

This is pretty readable, or?


By El Pseudonymo at Sat, 2004/04/17 - 5:00am

Not compared to just writing + in a functional language. The whole thing is really a hack around the lack of lambda forms, IMHO.


By Sad Eagle at Sat, 2004/04/17 - 5:00am

When I first read it I thought: Ok, this adds 'sum' to each element of the vector v.... Wait, that wouldn't make sense. Ok, so I need to look up what exactly 'add_to' does. *browses possibly external header file for definition, while breaking the flow of reading code*


By Anonymous at Sun, 2004/04/18 - 5:00am

The STL is not a great thing to use here. Heck, you ran into number of its problems just in your example:

1) Boost.Lambda is tricky, because you have to remember corner cases where things like var() are necessary;

1.1) You don't mention what the compiler error looks like when you make a mistake in Boost.Lambda (its *unreadable*);

2) You have to write wrappers that should absolutely be in the base language;

3) You have to litter your code with useless typedefs;

4) As a result of (1), and the lack of a proper lambda in C++, many of the STL algorithms are much less useful in non-trivial cases.


By Rayiner Hashem at Sat, 2004/04/17 - 5:00am

you can do foreach in standard c++ if you are really clever

check out the bottom of http://dot.kde.org/1082132072/1082135961


By michael toksvig at Fri, 2004/04/23 - 5:00am

Dylan:

reduce1(method(s, i) s + size(i) end, list);

Mine might be a bit shorter, because your's needs to initialize sum first.


By Rayiner Hashem at Sun, 2004/04/18 - 5:00am

Can I do something like:
copy(l.begin(),l.end(),QTListBoxBackInserter(listBox));
?


By dotTroll (c) at Fri, 2004/04/16 - 5:00am

How said that you can't do it now?

Compile the attached example with:
g++ main.cpp -o insert_test -lqt-mt -I[include-path-qt] -L[lib-path-qt]

(Qt must have been compiled with STL support)

run it...works for me pretty well.

Christian


By Christian Loose at Sat, 2004/04/17 - 5:00am

Trolltech is so great. Qt4 looks just awesome. I'm particularly happy about the vector drawing engine (Arthur), and the new Interview system. It looks like Qt will remain one of the most powerful toolkits out there. If Qt4 is as good as its shaping up to be, it'll also quiet down any nay-sayers who think Longhorn will leave *NIX GUIs behind the technology curve.


By Rayiner Hashem at Fri, 2004/04/16 - 5:00am

The nay-sayers won't shut up. It's their hobby to ridicule the NIX desktop. I suspect that in ten years, when KDE has 62% of the desktop and Windows with a paltry 3%, they'll still be saying "but wait until the next release!"


By David Johnson at Sat, 2004/04/17 - 5:00am

"It's their hobby to ridicule the NIX desktop. I suspect that in ten years, when KDE has 62% of the desktop and Windows with a paltry 3%, they'll still be saying "but wait until the next release!""

Well let us not get ahead of ourselves :). However, I'm using .NET now commercially, and although it is certainly an improvement on Win32 programming (C# is a very nice language) there is a heck of a lot in the NIX/Qt world that completely nullifies any hype. Rest assured that there is nothing in .NET/WinFX that you can't do just as easily using Qt and NIX based technology - quite the opposite infact :).


By David at Sat, 2004/04/17 - 5:00am

hooray, at last !


By ik at Sat, 2004/04/17 - 5:00am

Qt 4 sounds amazing, I just hope that they will be able to deliver, that's a hume amount of stuff their promising and none of it is trivial. I'm very happy with the direction Trolltech is taking with Qt 4 and I wish them the best of luck!

I'm also looking forward to Mark Summerfield and Jasmin Blachette's book on Qt 4.0. I've already got their book on 3.2.x and I found it to be pretty good, though still a bit too advanced for me (I don't know C++ well).


By Alex at Sat, 2004/04/17 - 5:00am

drooool..
transparency. foreach. double-buffering. vector and pixel-based drawing. /real/ WYSIWIG. uber multi-threading. accsessbility. gui/non-gui split. designer in kdevelop. smaller. faster.

Is there anything they havn't done??


By je4d at Sat, 2004/04/17 - 5:00am

I'm missing the function
Qshow_app_i_have_in_mind();


By Anonymous at Sat, 2004/04/17 - 5:00am

DWIM! DWIM!


By Rayiner Hashem at Sat, 2004/04/17 - 5:00am

"In Qt 3, Qt Designer and Qt Assistant are used independently of the programming environment. Starting with Qt 4, it will be possible to use these tools from within the programming environment. Initial plans are for integration with the Visual Studio .NET, KDevelop, and Xcode IDEs."

Yes, very important. I think at the moment people are a bit mystified with using two or three development environments. With VB/VC++ etc. Microsoft learned the wisdom of binding things together.

"A new paint engine...A new text-rendering engine"

This sounds like a premier platform to do Office suite development on....

"The new model/view framework, codenamed Interview, provides tree views, list/icon views, and tables using a common data model abstraction to support data-driven GUIs that are fast and responsive even with large data sets."

Spot on! People moving from a Windows environment and really developing commercially will certainly appreciate this.

"Qt 4 introduces a new set of template classes, codenamed Tulip, that are lighter, safer, and easier to use than the STL's containers. Developers who are unfamilar with the STL, or who prefer the "Qt way" of doing things, can use these new classes instead of the STL classes."

This sounds great, although I will say that if you are going to do this with C++ why not use a language like C#/Java etc. in the first place? They are languages that syntactically look much better when doing stuff like this.

"Qt 4 with STL-style iterators:

QList::const_iterator i;
for (i = list.begin(); i != list.end(); ++i)
sum += (*i).size();"

Commercial development with syntax like this? Yuck! It is also terribly unreadable.

"We are putting an enormous amount of effort into Qt 4, and we are very excited about the new capabilities and technologies that we are building into it."

So you should be. I'm using .NET now in a big way, and beyond the hype of stuff like XAML and the future WinFX stuff I'm not all that impressed to be honest.


By David at Sat, 2004/04/17 - 5:00am

is "Qt on DirectFB" project dead? as on http://qt-directfb.sourceforge.net/ -- last updates was in middle of 2003...


By gray at Mon, 2004/04/19 - 5:00am

Why don't the Trolls add optional garbage collection to QT? That would really help it when competing with Java.


By Spy Hunter at Mon, 2004/04/19 - 5:00am

When will KDE 4.0 (which is my guess is the first KDE release to be based on Qt4) be released?

My wild guess would be sometime in the fall 2005, say October 2005 :)

And yes, this is of course for fun only, but I think it'll be fun to look back to when KDE 4.0 sometime in the future is released :)


By Joergen Ramskov at Mon, 2004/04/19 - 5:00am

mid summer 05.. if kde 3.3 comes out late summer 04


By anon at Mon, 2004/04/19 - 5:00am

Pages