Archive

Posts Tagged ‘Qt’

Rant about Qt

August 11, 2015 3 comments

Whenever I touch Qt designer to design a new window I feel like I have to rant about it. So here is my rant: layouts in Qt are bad bad bad bad bad!

I think I’ll need to find other ways to vent my frustration.

UPDATE: I didn’t want to make just another blog post about this stupidity, that’s why I’m expanding this post instead. I’ll spend this day trying to make a window with things placed at specific locations. And it’ll take the whole day. Again. When it comes to Qt’s window layouts and widgets the usual (and only working) solution is to “write it yourself.” If it weren’t the only real option for making cross platform apps, I’d be too frustrated to use it any longer.

UPDATE2: It turns out what I could easily achieve in c++builder (or directly in winapi – done both) is impossible in Qt. I spent the whole day looking for a solution and it can’t be done. Now I’ll have to figure out a way how not to make the kanji handwriting recognizer window butt ugly.

Categories: Rant Tags: ,

Qt user interface design difficulties (rant)

June 25, 2015 1 comment

I plan making a multiple window interface instead of the visual mess zkanji currently is. Having said that, I don’t have any well designed windows at the moment. In the past 2 days I was struggling with making an acceptable user interface for the kanji search window, but with no success.

Qt is great in many things. For example it has a library that provides many things that should be in STL. (A good string handling for example.) Surprisingly, interface design is not among its strong points. It’s possible to do everything you want with it, but it requires a lot of work, and the visual designer included with the library is simply bad. It allows placing “widgets” on windows, organize them in groups (by putting them on the same parent widget) and there are those evil things called layouts. Even if all you want is placing standard looking edit boxes, check boxes and buttons on windows, as soon as you want those to be placed at specific locations you are out of luck. The layouts will make sure they get stretched or moved to the wrong side of the window. (There are solutions but they are all awkward and break as soon as you change some setting in the system. For example font size.)

But what if you want something else? Your program will definitely require a specific widget behavior, the widget should be placed on a toolbar, its size should match some criteria not directly related to the contents of the widget. There are many such things that are probably only needed in one of every ten programs, but at least one of them will definitely be needed. In those cases the only solution is to write code in the constructor. Code, that (in my opinion) should be handled by the designer just as well. Is that such a bad thing? you might ask. Unfortunately yes. Once a widget is out of place, layouts become unusable. Programmatically inserting something in the middle of an interface is one thing, but more often than not it also means you can’t place the rest of the interface either. Not to mention it’s very difficult to design something if you can’t see the final result in your design.

So I finally gave up. Previously I thought most open source programs look and behave bad simply because the creators were lazy and had absolutely no sense of taste for design, and can’t imagine themselves in the place of their users. (Because they are good coders and not good designers or something.) Now I think it’s that, AND every free UI library or toolkit are bad as well. Rant over.

I’m now aiming at making a feature complete program that will look bad (hopefully only at first), but work as good as zkanji does currently. There will be casualties (I threw out the 4-corner kanji lookup, and you can’t add a word with different meanings several times to groups) but in general I hope it will work just as well or even better than zkanji previously did.

Categories: Rant Tags: , ,

Just a short thought on Qt

June 19, 2015 Comments off

Qt has (sometimes huge) design mistakes in my opinion but it’s far from bad. But try to look up unrelated information about it, and you’ll find the fanboys defending every silly thing about it.

For example, when you design a window in the Qt Designer, it creates an XML file with the .ui extension. That file is then translated to source files. The generated header has code like this:

class Ui_MainForm
{
    // ... Declarations of widgets and some helper functions.
}

below it another class is generated in this exact way:

namespace Ui {
    class MainForm: public Ui_MainForm {};
} // namespace Ui

The class in the Ui namespace can then be used as a private member in another header file, which is provided for the programmer to change: (because the code above is auto generated)

class MainForm : public QMainWindow
 {
    // ... some things you add here
private:
    Ui::MainForm ui;
}

Not one, but more people asked why is there a Ui::MainForm generated, when there is also a Ui_MainForm, which is the exact same thing. They were just curious and asked politely but the fanboys attacked. “It seems to me you do not get what namespaces are” (exact quote).

(This is the end of the post. If you don’t understand why I’m troubled by such reactions you are either not a programmer (it’s normal then, not your fault), or you are smarter than I am and the way Qt does this appears right to you.)

