Information Technology, Raspberry Pi

Raspberry Qt – Part 13 – A Bit of Explanation

qml_diffPlease read Part 12 first.

Were this a book I would be printing and explaining a lot of code. This isn’t a product people are paying for so it will be a bit more limited. Hopefully you pulled down the original source zip posted quite a ways back in this thread. You should have also pulled down the Pi QML zip file from my previous post. Now you just have to pull down this file.deskQml to have the whole enchilada.

The first thing to rant about is the amount of hand coding. This is a simple screen, not even well done. If it was done correctly the entire screen would have been enclosed in a HBOX layout so maximizing the screen would actually resize everything to use the entire screen. I didn’t do that with the UI file either so tried to keep this an apples to apples comparison.

Yes, the designer can be a PITA. Yes, there is some urban lore you have to absorb either from the wink and a nod club or by crawling naked through broken glass on your own. That said, I personally don’t care how yuge my UI file gets. I like having things like stacked widgets at my disposal. I would really hate to seem someone try to code the equivalent of a 12 screen stacked widget in QML. I keep reading about how QML is supposed to be for dynamic and complex screens, but I’m just not seeing it. Most importantly, this puddle of bits is INTERPRETED and part 12 showed you the extreme processor price one pays for that. Personally, I believe QML is only for people who want to work with nothing but their own rectangles.

Rather than show and explain the code as I tend to do in my books, we will just discuss the Meld diff image in this post. Hopefully your browser will let you zoom it to full screen and hopefully you have a real screen, not one of those identity theft enablers. On the left is the code from the PC, on the right is the code from the Pi. Naturally I developed on my desktop with multiple monitors first. Then when I tried to build it on the Pi I got burned.

Visually one cannot tell a difference in the running application. The Pi had a slightly older Qt release so it only had 1.2, not 1.4 of controls and their corresponding styles. At least on the right hand side you can see how the grizzled QML hacks do it. They have a rectangle which fills the parent and they give it the color. Add it first so everything is visually added on top of it which makes it _seem_ like a background color for the window. Instead of being an attribute of an object, the color is yet another object.

NOTE: If you declare an ApplicationWindow without a background color of any kind it is still given a background color based on the desktop/OS/environment/platform.

When you dig down deep in the C++ Qt documentation/lore you will find Qt optimizes screen updates for embedded platforms. Given the processor load we saw just moving the mouse around in the QML version of the application this cannot possibly be true for QML. What I mean by “optimizes” is if the GUI event queue gets 30+ events to repaint, say a button or an image, before the screen update actually has a chance to happen, Qt is smart enough to throw all but the last one away. The final version is what is important. Yes, there are ways to force a screen update if you really wish to slow your application down, but, if you are dynamically adding a bunch of objects, say file icons because you are displaying directory contents in a dialog, it is much nicer to have them all appear at once than watch ice melt. There have been other improvements as well:

Native Widgets vs Alien Widgets

Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing system. They do not have a native window handle associated with them. This feature significantly speeds up widget painting, resizing, and removes flicker.

Should you require the old behavior with native windows, you can choose one of the following options:

  1. Use the QT_USE_NATIVE_WINDOWS=1 in your environment.

  2. Set the Qt::AA_NativeWindows attribute on your application. All widgets will be native widgets.

  3. Set the Qt::WA_NativeWindow attribute on widgets: The widget itself and all of its ancestors will become native (unless Qt::WA_DontCreateNativeAncestors is set).

  4. Call QWidget::winId to enforce a native window (this implies 3).

  5. Set the Qt::WA_PaintOnScreen attribute to enforce a native window (this implies 3).

Not to mention off-screen rendering and many other speed improvements.

Other than the changes you see in the diff image, my Qt environments were close enough to allow the application to build and run without fatal incident. Yes, I had to follow down the checklist created with the “refresh” post.  qml-module-qtquick-extras was not in the repo at all and libqt5sql5-psql is in the repo but broken. Thankfully I need that for something else on my desktop.

There is one issue I need to mention. This is another pet peeve I have with non-proprietary scripted languages. You see DCL (Digital Command Language) is a proprietary scripting language for the OpenVMS operating system. As such it is safe, trusted and tested. JCL (Job Control Language) from IBM is what it sounds, a method of assembling job steps. Once again this is a thing which is proprietary, safe, trusted and tested. In the OpenSource world where any 12 yo with a keyboard and Internet access can submit stuff into a repo which cascades outwards, you continually get victimized by (&*)(*& like this:

QML Debugger: Waiting for connection on port 46163...
13:07:30 Level: 7 Message: Root object had name of window
13:07:30 Level: 7 Message: Result of connecting signals 1
JITed object file architecture armv4 is not compatible with target architecture arm.
JITed object file architecture armv4 is not compatible with target architecture arm.
JITed object file architecture armv4 is not compatible with target architecture arm.
JITed object file architecture armv4 is not compatible with target architecture arm.
JITed object file architecture armv4 is not compatible with target architecture arm.
JITed object file architecture armv4 is not compatible with target architecture arm.
JITed object file architecture armv4 is not compatible with target architecture arm.
JITed object file architecture armv4 is not compatible with target architecture arm.
qml: received YELLOW

qml: sending BLUE
QThread: Destroyed while thread is still running

Okay, the QThread thing at the end is me. I did not connect up a signal from the engine to set the shutdown flag for a graceful exit. I’m talking about the “object file architecture.” This is a javascript/QML issue with plenty of fingers to point in plenty of directions. My issue isn’t this particular debacle, rather it is that debacles like these always happen with OpenSource scripting things.

For those who do not know, JIT stands for Just In Time. Each and every time you run your QML program, the QML portion is compiled to a state many refer to as “p-compiled.” Some even call it “Taint” because “taint” binary and “taint” source. It is a set of byte codes the engine/VM recognize but certainly not the CPU. Somewhere along the way someone tried desperately to shave perhaps 3% of CPU utilization and some hefty poundage from the Qt package by only including support for armv4 (at least in the Raspbian repos, but it could go all the way back to Digia.)

Assignment:

Get rid of the annoying QThread: message. I humbly suggest you change SerialThread::shutDown() from a public method to a public slot to make your life easier. You probably want to look at all of the signals QApplication has to offer as well.