Categories: Rant Tags: , ,

Qt or STL containers in zkanji

June 5, 2015 Comments off

This post is not exactly about what I planned the last time, but I’m sure nobody will be angry about it.

Instead of relying on STL to handle the storage of data, Qt has its own container classes. STL wasn’t standardized at the time Qt started out so this is somewhat understandable, though it still happened in ancient times. When I started writing the Qt version of zkanji, I had to decide which set of container classes to use. I originally developed zkanji in an entirely different framework that didn’t use STL itself, so now when I’m rewriting everything, it really means rewriting everything. This put me in the position where I had to choose one set of the container classes.

Because the Qt documentation is full of QList this and QList that, and they also say that QList is the recommended container ‘cos it’s so great, at first I put QLists everywhere. (It is not like std::list, but rather a vector holding pointers.) I can’t say whether it was a mistake or not, but it turned out that the QList implementation is very slow in the VS debugger. The debugger is notorious of being slow anyway, but when it sees a lot of asserts, memory allocations and access, it’s even slower. (Also if you use iterators a lot it can be very slow.) Once I replaced QList at some key locations with QVector, my program sped up in the debugger. I don’t know the reason behind it, but I was lazy to check out their source code.

This was the point when I started looking for comparisons of the Qt and the STL container classes, and only found a few, like this and this. Apart from these I only saw half sentences about the inefficiency of Qt and, from others, how great it is.

Qt containers are really convenient. They hold an internal pointer which is the real container, and only that pointer gets copied if you copy the containers. The real copy only happens if you modify their contents. This can also be seen as a drawback because you never know when the “hard copy” happens. A single mistake when accessing the container elements can cause this to happen too, so be careful.

What gave me the final push was when I made some of my classes movable but non-copyable (as it’s bad when there are multiple copies of them all over the place even if only by mistake), and removed the default constructor of others. The compiler immediately scolded me that it’s not good, how could it instantiate a QList with them this way? As it turns out, Qt is not very friendly with C++11 features, even if they claim otherwise. This unfortunate detail made me switch to STL, and if some containers are STL, it’s not a good practice to mix them with QT containers in a single code. For example I would have to use the at() function of Qt lists but avoid that in STL for speed (they do different things…), and that would cause a lot of confusion later.

Phew, this was a long introduction!

QList, as I mentioned above, is like an std::vector holding pointers, with the difference that it leaves some space in front of the allocated data, so insertion and removal from the first half of the container is faster than with std::vector. Because it internally holds pointers, it also manages them. You pass in a value and it allocates a new object for it. No more need for smart pointers when the list does the allocation and deletion. When I switched to a pure STL implementation this convenience was lost. But worry not! (You didn’t worry? Sorry.) I just had to create a new container class derived from std::vector that works like a list of smart pointers. Erasing an element also deletes the object via its pointer that was stored there. In general, deriving from STL containers is a mistake because they don’t have virtual destructors. I don’t plan passing them as pointers to the base vector’s type when handling my “smartvector” (as I named it) so no problems there. It’s all for convenience because this way VS shows the list of elements in the debugger, and I don’t have to add a natvis extension to it.

String storage? I had wchar_t all over zkanji originally while it was Windows only. This data type holds a 2 bytes wide character when compiled on Windows, and a 4 bytes wide one on linux implementations. Obviously I had to get rid of it in the new code. I was eyeing QString at first, and it’s probably a good choice usually, but I just don’t like the idea of storing unnecessary data, like reference counting, inner pointer for fast copy etc., when the average size of the strings is 3-5 characters (for kana / kanji) and maybe 20 for English definitions. std::string was out of question in the first place, because I could at most use UTF-8 with them, and string comparison and the like would be a pain.

At first I replaced every wchar_t* with QChar*. QChar is the character type used in arrays inside QString, and an array of QChar can be easily converted to QString where the Qt GUI code needs it. I tested it myself and found that using arrays of QChar or using unsigned short (which it holds internally) has exactly the same speed. QChar also has its convenience with its built in functions so it was an obvious choice. I also found out by testing that comparing strings with the QString comparison functions is 1.3 times slower than writing my own function that compares characters one by one in a QChar array. (Yes I tried this in release code as well.)

As a real solution, I finally got off my lazy bum and wrote a container class for QChar arrays that frees up the data when it gets deleted. I also made the natvis extension for it so the debugger correctly shows my strings, and not just the first character in the array. This string is designed like an array: it shouldn’t be modified too often, so it’s purely for holding the data, but because of that it can be very fast and memory efficient as well.

With this I have everything that satisfies my (current) container needs. I can’t give a real conclusion or judge which is better, Qt or STL containers. I found Qt containers to be much more convenient than STL containers, and not as much slower that would make them useless (when you are not handling huge amounts of data), but they are not as c++11 friendly as I wish they were, so I waved them good bye.

Next time I’ll write about… something. I can’t see the future it seems.

Categories: Development, Rant Tags: , ,

Qt my subjective first impressions

June 2, 2015 Comments off

I’m going to be very honest straight away. I had a lot of prejudice against Qt before I tried it. Most programs that boast to be cross-platform are bad, including those that use Qt. This is only not true about some projects because they are huge, many coders contribute and the interface is often written separately for each platform.

Qt didn’t turn out to be as bad as I expected it to be though, but I’m still going to take it to pieces here. I’ve only been using it for about two weeks, so I’m sure I’ll figure out easier ways to do things compared to what I do now. I want to write more posts about Qt, so let’s start with “first impressions”. What a newbie (to Qt) will find when he or she first uses it depends on the person. I can only write about my impressions.

I have been coding for some time already and I have seen huge libraries, including many parts of winapi. Qt at the first glance seems huge too. This can be a bad or a good thing. I think that it provides many tools that I need for zkanji, and I’m yet to find things it doesn’t have. It’s very convenient that way and unlike .Net with C# (which I think is a good comparison in this regard)  Qt is C++ and it works fast too. (There’s the so called Quick controls part of Qt which is slow. I’m not using it.) On the negative side, the Qt dlls that you might have to include with your program can take up tens of megabytes. (Just for comparison, .Net installs hundreds.) This might not sound that bad nowadays, but a lot of people still have slow internet connection or artificial bandwidth limits. I’ll have to see what the file size ends up to be once I statically link Qt to my program.

Even if you are used to big libraries, you’ll still have to read a lot of Qt introduction and documentation of very basic features. I guess this is normal, but there are many small things you will have to figure out for yourself. There are many tutorial videos out there. I haven’t seen them because I don’t appreciate videos like that. Coding takes a lot of typing, so I need my information in written form. (I can’t get it how newer generations only understand anything if they saw a video about it.)

As a new user it was mainly the documentation I tried. I might not be your typical new user, because my first idea was to write a new control… I mean, widget. In zkanji (pre-Qt), the area that shows the word results for dictionary searches is an entirely custom made control. I wrote its display code and its input handling from scratch because there was nothing I could use that can display and scroll ten thousand lines in an instant. I was looking in the documentation for “how to write a custom widget”, but it only writes about how to make “properties” for it (that you can manipulate in the designer), what options to add to some files I have never even heard of before and such. Nothing about what you’ll definitely have to inherit etc, which functions should be implemented or anything. I found out things spending my first weekend on this but it turned out that while this approach works, it’s faster to just use one of the existing item view widgets of Qt, namely QTableView. I have many problems with the documentation (which isn’t that bad btw) but this is a first impressions post so I can write about that later.

Qt’s designer is a mess. I have mostly read positive opinions about it, but it’s not as good as the form designer in Visual Studio (which is not available for c++ unfortunately), and even the VS form designer was not as good as the one in Delphi/C++ Builder, which is still way ahead of the competition. The worst crime of the designer is that it can show you something, and when you compile your program what you get is entirely different. Most of the functionality which could be implemented in the designer is not. Whenever I needed something, and I expected a property to exist for it, it didn’t. You have to write many many lines of code to achieve things that were ordinary in the previously mentioned competition.

The layout system, which is used in the designer and in the running program too for placing widgets, was very hard for me to figure out, and I’m still struggling with it every time. It’s very different from what I’m used to, and maybe because I already learned something else, I find it unintuitive. This in itself could fill a whole post, but I think I won’t write about it, because it’d be just complaints about how it’s not what I’m used to.

To close this post, my first impression of Qt is that it is usable. It has convenient parts, and other parts that are so bad you wouldn’t believe it’s part of the same thing. I think I’ll be able to write zkanji using it, but it requires much time to learn.

In the next (probably shorter) post, I plan to write about my struggle to make zkanji with Qt work as a native app (at least on Windows).

Categories: Rant Tags: