Connectivity options for mobile M2M/IoT/Connected devices

Many of us deal or will deal with (connected) M2M/IoT devices. This might be writing firmware for microcontrollers, using a RTOS like NuttX or a full blown Unix (like) operating system like FreeBSD or Yocto/Poky Linux, creating and building code to run on the device, processing data in the backend or somewhere inbetween. Many of these devices will have sensors to collect data like GNSS position/time, temperature, light detector, measuring acceleration, see airplanes, detect lightnings, etc.

The backend problem is work but mostly "solved". One can rely on something like Amazon IoT or creating a powerful infrastructure using many of the FOSS options for message routing, data storage, indexing and retrieval in C++. In this post I want to focus about the little detail of how data can go from the device to the backend.



To make this thought experiment a bit more real let's imagine we want to build a bicycle lock/tracker. Many of my colleagues ride their bicycle to work and bikes being stolen remains a big tragedy. So the primary focus of an IoT device would be to prevent theft (make other bikes a more easy target) or making selling a stolen bicycle more difficult (e.g. by easily checking if something has been stolen) and in case it has been stolen to make it more easy to find the current location.

Architecture

Let's assume two different architectures. One possibility is to have the bicycle actively acquire the position and then try to push this information to a server ("active push"). Another approach is to have fixed installed scanning stations or users to scan/report bicycles ("passive pull"). Both lead to very different designs.

Active Push

The system would need some sort of GNSS module, a microcontroller or some full blown SoC to run Linux, an accelerator meter and maybe more sensors. It should somehow fit into an average bicycle frame, have good antennas to work from inside the frame, last/work for the lifetime of a bicycle and most importantly a way to bridge the air-gap from the bicycle to the server.

Push architecture

Passive Pull

The device would not know its position or if it is moved. It might be a simple barcode/QR code/NFC/iBeacon/etc. In case of a barcode it could be the serial number of the frame and some owner/registration information. In case of NFC it should be a randomized serial number (if possible to increase privacy). Users would need to scan the barcode/QR-code and an application would annotate the found bicycle with the current location (cell towers, wifi networks, WGS 84 coordinate) and upload it to the server. For NFC the smartphone might be able to scan the tag and one can try to put readers at busy locations.

The incentive for the app user is to feel good collecting points for scanning bicycles, maybe some rewards if a stolen bicycle is found. Buyers could easily check bicycles if they were reported as stolen (not considering the difficulty of how to establish ownership).


Pull architecture



Technology requirements

The technologies that come to my mind are Barcode, QR-Code, play some humanly not hearable noise and decode in an app, NFCZigBee6LoWPANBluetooth, Bluetooth Smart, GSM, UMTS, LTE, NB-IOT. Next I will look at the main differentiation/constraints of these technologies and provide a small explanation and finish how these constraints interact with each other.


World wide usable

Radio Technology operates on a specific set of radio frequencies (Bands). Each country may manage these frequencies separately and this can lead to having to use the same technology on different bands depending on the current country. This will increase the complexity of the antenna design (or require multiple of them), make mechanical design more complex, makes software testing more difficult, production testing, etc. Or there might be multiple users/technologies on the same band (e.g. wifi + bluetooth or just too many wifis).



Power consumption

Each radio technology requires to broadcast and might require to listen or permanently monitor the air for incoming messages ("paging"). With NFC the scanner might be able to power the device but for other technologies this is unlikely to be true. One will need to define the lifetime of the device and the size of the battery or look into ways of replacing/recycling batteries or to charge them.



Range

Different technologies were designed to work with sender/receiver being away at different min/max. distances (and speeds but that is not relevant for the lock nor is the bandwidth for our application). E.g. with Near Field Communication (NFC) the workable range is meters while with GSM it will be many kilometers and with UMTS the cell size depends on how many phones are currently using it (the cell is breathing).



Pick two of three

Ideally we want something that works over long distances, requires no battery to send/receive and the system is still pushing out the position/acceleration/event report to servers. Sadly this is not how reality works and we will have to set priorities.

The more bands to support, the more complicated the antenna design, production, calibration, testing. It might be that one technology does not work in all countries or that it is not equally popular or the market situation is different, e.g. some cities have city wide public hotspots, some don't.

Higher power transmission increases the range but increases the power consumption even more. More current will be used during transmission which requires a better hardware design to buffer the spikes, a bigger battery and ultimately a way to charge or efficiently replace batteries.

Given these constraints it is time to explore some technologies. I will use the one already mentioned at the beginning of this section.


Technologies


Technology Bands Global coverage Range Battery needed Scan Device needed Cost of device Arch. Comment
Barcode/QR-Code Optical Yes Centimeters No App scanning barcode required extremely low Pull Sticker needs to be hard to remove and visible, maybe embedded to the frame
Play audio Non human hearable audio Yes Centimeters Yes App recording audio moderate Pull Button to play audio?
NFC 13.56 Mhz Yes Centimeters No Yes extremely low Pull Privacy issues
RFID Many Yes, but not on single band Centimeters to meters Yes Receiver required low Pull Many bands, specific readers needed
Bluetooth LE 2.4 Ghz Yes Meters Yes Yes, but common low Pull/Push Competes with Wifi for spectrum
ZigBee Multiple Yes, but not on single band Meters Yes Yes mid Push Not commonly deployed, software more involved
6LoWPAN Like ZigBee Like ZigBee Meters Yes Yes low Push Uses ZigBee physical layer and then IPv6. Requires 6LoWPAN to Internet translation
GSM 800/900, 1800/1900 Almost besides South Korea, Japan, some islands Kilometers Yes No moderate Push Almost global coverage, direct communication with backend possible
UMTS Many Less than GSM but South Korea, Japan Meters to Kilometers depends on usage Yes No high Push Higher power usage than GSM, higher device cost
LTE Many Less than GSM Designed for kilometers Yes No high Push Expensive, higher power consumption
NB-IOT (LTE) Many Not deployed Kilometers Yes No high Push Not deployed and coming in the future. Can embed GSM equally well into a LTE carrier


Conclusion

Both a push and pull architecture seem to be feasible and create different challenges and possibilities. A pull architecture will require at least Smartphone App support and maybe a custom receiver device. It will only work in regions with lots of users and making privacy/tracking more difficult is something to solve.

For push technology using GSM is a good approach. If coverage in South Korea or Japan is required a mix of GSM/UMTS might be an option. NB-IOT seems nice but right now it is not deployed and it is not clear if a module will require less power than a GSM module. NB-IOT might only be in the interest of basestation vendors (the future will tell). Using GSM/UMTS brings its own set of problems on the device side but that is for other posts.

GammaRay 2.5 release

GammaRay 2.5 has been released, the biggest feature release yet of our Qt introspection tool. Besides support for Qt 5.7 and in particular the newly added Qt 3D module a slew of new features awaits you, such as access to QML context property chains and type information, object instance statistics, support for inspecting networking and SSL classes, and runtime switchable logging categories.

We also improved many existing functionality, such as the object and source code navigation and the remote view. We enabled recursive access to value type properties and integrated the QPainter analyzer in more tools.

GammaRay is now also commercially available as part of the Qt Automotive suite, which includes integration with QtCreator for convenient inspection of embedded targets using Linux, QNX, Android or Boot2Qt.

Download GammaRay

The post GammaRay 2.5 release appeared first on KDAB.

KDStateMachineEditor 1.1.0 released

KDStateMachineEditor is a Qt-based framework for creating Qt State Machine metacode using a graphical user interface. It works on all major platforms and is now available as part of the Qt Auto suite.

The latest release of KDAB’s KDStateMachineEditor includes changes to View, API and Build system.

View

  • Button added to show/hide transition labels
  • Now using native text rendering
  • Status bar removed

API

  • API added for context menu handling (cf. StateMachineView class)

Build system

  • Toolchain files added for cross-compiling (QNX, Android, etc.)
  • Compilation with namespaced Qt enabled
  • Build with an internal Graphviz build allowed (-DWITH_INTERNAL_GRAPHVIZ=ON)

KDStateMachineEditor Works on all major platforms and has been tested on Linux, OS X and Windows.

Prebuilt packages for some popular Linux distributions can be found here.

Homebrew recipe for OSX users can be found here.

The post KDStateMachineEditor 1.1.0 released appeared first on KDAB.

KDAB contributions to Qt 5.7

Hello, and welcome to the usual appointment with a new release of Qt!

Qt 5.7 has just been released, and once more, KDAB has been a huge part of it (we are shown in red on the graph):

Qt Project commit stats, up to June 2016. From http://www.macieira.org/blog/qt-stats/

Qt Project commit stats, up to June 2016. From http://www.macieira.org/blog/qt-stats/

In this blog post I will show some of the outstanding contributions by KDAB engineers to the 5.7 release.

Qt 3D

The star of Qt 5.7 is the first stable release of Qt 3D 2.0. The new version of Qt 3D is a total redesign of its architecture into a modern and streamlined 3D engine, exploiting modern design patterns such as entity-component systems, and capable to scale due to the heavily threaded design. This important milestone was the result of a massive effort done by KDAB in coordination with The Qt Company.

neptune-pbr1

If you want to know more about what Qt 3D can do for your application, you can watch this introductive webinar recorded by KDAB’s Dr. Sean Harmer and Paul Lemire for the 5.7 release.

Qt on Android

Thanks to KDAB’s BogDan Vatra, this release of Qt saw many improvements to its Android support. In no particular order:

  • Qt can now be used to easily create Android Services, that is, software components performing background tasks and that are kept alive even when the application that started them exits. See here for more information.
  • The QtAndroidExtras module gained helper functions to run Runnables on the Android UI thread. They are extremely useful for accessing Android APIs from C++ code that must be done on Android UI thread. More info about this is available in this blog post by BogDan.
  • Another addition to the QtAndroidExtras module is the QtAndroid::hideSplashScreen function, which allows a developer to programmatically hide the splash screen of their applications.
  • The QtGamepad module gained Android support.

Performance and correctness improvements

A codebase as big as Qt needs constant fixes, improvements and bugfixes. Sometimes these come from bug reports, sometimes by reading code in order to understand it better, and in some other cases by analyzing the codebase using the latest tools available. KDAB is committed to keeping Qt in a great shape, and that is why KDAB engineers spend a lot of time polishing the Qt codebase.

Some of the results of these efforts are:

  • QHash gained equal_range, just like QMap and the other STL associative container. This function can be used to iterate on all the values of a (multi)hash that have the same key without performing any extra memory allocation. In other words, this code:
    // BAD!!! allocates a temporary QList 
    // for holding the values corresponding to "key"
    foreach (const auto &value, hash.values(key)) {
    }
    

    can be changed to

    const auto range = hash.equal_range(key);
    for (auto i = range.first; i != range.second; ++i) {
    }
    

    which never throws (if hash is const), expands to less code and does not allocate memory.

  • Running Qt under the Undefined Behavior Sanitizer revealed dozens of codepaths where undefined behaviour was accidentally triggered. The problems ranged from potential signed integer overflows and shift of negative numbers to misaligned loads, invalid casts and invalid calls to library functions such as memset or memcpy. KDAB’s Senior Engineer Marc Mutz contributed many fixes to these undefined behaviours, fixes that made their way into Qt 5.6.1 and Qt 5.7.
  • Some quadratic loops were removed from Qt and replaced with linear or linearithmic ones. Notably, an occurrence of such loops in the Qt Quick item views caused massive performance degradations when sorting big models, which was fixed in this commit by KDAB’s engineer Milian Wolff.
  • Since Qt 5.7 requires the usage of a C++11 compiler, we have starting porting foreach loops to ranged for loops. Ranged for loops expand to less code (because there is no implicit copy taking place), and since compilers recognize them as a syntactic structure, they can optimize them better. Over a thousand occurrences were changed, leading to savings in Qt both in terms of library size and runtime speed.
  • We have also started using C++ Standard Library features in Qt. While Qt cannot expose STL types because of its binary compatibility promise, it can use them in its own implementation. A big advantage of using STL datatypes is that they’re generally much more efficient, have more features and expand to a lot less code than Qt counterpart. For instance, replacing some QStack usages with std::stack led to 1KB of code saved per instance replaced; and introducing std::vector in central codepaths (such as the ones in QMetaObjectBuilder) saved 4.5KB.
  • While profiling Qt3D code, we found that the mere act of iterating over resources embedded in an application (by means of QDirIterator) uncompressed them. Then, reading a given resource via QFile uncompressed it again. This was immediately fixed in this commit by KDAB’s Director of Automotive, Volker Krause.

Other contributions

Last but not least:

  • It is now possible to use the Qt Virtual Keyboard under QtWayland compositors.
  • The clang-cl mkspec was added. This mkspec makes it possible to build Qt using the Clang frontend for MSVC. Stay tuned for more blog posts on this matter. 🙂
  • A small convenience QFlag::setFlag method was added, to set or unset a flag in a bitmask without using bitwise operations.

About KDAB

KDAB is a consulting company dedicated to Qt and offering a wide variety of services and providing training courses in:

KDAB believes that it is critical for our business to invest in Qt3D and Qt, in general, to keep pushing the technology forward, ensuring it remains competitive.

The post KDAB contributions to Qt 5.7 appeared first on KDAB.

Four Habit-Forming Tips to Faster C++

Are you a victim of premature pessimisation? Here’s a short definition from Herb Sutter:

Premature pessimization is when you write code that is slower than it needs to be, usually by asking for unnecessary extra work, when equivalently complex code would be faster and should just naturally flow out of your fingers.

Despite how amazing today’s compilers have become at generating code, humans still know more about the intended use of a function or class than can be specified by mere syntax. Compilers operate under a host of very strict rules that enforce correctness at the expense of faster code. What’s more, modern processor architectures sometimes compete with C++ language habits that have become ingrained in programmers from decades of previous best practice.

I believe that if you want to improve the speed of your code, you need to adopt habits that take advantage of modern compilers and modern processor architectures—habits that will help your compiler generate the best-possible code. Habits that, if you follow them, will generate faster code before you even start the optimisation process.

Here’s four habit-forming tips that are all about avoiding pessimisation and, in my experience, go a long way to creating faster C++ classes.

1) Make use of the (named-) return-value optimisation

According to Lawrence Crowl, (named-) return-value optimisation ((N)RVO) is one of the most important optimisations in modern C++. Okay—what is it?

Let’s start with plain return-value optimization (RVO). Normally, when a C++ method returns an unnamed object, the compiler creates a temporary object, which is then copy-constructed into the target object.

MyData myFunction() {
    return MyData(); // Create and return unnamed obj
}

MyData abc = myFunction();

With RVO, the C++ standard allows the compiler to skip the creation of the temporary, treating both object instances—the one inside the function and the one assigned to the variable outside the function—as the same. This usually goes under the name of copy elision. But what is elided here is the temporary and the copy.

So, not only do you save the copy constructor call, you also save the destructor call, as well as some stack memory. Clearly, elimination of extra calls and temporaries saves time and space, but crucially, RVO is an enabler for pass-by-value designs. Imagine MyData was a large million-by-million matrix. There mere chance that some target compiler could fail to implement this optimisation would make every good programmer shy away from return-by-value and resort to out parameters instead (more on those further down).

As an aside: don’t C++ Move Semantics solve this? The answer is: no. If you move instead of copy, you still have the temporary and its destructor call in the executable code. And if your matrix is not heap-allocated, but statically sized, such as a std::array<std::array<double, 1000>, 1000>>, moving is the same as copying. With RVO, you mustn’t be afraid of returning by value. You must unlearn what you have learned and embrace return-by-value.

Named Return Value Optimization is similar but it allows the compiler to eliminate not just rvalues (temporaries), but lvalues (local variables), too, under certain conditions.

What all compilers these days (and for some time now) reliably implement is NRVO in the case where there is a single variable that is passed to every return, and declared at function scope as the first variable:

MyData myFunction() {
    MyData result;           // Declare return val in ONE place

    if (doing_something) {
        return result;       // Return same val everywhere
    }
    // Doing something else
    return result;           // Return same val everywhere
}

MyData abc = myFunction();

Sadly, many compilers, including GCC, fail to apply NRVO when you deviate even slightly from the basic pattern:

MyData myFunction() {
    if (doing_something)
        return MyData();     // RVO expected

    MyData result;

    // ...
    return result;           // NRVO expected
}

MyData abc = myFunction();

At least GCC fails to use NRVO for the second return statement in that function. The fix in this case is easy (go back to the first version), but it’s not always that easy. It is an altogether sad state of affairs for a language that is said to have the most advanced optimisers available to it for compilers to fail to implement this very basic optimisation.

So, for the time being, get your fingers accustomed to typing the classical NRVO pattern: it enables the compiler to generate code that does what you want in the most efficient way enabled by the C++ standard.

If diving into assembly code to check whether a particular patterns makes your compiler drop NRVO isn’t your thing, Thomas Brown provides a very comprehensive list of compilers tested for their NRVO support and I’ve extended Brown’s work with some additional results.

If you start using the NVRO pattern but aren’t getting the results you expect, your compiler may not automatically perform NRVO transformations. You may need to check your compiler optimization settings and explicitly enable them.

Return parameters by value whenever possible

This is pretty simple: don’t use “out-parameters”. The result for the caller is certainly kinder: we just return our value instead of having the caller allocate a variable and pass in a reference. Even if your function returns multiple results, nearly all of the time you’re much better off creating a small result struct that the function passes back (via (N)RVO!):

That is, instead of this:

void convertToFraction(double val, int &numerator, int &denominator) {
    numerator = /*calculation */ ;
    denominator = /*calculation */ ;
}

int numerator, denominator;
convertToFraction(val, numerator, denominator); // or was it "denominator, nominator"?
use(numerator);
use(denominator);                                                    

You should prefer this:

struct fractional_parts {
    int numerator;
    int denominator;
};

fractional_parts convertToFraction(double val) {
    int numerator = /*calculation */ ;
    int denominator = /*calculation */ ;
    return {numerator, denominator}; // C++11 braced initialisation -> RVO
}

auto parts = convertToFraction(val);
use(parts.nominator);
use(parts.denominator);

This may seem surprising, even counter-intuitive, for programmers that cut their teeth on older x86 architectures. You’re just passing around a pointer instead of a big chunk of data, right? Quite simply, “out” parameter pointers force a modern compiler to avoid certain optimisations when calling non-inlined functions. Because the compiler can’t always determine if the function call may change an underlying value (due to aliasing), it can’t beneficially keep the value in a CPU register or reorder instructions around it. Besides, compilers have gotten pretty smart—they don’t actually do expensive value passing unless they need to (see the next tip). With 64-bit and even 32-bit CPUs, small structs can be packed into registers or automatically allocated on the stack as needed by the compiler. Returning results by value allows the compiler to understand that there isn’t any modification or aliasing happening to your parameters, and you and your callers get to write simpler code.

3) Cache member-variables and reference-parameters

This rule is straightforward: take a copy of the member-variables or reference-parameters you are going to use within your function at the top of the function, instead of using them directly throughout the method. There are two good reasons for this.

The first is the same as the tip above—because pointer references (even member-variables in methods, as they’re accessed through the implicit this pointer) put a stick in the wheels of the compiler’s optimisation. The compiler can’t guarantee that things don’t change outside its view, so it takes a very conservative (and in most cases wasteful) approach and throws away any state information it may have gleaned about those variables each time they’re used anew. And that’s valuable information that can help the compiler eliminate instructions and references to memory.

Another important reason is correctness. As an example provided by Lawrence Crowl in his CppCon 2014 talk “The Implementation of Value Types”, instead of this complex number multiplication:

template <class T> 
complex<T> &complex<T>;::operator*=(const complex<T> &a) {
   real = real * a.real – imag * a.imag;
   imag = real * a.imag + imag * a.real;
   return *this;
}

You should prefer this version:

template <class T> 
complex<T> &complex<T>;::operator*=(const complex<T> &a) {
   T a_real = a.real, a_imag = a.imag;
   T t_real =   real, t_imag =   imag; // t == this
   real = t_real * a_real – t_imag * a_imag;
   imag = t_real * a_imag + t_imag * a_real;
   return *this;
}

This second, non-aliased version will still work properly if you use value *= value to square a number; the first one won’t give you the right value because it doesn’t protect against aliased variables.

To summarise succinctly: read from (and write to!) each non-local variable exactly once in every function.

4) Organize your member variables intelligently

Is it better to organize member variables for readability or for the compiler? Ideally, you pick a scheme that works for both.

And now is a perfect time for a short refresher about CPU caches. Of course data coming from memory is very slow compared to data coming from a cache. An important fact to remember is that data is loaded into the cache in (typically) 64-byte blocks called cache lines. The cache line—that is, your requested data and the 64 bytes surrounding it—is loaded on your first request for memory absent in the cache. Because every cache miss silently penalises your program, you want a well-considered strategy for ensuring you reduce cache misses whenever possible. Even if the first memory access is outside the cache, trying to structure your accesses so that a second, third, or forth access is within the cache will have a significant impact on speed. With that in mind, consider these tips for your member-variable declarations:

  • Move the most-frequently-used member-variables first
  • Move the least-frequently-used member-variables last
  • If variables are often used together, group them near each other
  • Try to reference variables in your functions in the order they’re declared

Nearly all C++ compilers organize member variables in memory in the order in which they are declared. And grouping your member variables using the above guidelines can help reduce cache misses that drastically impact performance. Although compilers can be smart about creating code that works with caching strategies in a way that’s hard for humans to track, the C++ rules on class layout make it hard for compilers to really shine. Your goal here is to help the compiler by stacking the deck on cache-line loads that will preferentially load the variables in the order you’ll need them.

This can be a tough one if you’re not sure how frequently things are used. While it’s not always easy for complicated classes to know what member variables may be touched more often, generally following this rule of thumb as well as you can will help. Certainly for the simpler classes (string, dates/times, points, complex, quaternions, etc) you’ll probably be accessing most member variables most of the time, but you can still declare and access your member variables in a consistent way that will help guarantee that you’re minimizing your cache misses.

Conclusion

The bottomline is that it still takes some amount of hand-holding to get a compiler to generate the best code. Good coding-habits are by no means the end-all, but are certainly a great place to start.

The post Four Habit-Forming Tips to Faster C++ appeared first on KDAB.

Programmation Qt Quick (QML)

Paris, le 22 – 26 Août

En août offrez-vous une formation Qt en français avec un expert.

Apprenez les techniques de développement d’applications graphiques modernes, en utilisant la technologie Qt Quick (basée sur le langage QML) ainsi que la technologie objet Qt/C++.

“Mon équipe C++ a été ravie de cette formation. J‘espère pouvoir implémenter Qt dans nos applis ASAP.” CGG Veritas, Massy, France

Découvrir plus!

Voyez autres retours clients.

Enregistrez-vous

The post Programmation Qt Quick (QML) appeared first on KDAB.

Virtual Tactile-ness: Creating Engaging User Experiences

When you walk on a beach, you may be tempted to reach down and pick up a smooth stone or a shiny shell, turn it around in your fingers feeling its weight and texture. If a friendly cat or dog walks close by, you may be tempted to reach out and stroke its fur. When humans are attracted to an object because of its color, shape, surface or texture – because of its visceral appeal – they are often compelled to reach out and touch it.

Can the same attraction happen in a virtual realm, in a user experience?

Qt WebBrowser 1.0

We have recently open sourced Qt WebBrowser!

Screenshot of the Qt WebBrowser.
Qt WebBrowser (codename Roadtrip) is a browser for embedded devices developed using the capabilities of Qt and Qt WebEngine. Using Chromium, it features up-to-date HTML technologies behind a minimal but slick touch-friendly user interface written in Qt Quick.

All basic browser features are supported: You can search for text (both in history and via Google). You can bookmark pages, navigate in the page history, and open multiple pages concurrently. Depending on the codecs available, full-screen video and audio playback should also just work. You can also enable a private browser mode that leaves no traces after the browser is closed.

So far the browser has been only shipped as part of the Qt for Device Creation demo, but we’re now releasing it also separately under GPLv3 and Commercial licenses. The browser serves as a testbed and demo for Qt and Qt WebEngine, but we see that it can also be used in your device solutions. So please talk to us if you have any kind of feedback, particularly feature requests! The preferred place is JIRA, but you can also just drop us a mail.

The browser is optimized for embedded touch displays (running Linux), but you can play with it on the desktop platforms, too! Just make sure that you have Qt WebEngine, Qt Quick, and Qt VirtualKeyboard installed (version 5.7 or newer). For optimal performance on embedded devices you should plan for hardware-accelerated OpenGL, and around 1 GiByte of memory for the whole system. Anyhow, depending on your system configuration and the pages to be supported there is room for optimization.

More details about the browser’s user interface and capabilities can be found in the documentation. The source code is hosted on code.qt.io.

The post Qt WebBrowser 1.0 appeared first on Qt Blog.

Leaving Berlin, saying hello to Amsterdam

Berlin continues to gain a lot of popularity, culturally and culinarily it is an awesome place and besides increasing rents it still remains more affordable than other cities. In terms of economy Berlin attracts new companies and branches/offices as well. At the same time I felt the itch and it was time to leave my home town once again. In the end I settled for the bicycle friendly (and sometimes sunny) city of Amsterdam.

My main interest remains building reliable systems with Smalltalk, C/C++, Qt and learn new technology (Tensorflow? Rust? ElasticSearch, Mongo, UUCP) and talk about GSM (SCCP, SIGTRAN, TCAP, ROS, MAP, Diameter, GTP) or get re-exposed to WebKit/Blink.

If you are in Amsterdam or if you know people or companies I am happy to meet and make new contacts.

A Quick Preview of What You’ll See at Qt World Summit 2016

This year at #QtWS16, The Qt Company and our ecosystem will deliver several inspirational keynotes, insightful breakouts, take a look into the future of IoT and how Qt will be the enabler, putting you and your project ahead of the curve.

Here is a sneak peek at some of the things you will see in San Francisco at the Qt World Summit:

Seating is limited, so register today for the early bird offer!

The post A Quick Preview of What You’ll See at Qt World Summit 2016 appeared first on Qt Blog.

Leaky lambdas and self referencing shared pointers

After a bit of a debugging session, I ended up looking at some code in a large project

m_foo = std::make_shared<SomeQObject>();
/* plenty of lines and function boundaries left out */ 
(void)connect(m_foo.get(), &SomeQObject::someSignal, [m_foo]() {
  /* */
});

The connection gets removed when the pointer inside m_foo gets de-allocated by the shared_ptr.
But the connection target is a lambda that has captured a copy of the shared_ptr…

There is at least a couple of solutions.

  • Keep the connection object (QMetaObject::Connection) around and call disconnect in your destructor. That way the connection gets removed and the lamda object should get removed
  • Capture the shared pointer by (const) reference. Capture the shared pointer as a weak pointer. Or as a raw pointer. All of this is safe because whenever the shared pointer gets a refcount of zero, the connection gets taken down with the object.

I guess the lesson learnt is be careful when capturing shared pointers.

Let Qt models meet std::vector<std::tuple<…>>

The problem

So. I was stuck with a container of tuples that I wanted to see in a Qt view (QTableView, QtQuick ListView or similar). So how to do that?

Another problem: I haven’t been doing fun things with templates recently.

A solution?

After a bit of hacking, it seems like it can just be done like

typedef std::tuple<std::string, QString> Element;
typedef std::vector List;
List list = { std::make_tuple("first", "second"), 
              std::make_tuple("third", "fourth") };
std::unique_ptr<TableModel> magic = createTableModel(list);
QTableView view;
view.setModel(magic->model());

and … tada:
QTableView

Of course, we are also QtQuick friendly

std::unique_ptr<ListModel>List>> magic = createListModel(list);
// expose magic->model() to your quickview

and a delegate containing the following

Text {
    text: role0
}
Text {
    text: role1
}

 

can give:
ListView

But enough about creation.

Whattabout manipulation?

Luckily we got you covered. Insert two extra rows at position 1?

auto lines = { std::make_tuple("extra", "extra"),
               std::make_tuple("extra2","extra2") };
magic->insertRows(1,lines.begin(), lines.end());

Append a row?

magic->appendRow(std::make_tuple("",""));

Remove 2 rows at position 3?

magic->removeRow(3,2);

Replace the underlying list?

List newList;
// fill list
magic->reset(newList);

Read-only looping over the elements?

for(const Element& e : magic->list())
{
    ...
}

The Qt model of course also accepts setData calls.

Future?

If anyone is interested I will polish the code a bit and publish it. If that’s the case, how should I name this thing?

And I did get around doing fun things with templates again.

Qt Creator 4.0.3 released

We are happy to announce the release of Qt Creator 4.0.3.

Improvements

In this release we removed a bug which disabled the run button on macOS 10.8 and FreeBSD, made the Clang code model stop replacing the dot in floating point literals by an arrow, and fixed an issue with opening CMake projects from symbolically linked directories.

Please find more information in our change log.

Get Qt Creator 4.0.3

The opensource version is available on the Qt download page, and you find commercially licensed packages on the Qt Account Portal. Qt Creator 4.0.3 is also available through an update in the online installer. Please post issues in our bug tracker. You can also find us on IRC on #qt-creator on chat.freenode.net, and on the Qt Creator mailing list.

The post Qt Creator 4.0.3 released appeared first on Qt Blog.

Qt Creator 4.1.0 Beta released

We are happy to announce the release of Qt Creator 4.1.0 Beta1.

dark-flat light-flat

What could be said to be the most visible new feature, if you turn it on, is that we added the Flat Dark and Flat Light themes. These are the continuation of the effort to implement the concept design by Diana, and complement the Flat theme, which is a light theme with dark tool bars that was introduced with Qt Creator 4.0. You can change the theme in the Environment > Interface > Theme settings and try them.

Editing

A feature that should be mostly invisible, is that Qt Creator now automatically releases resources of documents that are not modified and have not been in your focus for a longer time (meaning: that moved a certain way down in your document history). We actually have a related feature since a long time already: When we restore a session, only the visible documents are loaded into editors, even though the others appear in the Open Documents pane and other document choosers. Opening them will also restore editor state, like scroll and cursor positions. Documents can now fall back into that state even after they were loaded. This avoids Qt Creator accumulating system resources, without the need for the user to manually close documents. You can configure this behavior in the Environment > System settings.

The text editors have received another long wished for improvement. You can now separately define if brackets or quotes are automatically added while typing. There are also separate settings if typing the character manually will then replace the automatically inserted character, and if deleting the originally typed character will remove the automatically inserted counterpart. Additionally the latter two features should behave more natural, because they are only active as long as the text cursor does not move away from the location where the counterpart character was added. Find the new options in the Text Editor > Completion settings.

C++

We have updated our binary packages to use Clang 3.8, which fixes many issues with parsing MSVC 2015 standard headers with the Clang code model. We also separated the color scheme setting for function declarations and usages, and added a new one for global variables.

Qt Quick

If you are working with Qt Quick, you might be happy to hear that we greatly improved the overall performance of Qt Quick designer, by optimizing the process of updating the QML document when changes happen. You can now also choose the Qt Quick Controls 2 style that your items should be rendered in.

We also improved the the performance of the QML Profiler in the presence of many events.

Other Additions and Improvements

We further improved the CMake project support that was overhauled in Qt Creator 4.0. You now have the option to turn off automatic running of CMake per configured tool (Build & Run > CMake). It is now also no longer run automatically if Qt Creator is not the active application. We also improved the parsing of CMake errors, and fixed an issue with the ordering of include paths that are passed to the code model.

Because of the efforts of Filippo Cucchetto we now also have experimental support for the Nim programming language. (Turn the plugin on in Help > About Plugins, or Qt Creator > About Plugins on macOS.) It includes syntax highlighting, indentation, coding style settings, and simple project management supporting building, running and debugging applications. Many thanks to him for this contribution!

There have been many other changes. Please refer to our change log for a more complete overview.

Get Qt Creator 4.1.0 Beta1

The opensource version is available on the Qt download page, and you find commercially licensed packages on the Qt Account Portal. Please post issues in our bug tracker. You can also find us on IRC on #qt-creator on chat.freenode.net, and on the Qt Creator mailing list.

The post Qt Creator 4.1.0 Beta released appeared first on Qt Blog.

WireGuard, Secure Network Tunnel with Modern Crypto

After quite a bit of hard work, I've at long last launched WireGuard, a secure network tunnel that uses modern crypto, is extremely fast, and is easy and pleasurable to use. You can read about it at the website, but in short, it's based on the simple idea of an association between public keys and permitted IP addresses. Along the way it uses some nice crypto trick to achieve it's goal. For performance it lives in the kernel, though cross-platform versions in safe languages like Rust, Go, etc are on their way.

The launch was wildly successful. About 10 minutes after I ran /etc/init.d/nginx restart, somebody had already put it on Hacker News and the Twitter sphere, and within 24 hours I had received 150,000 unique IPs. The reception has been very warm, and the mailing list has already started to get some patches. Distro maintainers have stepped up and packages are being prepared. There are currently packages for Gentoo, Arch, Debian, and OpenWRT, which is very exciting.

Although it's still experimental and not yet in final stable/secure form, I'd be interested in general feedback from experimenters and testers.

Status Update on Qt for WinRT / UWP

It has been a long while since we were writing on this blog about the WinRT port of Qt.

Hence, this is going to be a longer article on what we achieved in the meanwhile, are currently working on, and what we will provide in future releases.

Supported Platforms

WinRT as a platform API set has been continuously improved and new features have been added which Qt can make use of, allowing us to provide more of Qt API to developers. One example is drag and drop support.

Many of you might have heard of the terminology Universal Windows Platform, or UWP. This describes a rather high level abstraction, in the end it boils down to the WinRT API being used and extended. Hence, the Qt for WinRT version currently supports the following platforms:

  • Windows 8.1
  • Windows Phone 8.1
  • Windows 10
  • Windows 10 Mobile
  • Windows 10 IoT (Core/Professional) *
  • Microsoft Hololens *
  • XBOX One *

* I will talk about those platforms later.

Previous / Current Qt releases

Qt 5.6 marked an important release for the port as we needed to exchange a lot of the internals to be able to integrate custom Xaml content into a Qt application. One example of achieving this was to enable support for Qt WebView, which integrates Microsoft Edge into a Qt application. In case you have your own custom Xaml content you need integrated, I recommend to take a look at the source code. You will recognize that there are some caveats on what you need to do from which thread.

Furthermore, we have been working a lot on camera support in Qt Multimedia, added synthesis of Pen events to use it e.g. on Surface devices and general bug fixes and stability improvements. At Qt 5.6 is a LTS release, we will also continue to update this branch and provide fixes for crucial bug reports.

In addition Qt 5.6.1 includes two workflow changes I would like to highlight:

  1. Creating a Visual Studio project with qmake does not require to add CONFIG+=windeployqt anymore. We have recognized that almost all users use this option instead of manually deploying or collection libraries and plugins for the package. Hence, we enabled it by default.
  2. We added a default capability feature for the template manifest. As an example, if you use QT+=multimedia in your project, this will automatically add webcam and microphone capabilities to your project. The benefit is that during development you will have all features available without considering which capability matches which feature. However, you have to make sure to remove non required capabilities during the publishing process. For instance, the internetClientServer capability is enabled by default allowing an app to act as a server. In most cases you will not need this capability for your app.

Moving on to Qt 5.7 there are two features to emphasize about Qt on WinRT.

First of all, we added a low latency audio plugin, utilizing WASAPI. This was due to huge request by users. Additionally, this plugin can also be used for classic development, meaning regular desktop applications. The advantage against the windowsaudio backend using WaveOut is clearly found in latency. According to Microsoft the guaranteed latency has been greatly reduced in Windows 10 and later releases and you will be able to utilize it with Qt plugin. The downside is that WASAPI synchronizes the sample-rate to the audio driver without providing any conversion capabilities for a developer. Hence, you are responsible for converting between sample rates in case those do not match. The plugin is not enabled by default for the desktop platforms, but you can compile, test and use it from our git repository or source package.

One additional item we have added with experimental support is to use JIT in the QmlEngine on x86 and x64 architectures. You might remember that initially this was not supported for the Windows Store. However, this seems to have changed even though there is no public statement or documentation about this yet. Using JIT can speed up your application significantly depending on your use cases, for instance some test functions in the engine auto tests executed faster by a factor of 100+. To enable this in your WinRT app, all you have to do is add the codeGeneration capability in your manifest, recompile your appx and start testing. From our experiments it is possible to push and publish an app in the Windows Store, however it is not guaranteed that this feature will stay. We have been told that this capability is mostly used for .NET native, but also (or because of it) allows VirtualAllocFromApp/VirtualFree to succeed.

Future Qt releases

We would like to see JIT also available on ARM to use it for on mobile platforms and also Windows 10 IoT Core, where speed improvements are even more crucial. Unfortunately, the current public API does not provide us everything we need, for instance flushing cache lines is not supported. Once those items are public, we can continue on topic and we will keep you updated. You can also watch the WIP in the meanwhile.

Qt 5.8 is already shaping up with feature freeze approaching in less than a month. Hence I would like to summarize a couple of items we have been working on for this release.

Again, we validated the reports for WinRT with the highest votes to get an understanding what is most important for users and customers. From that list Qt 5.8 will add support for BTLE and Qt Purchasing to publish applications in the Windows Store using In App Products.

Qt Speech will be part of Qt 5.8 as a tech preview module, including support for WinRT using the Speech Synthesizer API.

Lastly, you might have read about our efforts to decouple the hard dependency of Qt Quick on OpenGL and providing additional backends. Laszlo has been doing an incredible job adding a D3D12 backend, which will also work for WinRT. For more information, you can read the snapshot documentation.

Platform Ammendment

Windows 10 IoT Core / Professional

Microsoft has introduced a new line of embedded operating systems called Windows 10 IoT. This is based on the Windows 10 architecture and comes with a limited feature set tailored towards embedded use-cases. For instance, no window manager / compositor is supported, only one application is supposed to show full screen. There are images available for various embedded devices, like the Raspberry Pi or the Dragonboard 410c, but the user experience might vary heavily depending on the snapshot of the image and its driver status. There is no graphics acceleration for the Raspberry Pi, causing Qt for WinRT to use the WARP software renderer with fairly bad fps rendering and a broken user experience. The Dragonboard has graphics acceleration and visually it is way more appealing, but you might experience troubles in other areas.

Microsoft Hololens

Unfortunately, we did not have the chance yet to experiment with the Hololens physically. But there are emulator images available and according from our experience using those, Qt does run on the Hololens. When publishing your app to the Store you can select the Hololens as an additional target to deploy to. In case you have experience with Qt on this device, feel free to get in touch with us.

XBOX One

The XBOX One will be opened towards 3rd party developers in one of its upcoming releases. Developers are already capable of setting the console into development mode and start coding on it. Using Qt for WinRT you will be able to develop Qt applications for the XBOX One and, once enabled, push those to the Store. From our experience input handling is not working to our fullest satisfaction, but we will work on this in the nearer future.

 

Moving further into the future there a lot of items we would like to do for the WinRT port, but we also need your feedback on what is important for developers. Hence I would like to ask every developer on this platform to vote and/or create items on our bugtracker. For easier tracking, all WinRT related items have QtPorts:WinRT as component.

The post Status Update on Qt for WinRT / UWP appeared first on Qt Blog.

Aligning with the Yocto Project

We have leveraged Yocto internally for many years to build our reference “Boot to Qt” embedded Linux stack of Qt for Device Creation. During 2015 we started to align our work with upstream Yocto Project, including contributions to improve the meta-qt5 layer. With Qt 5.7 we have also opened our meta-boot2qt layer in order to make it easier to co-operate with semiconductor vendors, open-source community as well as the customers using Qt for Device Creation.

The Yocto Project is an open source collaboration project that provides templates, tools and methods to help create custom Linux-based systems for embedded products regardless of the hardware architecture. The Yocto project is derived from the OpenEmbedded project and it shares core part of the metadata, recipes and tools with OpenEmbedded. The reference distribution of the Yocto Project is called Poky. It contains the OpenEmbedded Build System (BitBake and OpenEmbedded Core) as well as a set of metadata to get you started building your own distro. In addition there are available lot of metalayers which variate the core layers and add additional components, configurations and rule scripts for creating vendor specific distributions. Goal of the Yocto Project is to de-mystify the art of making embedded Linux distributions, helping both the technology providers to co-operate more efficiently and the device makers to better manage the exact distribution they have in their device.

The Qt Company is now proudly also an official Yocto Project Participant:

Yocto_Project_Badge_Participant_Web_RGB

For the past year we have been actively working together with meta-qt5, the Yocto compatible meta layer dedicated for building Qt modules for your embedded devices. The layer was also recently updated to provide recipes for the previously commercial modules (Qt Virtual Keyboard, Qt Charts and Qt Data Visualization), which are now open source in Qt 5.7. We have offered Yocto based reference images since Qt 5.1, and we released our first reference images based on meta-qt5 with Qt for Device Creation 5.6.0 and continue the work with the latest 5.7.0 release. The 5.7.0 release is based on Yocto 2.0 (Jethro), and idea is to update the Yocto release version for each minor Qt version, when suitable stable release is available. In order to provide support for the latest version of Qt, we have a mirror of meta-qt5 in the Qt Project repository. We do work upstream as much as possible, and are also welcome to host the upstream meta-qt5 repository under the Qt Project (currently it is in github).

Since the meta-qt5 layer provides only recipes for building the Qt modules, we have created a separate Boot to Qt meta layer, meta-boot2qt, which takes care of building the images and toolchains for the reference devices. The meta-boot2qt layer integrates all the required BSP meta layers, so there is no manual configurations necessary when starting Yocto build for one of the Qt reference devices. The layer was previously available only for our commercial customers, but with Qt 5.7 we have open sourced it as well. To get started with meta-boot2qt, clone the repository for meta-boot2qt and follow the instructions of building your own embedded Linux image in the Qt documentation.

Currently Qt for Device Creation and the meta-boot2qt layer contains support for many commonly available development boards and production hardware:

  • Raspberry Pi (raspberrypi)
  • Raspberry Pi 2 (raspberrypi2)
  • Raspberry Pi 3 (raspberrypi3)
  • BeagleBone Black (beaglebone)
  • Boundary Devices (i.MX6 Boards nitrogen6x)
  • Freescale SABRE SD (i.MX6Quad imx6qsabresd)
  • Freescale SABRE SD (i.MX6Dual imx6dlsabresd)
  • Toradex Apalis iMX6 (apalis-imx6)
  • Toradex Colibri iMX6 (colibri-imx6)
  • Toradex Colibri VF (colibri-vf)
  • Kontron SMARC-sAMX6i (smarc-smax6i)
  • Intel NUC (intel-corei7-64)
  • NVIDIA DRIVE CX (tegra-t18x)
  • Qt for Device Creation Emulator (emulator)

Qt works with much wider variety of hardware than we have as reference devices, so if your hardware is not listed it does not mean it can’t be used. We are offering convinient pre-built binaries for the reference devices as part of the Qt for Device Creation installer. With the Yocto tooling it is easy to take these as a starting point and tune the image according to your specific needs. If you do not yet have Qt for Device Creation, please ask and we’ll provide you with a free evaluation. If you need help with Yocto or other things, please contact us or one of the official Qt Partners to get a boost into your embedded development.

 

The post Aligning with the Yocto Project appeared first on Qt Blog.

Intents with Qt for Android, part 1

by Eskil Abrahamsen Blomfeldt (Qt Blog)

The “intent” is the main facility for interprocess communication on Android. Basically, an intent is an object that is processed by the operating system and then passed to one or more of the installed applications based on its contents. It could for instance be a request to show a video, in which case the intent type would be ACTION_VIEW and the mime type would be set accordingly. Applications can subscribe to certain intents by setting an intent filter in their manifest files. The first time a type of intent is seen, the user of the device will be presented with a selection of applications known to subscribe to that type of intent. If they choose, they can set a default at this point, or select to be asked for every instance.

This is the first of a few articles showing how to use intents with Qt for Android.

The mechanism itself is quite general. What is described above is one use case, but intents are also used for other things: One such thing is launching services inside the application. This is usually formatted as an “explicit intent”, meaning that the fully qualified name of the service to start is provided, so it cannot be intercepted by any other applications.

Another way intents are used is for broadcasts, for instance when the time zone of the device changes. While the action to view a video described above would only launch the one specific application selected by the user, a broadcast will rather be passed to any application which subscribes to it.

This blog will focus on Android, but a similar mechanism called app extensions was introduced in iOS 8.

In this first article about intents on Android, I will focus on the simplest use case: Creating an implicit intent from Qt to start an unspecified application on the target device. As an example, I have made a simple application which presents food recipes. Each recipe has an estimated time for completion. By clicking a button, you can set a timer using the preferred countdown application on the device. (For a more useful use case, one might imagine a button setting a timer for each of the steps in the recipe’s directions, but for this simple example we will only have a single timer per recipe.)

I won’t go into detail about how the application itself is written, but the code can be found here. No effort has been made to make the UI look nice, so please disregard that. The application is backed by an SQLite database (which is filled with some dummy content the first time the application is started) and has a very simple UI written in Qt Quick Controls 2, allowing the user to select a recipe from a list, see its details on a separate page and click a button on the recipe to set a timer in the system.

Picture of recipe

The part we will focus on is the code that actually requests the timer from the system. This is in the recipe.cpp file, in the function Recipe::createTimer(). For our example we will be using the AlarmClock.ACTION_SET_TIMER intent type.

We will use the JNI convenience APIs in the Qt Android Extras module for this. I will go through this code step by step.

    QAndroidJniObject ACTION_SET_TIMER = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                          "ACTION_SET_TIMER");
    QAndroidJniObject intent("android/content/Intent",
                             "(Ljava/lang/String;)V",
                             ACTION_SET_TIMER.object());

The first step is to create the intent. We retrieve the identifier of the ACTION_SET_TIMER intent. This is a static member of the android.provider.AlarmClock class and is of type String. Note the use of slashes in place of dots in the package name of the class. This corresponds to the bytecode representation of package names (for historical reasons according to the specification) and is therefore also used in signatures in JNI.

Since we are only using functions from Qt Android Extras and no explicit calls using the JNI APIs, we don’t have to worry about reference management. This is one primary convenience of the APIs.

The next step is to actually create the intent object. We do this by constructing a QAndroidJniObject, passing in the JNI-mangled signature of the Java constructor we want to call and we pass in the ID of the action we just got from the AlarmClock class.

    QAndroidJniObject EXTRA_MESSAGE = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                       "EXTRA_MESSAGE");
    QAndroidJniObject messageObject = QAndroidJniObject::fromString(message);
    intent.callObjectMethod("putExtra",
                            "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
                            EXTRA_MESSAGE.object(),
                            messageObject.object());

    QAndroidJniObject EXTRA_LENGTH = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                      "EXTRA_LENGTH");
    intent.callObjectMethod("putExtra",
                            "(Ljava/lang/String;I)Landroid/content/Intent;",
                            EXTRA_LENGTH.object(),
                            jint(m_time * 60));

    QAndroidJniObject EXTRA_SKIP_UI = QAndroidJniObject::getStaticObjectField("android/provider/AlarmClock",
                                                                                      "EXTRA_SKIP_UI");
    intent.callObjectMethod("putExtra",
                            "(Ljava/lang/String;Z)Landroid/content/Intent;",
                            EXTRA_SKIP_UI.object(),
                            jboolean(true));

Next up, we set up some arguments we want to send to the activity handling the action. We pass in a description of the timer and the number of seconds to set it for.

    QAndroidJniObject activity = QtAndroid::androidActivity();
    QAndroidJniObject packageManager = activity.callObjectMethod("getPackageManager",
                                                                 "()Landroid/content/pm/PackageManager;");
    QAndroidJniObject componentName = intent.callObjectMethod("resolveActivity",
                                                              "(Landroid/content/pm/PackageManager;)Landroid/content/ComponentName;",
                                                              packageManager.object());

Then we have to resolve the activity. This will tell the system to check if there is an application available to handle the ACTION_SET_TIMER action. We first get a reference to the current activity (our current context) in order to get the appropriate package manager. Then we call resolveActivity() on the intent and pass in the package manager.

    if (componentName.isValid()) {
        QtAndroid::startActivity(intent, 0);
    } else {
        qWarning() << "Unable to resolve activity";
    }

If the returned component name is non-null, we start the activity using the convenience function in Qt Android Extras. We will look at more features of this function in a later blog. If no appropriate activity is found, then this code only outputs a warning to the console. A proper application might complain in the actual user interface, but note that the operating system has also alerted the user of the problem at this point.

Screenshot of alarm that has been set

That’s it for this first introduction to using intents in Qt for Android. Look out for more complex examples in the future.

The post Intents with Qt for Android, part 1 appeared first on Qt Blog.

Tap, Tinder and Touchscreens: How Swipe Can Improve the User Experience

Tap is the safest touch gesture. Everyone understands that tap equals click. On a touchscreen, you tap where you would have pointed and clicked on a mouse-enabled display. Tap is a simple, deliberate gesture. The presence of a button-like element is indication enough that it can be tapped, and will likely mean yes or no, save or cancel, choose this thing or navigate to this new place.

Over-the-Air Updates, Part 2: Device Integration, API and Creating Updates

With Qt 5.7 for Device Creation we introduced a new piece of technology – an OSTree-based solution for Over-the-Air software updates for the whole software stack. For a more detailed introduction about this new component of the Boot to Qt software stack, read part one of the blog post series. This blog post contains a step-by-step guide on how to add OTA update capability to your Boot to Qt device, discusses Qt OTA API and finally demonstrates how to generate OTA updates for shipped devices.

Device Selection.

For this tutorial we are going to use the Intel NUC board – a new reference device in Qt 5.7 for Device Creation. Intel NUC is a low-cost, pint-sized powerhouse solution for a wide variety of fields, including Internet of Things where OTA update capability is especially desired. I chose this board for the tutorial because it is not your traditional ARM-based embedded Linux board that uses the U-Boot bootloader. Instead, Intel NUC is a x86-64 target with the GRUB 2 bootloader. The OTA solution in Technology Preview supports U-Boot and GRUB 2 bootloaders, and adding support for additional bootloaders is a straightforward task (as long as a bootloader has the means to read from an external configuration file).

Device Integration Steps.

I won’t go into too much detail at each step, as that is already covered in the OTA documentation. The goal of this tutorial is to show the necessary steps to add OTA capability to a device and to demonstrate that it doesn’t require months of effort to add such a capability. Rather, it takes just a few hours when using the OTA solution from Qt for Device Creation.

1. Generate OSTree boot compatible initramfs image.

This step requires booting the device with the sysroot to be released, so that the tool can generate initramfs that match the kernel version of the release. The device has to be connected to the machine from which you will run the generate-initramfs tool:

SDK_INSTALL_DIR/Tools/ota/dracut/generate-initramfs

2. Bootloader integration.

This is the only step that requires manual work. The bootscript used by your device has to be changed to use the configurations that are managed by OSTree. This will ensure that, after OTA updates or rollbacks, the correct kernel version (and corresponding boot files) will be selected at boot time. On U-Boot systems this requires sourcing uEnv.txt and then integrating the imported environment with the bootscript. On GRUB 2 systems, whenever the bootloader configuration files need to be updated, OSTree executes the ostree-grub-generator shell script to convert bootloader-independent configuration files into native grub.cfg format. A default ostree-grub-generator script can be found in the following path:

SDK_INSTALL_DIR/Tools/ota/qt-ostree/ostree-grub-generator

This script should be sufficient for most use cases, but feel free to modify it. The ostree-grub-generator file contains additional details. The script itself is about 40 lines long.

3. Convert your sysroot into an OTA enabled sysroot.

The conversion is done using the qt-ostree tool.

sudo ./qt-ostree \
--sysroot-image-path ${PATH_TO_SYSROOT} \
--create-ota-sysroot \
--ota-json ${OTA_METADATA} \
--initramfs ../dracut/initramfs-${device}-${release} \
--grub2-cfg-generator ${CUSTOM_GENERATOR}

This script will do all the necessary work to convert your sysroot into an OTA enabled sysroot. The ${OTA_METADATA} is a JSON file containing the system’s metadata. The following top-level fields have convenience methods in the Qt/QML OTA API: version and description. The API provides the means of manually fetching and parsing the file (which consequently can contain arbitrary metadata describing the sysroot).

4. Deploy the generated OTA image to an SD card.

sudo dd bs=4M if=<image> of=/dev/<device_name> && sync

5. Test that everything went according to plan.

Boot from the SD card and run the following command from the device:

ostree admin status

The output should be something similar to:

* qt-os 36524faa47e33da9dbded2ff99d1df47b3734427b94c8a11e062314ed31442a7.0
origin refspec: qt-os:linux/qt

Congratulations! Now the device can perform full system updates via a wireless network. Updates and rollbacks are atomic and the update process can safely be interrupted without leaving the system in an inconsistent state. If an update did not fully complete, for example due to a power failure, the device will boot into an unmodified system. Read about the other features of the update system in the OTA documentation.

User Space Integration.

With the device being OTA capable, we need to take advantage of that. We provide C++ / QML APIs to make OTA update functionality integration with Qt-based applications a breeze. Offline operations include querying the booted and rollback system version details and atomically performing the rollbacks. Online operations include fetching a new system version from a remote server and atomically performing system updates. A basic example that demonstrates the API:

Label { text: "CLIENT:"; }
Label { text: "Version: " + OTAClient.clientVersion }
Label { text: "Description: " + OTAClient.clientDescription }
Label { text: "Revision: " + OTAClient.clientRevision }

Label { text: "SERVER:"; }
Label { text: "Version: " + OTAClient.serverVersion }
Label { text: "Description: " + OTAClient.serverDescription }
Label { text: "Revision: " + OTAClient.serverRevision }

Label { text: "ROLLBACK:"; }
Label { text: "Version: " + OTAClient.rollbackVersion }
Label { text: "Description: " + OTAClient.rollbackDescription }
Label { text: "Revision: " + OTAClient.rollbackRevision }

RowLayout {
    Button {
        text: "Fetch OTA info"
        onClicked: OTAClient.fetchServerInfo()
    }
    Button {
        visible: OTAClient.rollbackAvailable
        text: "Rollback"
        onClicked: OTAClient.rollback()
    }
    Button {
        visible: OTAClient.updateAvailable
        text: "Update"
        onClicked: OTAClient.update()
    }
    Button {
        visible: OTAClient.restartRequired
        text: "Restart"
        onClicked: log("Restarting...")
    }
}

The above sample presents version information for the booted and rollback system, as well as what system version is available on a remote server. The sample program also contains buttons to initiate OTA tasks. The code below is used for logging OTA events. The API is still in Technology Preview, so the final version might have slight changes.

Connections {
    target: OTAClient
    onErrorChanged: log(error)
    onStatusChanged: log(status)
    onInitializationFinished: log("Initialization " + (OTAClient.initialized ? "finished" : "failed"))
    onFetchServerInfoFinished: {
        log("FetchServerInfo " + (success ? "finished" : "failed"))
        if (success)
            log("Update available: " + OTAClient.updateAvailable)
    }
    onRollbackFinished: log("Rollback " + (success ? "finished" : "failed"))
    onUpdateFinished: log("Update " + (success ? "finished" : "failed"))
}

This API could easily be used to write a daemon that communicates its version details to the server and the daemon could send a notification to the user when an update becomes available. The server could send out updates in batches, first updating a small subset of devices for field testing, fetching update statuses from daemons and if there are no issues, update the remaining devices. Some tools for this type of tasks are in the roadmap of OTA solution for the Boot to Qt stack.

Ship it! Some time later … a critical bug emerges.

As we took a precaution and built an embedded device with OTA capability as well as creating a Qt application for handling updates, there are only few simple steps to follow to resolve the issue.

1. Fix the bug.

I will leave the details up to you 😉 We will use the updated sysroot in the next step.

2. Generate an update.

This is done by using the qt-ostree tool. Generating an OTA update is a completely automated task.

sudo ./qt-ostree \
--sysroot-image-path ${PATH_TO_SYSROOT_WITH_THE_FIX} \
--ota-json ${OTA_METADATA_DESCRIBING_NEW_SYSROOT} \
--initramfs ../dracut/initramfs-${device}-${release}

The above command will create a new commit in the OSTree repository at WORKDIR/ostree-repo/, or create a new repository if one does not exist. This repository is the OTA update and can be exported to a production server at any time. OSTree repositories can be served via a static HTTP server (more on this in the next blog post).

3. Use Qt OTA API to update devices.

It is up to system builders to choose an update strategy.

Availability

The Boot to Qt project leverages The Yocto Project to built its own distribution layer called meta-boot2qt. The Boot to Qt distribution combines the vendor specific BSP layers and meta-qt5 into one package. This distribution is optimized to make the integration with the OTA tooling as simple as possible. All source code is available under commercial and GPL licenses.

Conclusion

Enabling the OTA update feature on Boot to Qt devices is a quick and worthwhile task. With OTA enabled devices you can ship your products early and provide more features later on. In the next blog post I will write about OSTree (OTA update) repository handling, remote configuration and security.

The post Over-the-Air Updates, Part 2: Device Integration, API and Creating Updates appeared first on Qt Blog.

Qt Certification

It has been possible to attend a Qt certification exam and become a Certified Qt Developer or Qt Specialist since 2009. Now the exams and certifications have been updated to cover the latest Qt features. In order to support providers of quality Qt training and ease developers’ preparation for the exams, we are also launching a Qt training partner program.

Developer Certificate

There are three kinds of exams as before: Qt and QML Essentials, Widget UI and Application Engine with Qt, and Qt Quick UI. Candidates, passing the essentials exam, are given the Certified Qt and QML Developer statuses. Compared to the previous essentials exam, basic knowledge of QML, such as elements, layouts, and user interactions, are required in the updated version. After the essentials exam, candidates may choose to become a Certified Qt C++ Specialist or Certified Qt Quick Specialist or even both. To become a Qt C++ Specialist, a candidate needs to pass the Widget UI and Application Engine with Qt exam, which tests the candidate’s knowledge about threading, databases, XML and JSON, networking, and model/view framework in addition to widgets. In a similar way, the Qt Quick UI exam tests the attendee’s knowledge about several Qt Quick and QML modules, such as Qt Quick Controls, particle system, multimedia, custom modules and new Qt Quick types. The exact curriculums are available at https://www.qt.io/qt-certification/.

In each exam, the candidates have 60 minutes to answer a number of multiple choice questions. The essentials exam consists of 50 questions, from which 31 must be correctly answered to pass the exam. Advanced exams contain 30 questions, from which 16 must be answered correctly. Coding is not required, but many questions contain a code snippet, which must be understood to pick up the correct answer or answers. Exams can be attended in any Pearson VUE authorized test center around the world. The details of test center locations and instructions how to make an appointment and attend an exam can be found at http://www.pearsonvue.com/qtcompany/. The exam price varies from test center to test center, so the exact price should be asked directly from the test center.

Certified Developers and Specialist will receive a printed certificate with 2-4 weeks after the exam.

The best way to prepare for the exams is, besides to write Qt programs covering all the curriculum topics, to attend a Qt training course. The Qt Company are now launching a Qt training partner program, where we make up-to-date training material available to providers of Qt training. All training under the program will be done by qualified trainers. Qt courses for open enrollment will be advertised on our web site: http://www.qt.io/qt-training/. Our hope is that over time this program will benefit Qt developers everywhere.

Good luck with your preparations and with your exams!

The post Qt Certification appeared first on Qt Blog.

An Introduction to Python Part 3

In this, the final installment of the blog series on Python, we'll look at modules and how object-oriented programming is supported. We'll take a brief look at two of the popular bindings for Qt from Python: PyQt and PySide. I'll wrap things up with some tips for effective programming and references for learning more.

Modules

Python includes a set of standard libraries, divided into packages and modules.

Enabling Connectivity in Your Embedded Product

by Sebastien Ronsse, Adeneo Embedded [Qt Service Partner] (Qt Blog)

Building embedded products today, regardless of the targeted market, not only involves creating a nice, user-friendly interface, but often requires interoperability and connectivity. Mixing web technologies with native content has come a long way and can now easily produce attractive and powerful applications.

When bringing connectivity to embedded products, some existing web technologies can be paired with a framework, such as Qt, to create best-in-class applications.

HTML5 technology is now standardized, well adapted for touch-screen navigation, and mature enough to run on embedded devices. Qt offers support for this through its WebEngine web content rendering engine based on Chromium. Mixed content is also possible, allowing users to write a typical application using QML and have dedicated HTML5 content as part of the solution.

Mobile and remote access

If there is a requirement to remotely access a device while providing the same or at least a subset of the embedded user interface, this is possible using HTML5 content within a Qt application. The result is that a team can develop and design an interface once and have it available on a myriad of devices.

Adeneo has used the i.MX6 SoloX to demonstrate this concept: an accelerometer sensor is sampled and an HTML5 graph displaying the different acceleration components is rendered within a Qt application. That same graph is also advertised remotely, accessible from any browser, allowing real-time view via tablets, mobile phones, regular computers or even other embedded devices.

Taking advantage of node.js

Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript and, when paired with other frameworks such as MongoDB, Express.js, and Angular.js, it provides a powerful, lightweight, and proven web stack. If you are interested in linking your embedded product with the Cloud, node.js is a popular cross-platform choice and is backed by services such as Microsoft Azure and Amazon AWS.

Qt can also be combined with 3D rendering techniques using technologies such as OpenGLES. A favorite example of mine is the Heart Rate Monitor demonstration Adeneo developed on the Renesas RZ/G1E Starter Kit, showing a real-time 3D model of a heart rendered with advanced shaders on the platform using Qt 5.4. This application works jointly with a node.js backend, and displays the heart rate pulse via HTML5 to clients connected to the device remotely through Web Sockets. This illustrates how Qt can easily be used in conjunction with such technologies, helping to create an all-in-one connected solution.

The latest flavors of Qt provide an optimized web engine and web view tandem. This provides developers with a cross-platform, all-in-one solution for building advanced web applications with minimal risk and development time. Producing hybrid applications is made possible through integration between these web-oriented components and the QML language, which can significantly reduce overall project costs as well as simplifying development.

Learn more about Adeneo’s Qt expertise here: http://www.adeneo-embedded.com/OS-Technologies/Qt

The post Enabling Connectivity in Your Embedded Product appeared first on Qt Blog.

What You Need to Know about the GNU LGPL

Qt 5.7 was released last week and as discussed in the release blog post, it is the first release that follows the new open source licensing scheme where we’ve unified the Qt for Application Development offering but also upgraded the LGPLv2.1 license to LGPLv3.

Qt has been available under LGPL for several years, and the license issues are naturally complex ones. To help you understand the obligations of the LGPLv3, we would like to introduce you this video done by Dr. Till Jaeger from JBB Rechtsanwälte, a recognized international legal expert on open source issues. The video goes through the background information about the GNU LGPLv3 and then addresses the separate rights you have under the LGPLv3.

In addition, to make the correct licensing choice, you can also take a look at our licensing pages, the licensing FAQ or the licensing comparison table at our web page.

Hope you find the video useful and enjoy Qt 5.7!

The post What You Need to Know about the GNU LGPL appeared first on Qt Blog.

Qt 5.6.1-1 Released

We have today released Qt 5.6.1-1, which fixes a critical problem in Qt 5.6.1 preventing certain type of Qt Quick applications from working properly. I am very sorry for the inconvenience, but those who have already downloaded Qt 5.6.1 now need to get the new Qt 5.6.1-1 release. The problem is already fixed in the Qt 5.7.0 released last week.

The problem with Qt 5.6.1, reported in QTBUG-53761, is that certain Qt Quick applications crash after some time. The problem occurs with code that loads more than 64 components (.qml or .js files) without instantiating objects from all of them. The components that initially don’t get instantiated will then be removed from the type cache, which causes problems if you later try to instantiate objects from them. Reason for the problem is too aggressive trimming of the QML type cache, which ends up deleting some QML types even though they were still in use by the application.

This bug was noticed and fixed just slightly too late for Qt 5.6.1 with https://codereview.qt-project.org/#/c/161888. It got into the 5.6 branch as well as into Qt 5.7.0 release last week. Furthermore, as the bug was a bit difficult one to diagnose, it was initially slightly misdiagnosed resulting it to be P1, not P0 as it should have been.

If you are using the online installer, Qt 5.6.1-1 can be updated using the maintenance tool. Offline packages are available for commercial users in the Qt Account portal and at the qt.io Download page for open-source users.

 

 

The post Qt 5.6.1-1 Released appeared first on Qt Blog.

Qt on Android: How to restart your application

Some time ago, I wrote a code to restart the running application on Android.

You might well ask why such a thing was needed. It was needed because there are cases where, whenever a user changes the theme, the application has to restart to apply the change (it can’t be applied on the fly). In my example I used it to restart Qt Quick Controls 2 gallery.

Sadly my fix was not accepted, because other platforms (iOS, IIRC) have this missing feature too, so it was decided to remove Android code so it didn’t stand out.

Anyway, because I think this piece of code might help other people, I’m going to share it with you today.

Our goal is to use AlarmManager.set() method to set an alarm (a PendingIntent) that will start our application in the near future (in our case 100ms from now), then quits the application. When the alarm timeouts it will start our application. Be aware that the AlarmManager is anything but accurate, so it might take more than 100ms to restart the application (in some cases it takes up to 5s to restart it).

Here is the code that does all the magic:

auto activity = QtAndroid::androidActivity();
auto packageManager = activity.callObjectMethod("getPackageManager",
                                                "()Landroid/content/pm/PackageManager;");

auto activityIntent = packageManager.callObjectMethod("getLaunchIntentForPackage",
                                                      "(Ljava/lang/String;)Landroid/content/Intent;",
                                                      activity.callObjectMethod("getPackageName",
                                                      "()Ljava/lang/String;").object());

auto pendingIntent = QAndroidJniObject::callStaticObjectMethod("android/app/PendingIntent", "getActivity",
                                                               "(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;",
                                                               activity.object(), jint(0), activityIntent.object(),
                                                               QAndroidJniObject::getStaticField<jint>("android/content/Intent",
                                                                                                       "FLAG_ACTIVITY_CLEAR_TOP"));

auto alarmManager = activity.callObjectMethod("getSystemService",
                                              "(Ljava/lang/String;)Ljava/lang/Object;",
                                              QAndroidJniObject::getStaticObjectField("android/content/Context",
                                                                                      "ALARM_SERVICE",
                                                                                      "Ljava/lang/String;").object());

alarmManager.callMethod<void>("set",
                              "(IJLandroid/app/PendingIntent;)V",
                              QAndroidJniObject::getStaticField<jint>("android/app/AlarmManager", "RTC"),
                              jlong(QDateTime::currentMSecsSinceEpoch() + 100), pendingIntent.object());

qApp->quit();

Let’s have a closer look to the code:

  • 1st line gets the activity packageManager object.
  • 2nd line gets an activityIntent object using the packageManager. getPackageName() method returns the name of this application’s package name.
  • 3rd line gets a pendingIntent needed to restart our application.
  • 4th line gets the alarmManager
  • 5th line sets the pendingIntent to start 100 milliseconds from now.
  • 6th line quits the application

The post Qt on Android: How to restart your application appeared first on KDAB.

Adding Live Translation to BlackBerry 10 C++ Code

MartinGreen

Editor:  Today we have a guest post from Martin Green.  Martin spent nearly a decade repairing marine navigational equipment on “Lakers” and “Salties”, such as RADAR, Loran C, gyrocompasses, and early SatNav, followed by twenty-five years as a contract Enterprise software developer for governments, banks, and major corporations before coming to mobile and BlackBerry 10 Native development in early 2013. He is the owner of arsMOBILIS and the developer of multiFEED, an RSS/Atom reader app available in BlackBerry World.

If you have built (or are building) your BlackBerry 10 Native Cascades apps with internationalization in mind then you likely have code peppered with QML qsTr() calls and C++ tr() macros. When your app starts up the text wrapped in qsTr() or tr() is substituted with the localized text for the device locale and language (if defined, otherwise default translation is used). This works fine unless you change the language setting on your device while your app is running. Unless you take steps to propagate the language change through your live app, the text displayed in your UI will not match the new device language setting until the page is reloaded or your app is restarted. QML provides for this “live translation” with the Retranslate class which can be used with qsTr() to update translations as soon the device language setting is changed:

Page {
    Container {
        Label {
         id: label01

         // ---This label's text will be live translated
         text: qsTr("Label 1") + Retranslate.onLanguageChanged
      }
      Label {
         id: label02

         // ---This label's text will be static translated
         text: qsTr("Label 2")
      }
   }
}

In this example label01 will have its text attribute live translated so that it is updated as soon as the device language is changed. On the other hand label02 will only have its text translated when the app is first started and subsequent language changes while the app is running will not update it.

Using the Retranslate class with QML makes live translation as simple as adding a small amount of code right after every use of qsTr(), but C++ provides no such convenience. To implement live translation in C++ code it is necessary to call the setXXX() slot for a string attribute with the tr() macro once to do the initial translation then connect the setXXX() slot to a LocaleHandler instance which emits a signal every time the language (or locale) changes. This is complicated by the fact that the LocaleHandler knows that the language has changed, but it doesn’t know which text key to supply to the slots it is attached to so we have to attach the LocaleHandler signal to an intermediary slot which knows what translation key to use for that attribute and which then emits another signal with the key as a parameter which must be connected to the control setXXX() slot. This means that for every single control attribute you want to live translate you will need a separate intermediary slot defined somewhere, a related signal for that slot with a QString argument, and two QObject::connect() calls. For every attribute we want to live translate. Obviously this gets very ugly, very fast.

I prefer to use C++ with little or no QML to lay out my app pages so I was determined to find a solution which was as easy to use as Retranslate in QML (or nearly so) and after some trial and error I came up with a solution I’m very happy with, which I called LiveTranslator. The core of this technique is a new C++ class called LiveTranslator. The usage syntax is a little more complicated than using QML Retranslate, but like Retranslate you only need to add one line of code for each attribute you want live translation on. Here is the header for LiveTranslator:

#ifndef LIVETRANSLATOR_HPP_
#define LIVETRANSLATOR_HPP_

#include <bb/cascades/LocaleHandler>

using namespace bb::cascades;

class LiveTranslator: public QObject {
    Q_OBJECT

    QString _key;
    QString _context;

    static LocaleHandler* _localeHandler;

public:
    LiveTranslator( const QString& context,
            const QString& key,
            QObject* target,
            const char* slot );

    static void setLocaleHandler( LocaleHandler* localeHandler );

private slots:
    void localeOrLanguageChangedHandler();

signals:
    void translate( const QString& string );
};

#endif /* LIVETRANSLATOR_HPP_ */

…and the body…

#include "LiveTranslator.hpp"

/* ---Initialize the locale handler pointer on app startup so we can tell if it
has been set properly later */
LocaleHandler* LiveTranslator::_localeHandler = 0;

/* ---Note that the target control is also used as the parent so the live translator dies when the control does */
LiveTranslator::LiveTranslator( const QString& context,
        const QString& key,
        QObject* target,
        const char* slot ) :  QObject( target ) {

    bool success;
    Q_UNUSED( success );

    // ---Save the context and key string
    this->_key = key;
    this->_context = context;

    // ---Die (during debug) if locale handler wasn't set properly before use
    Q_ASSERT( LiveTranslator::_localeHandler );

    // ---Watch for locale or language changes
    success = QObject::connect(
        LiveTranslator::_localeHandler,
        SIGNAL( localeOrLanguageChanged() ),
        SLOT( localeOrLanguageChangedHandler() )
    );
    Q_ASSERT( success );

    // ---Trigger specified slot when locale or language changes
    success = QObject::connect(
        this,
        SIGNAL( translate( const QString& ) ),
        target,
        slot
    );
    Q_ASSERT( success );
}

void LiveTranslator::localeOrLanguageChangedHandler() {
    /* ---Use the specified slot on the target to update the appropriate string
    attribute with the translated key */
    emit translate(
        QCoreApplication::translate(
            this->_context.toLocal8Bit().constData(),
            this->_key.toLocal8Bit().constData()
        )
    );
}

/* ---This function MUST be called once with a valid LocaleHandler before any
LiveTranslator classes are instantiated */
void LiveTranslator::setLocaleHandler( LocaleHandler* localeHandler ) {
    LiveTranslator::_localeHandler = localeHandler;
}

LiveTranslator encapsulates all the ugly stuff, including remembering the translation key, the intermediary slot/signal, and all signal/slot connections necessary for live translation. Using it is as simple as creating an instance of LiveTranslator, passing the constructor the translation key for the attribute (and the context, but more on that later), the target UI control, and the slot on that component that will accept the updated translation. Note that tr() only works with static key strings…

// ---This is valid
QString str1 = tr("string one");

// ---This is not!
Qstring str1 = "string one";
QString str2 = tr(str1);

…so rather than tr(), LiveTranslator must use QCoreApplication::translate() internally.

An example of LiveTranslator usage:

MyClass::MyClass() {
    Label* label = Label::create().text( tr("Label one") );
    new LiveTranslator( "MyClass", "Label one", label,
        SLOT(setText(const QString&)) );
    
    Option* option = Option::create().text( tr("Option one") )
        .description( tr("Option one description") );
    new LiveTranslator( "MyClass", "Option one", option,
        SLOT(setText(const QString&)));
    new LiveTranslator( "MyClass", "Option one description", option,
        SLOT(setDescription(const QString&)));
    
    ActionItem* actionItem = Option::create().title( tr("Action one") );
    new LiveTranslator( "MyClass", "Action one",
        actionItem, SLOT(setTitle(const QString&)));
}

Note that there is no need to save a reference to the new LiveTranslator instance since the constructor sets the “target” control as the parent. When the control is destroyed by your app the LiveTranslator will go with it. Also note that Momentics doesn’t know anything about LiveTranslator so you won’t be warned in the editor if the slot you provide is not valid. There is a Q_ASSERT in LiveTranslator though so you will know if the connection failed when testing your app in Debug mode.

The first parameter for the LiveTranslator constructor is the “context” where the translation key is located. When you use the tr() macro (or QML qsTr() function) the code parser makes note of where it found the key and stores it in the translation file along with the key. This way you could use the same translation key on different pages, and if the context is different you could have them translated differently. Again, the Index parser doesn’t know anything about the LiveTranslator class though so you have to tell it the context explicitly. For C++ the context is always the name of the class containing the code you are translating. Also, in case it isn’t obvious, the “key” parameter must be the same value as the one used with tr() on the line before it.

There is one thing you must do before using LiveTranslator in your C++ code and that is to give it a LocaleHandler to work with. Rather than force you to pass a LocaleHandler to every instance of LiveTranslator, you tell LiveTranslator which one to use just once with a static function call. If you created your app from one of the Momentics templates then you already have a handler you can use:

#include “LiveTranslator.hpp”

ApplicationUI::ApplicationUI() : QObject() {
    // prepare the localization
    m_pTranslator = new QTranslator( this );
    m_pLocaleHandler = new LocaleHandler( this );
    
    // Use this locale handler for all the live translations too
    LiveTranslator::setLocaleHandler( m_pLocaleHandler );

    ...
    ...
    ...
}

If all you care about live translating are normal UI components, then you have all you need now to easily implement live translation in your C++ code. If, however, you also want to have LiveTranslator work with certain system controls, such as SystemUiButton or SystemDialog you have a little more work ahead of you. The problem is that on these classes the attributes we would want to live translate are set with functions, not slots. This means that there is no way to tell LiveTranslator how to update the desired strings since it only works with Qt slots. The solution is quite simple though, all we need is to define a “helper” class for each system component type which can provide access to the setting function via slots. Here is a helper class for SystemUiButton

/*
 * SystemUIButtonTrxHlp.hpp
 *
 */

#ifndef SYSTEMUIBUTTONTRXHLP_HPP_
#define SYSTEMUIBUTTONTRXHLP_HPP_

#include <bb/system/SystemUiButton>

using namespace bb::system;

class SystemUiButtonTrxHlp: public QObject {
    Q_OBJECT

    SystemUiButton* _button;
public:
    SystemUiButtonTrxHlp( SystemUiButton* button );

public slots:
    void setLabel( const QString& label );
};

#endif /* SYSTEMUIBUTTONTRXHLP_HPP_ */

/*
 * SystemUiButtonTrxHlp.cpp
 *
*/

#include "SystemUiButtonTrxHlp.hpp"

SystemUiButtonTrxHlp::SystemUiButtonTrxHlp( SystemUiButton* button ) :
        QObject( button ) {
    this->_button = button;
}

void SystemUiButtonTrxHlp::setLabel( const QString& label ) {
    this->_button->setLabel( label );
       }

As with LiveTranslator the constructor automatically makes the target button the parent, so you can create an instance of the helper and forget it. Now a similar helper for SystemDialog

/*
 * SystemDialogTrxHlp.hpp
 *
*/

#ifndef SYSTEMDIALOGTRXHLP_HPP_
#define SYSTEMDIALOGTRXHLP_HPP_

#include <bb/system/SystemDialog>

using namespace bb::system;

class SystemDialogTrxHlp : public QObject {
    Q_OBJECT

    SystemDialog* _dialog;

public:
    SystemDialogTrxHlp( SystemDialog* dialog );

public slots:
    void setBody( const QString& text );
    void setRememberMeText( const QString& text );
    void setTitle( const QString& title );
};

#endif /* SYSTEMDIALOGTRXHLP_HPP_ */

/*
 * SystemDialogTrxHlp.cpp
 *
*/

#include "SystemDialogTrxHlp.hpp"

SystemDialogTrxHlp::SystemDialogTrxHlp( SystemDialog* dialog ) :
        QObject( dialog ) {
    this->_dialog = dialog;
}

void SystemDialogTrxHlp::setBody( const QString& title ) {
    this->_dialog->setBody( title );
}

void SystemDialogTrxHlp::setRememberMeText( const QString& text ) {
    this->_dialog->setRememberMeText( text );
}

void SystemDialogTrxHlp::setTitle( const QString& title ) {
    this->_dialog->setTitle( title );
}

Now let’s create a SystemDialog with live translation…

#include “SystemDialogTrxHlp.hpp”
#include “SystemUiButtonTrxHlp.hpp”

using namespace bb::system;

void MyClass::openDialog() {
    SystemDialog* dialog = new SystemDialog( tr(“Confirm Button”),
        tr(“Cancel Button”) );
    dialog->setTitle( tr(“Dialog Title”) );
    dialog->setBody( tr(“”Dialog Body”) );

    // ---Enable live translation
    new LiveTranslator( “MyClass”, “Dialog Title”, new SystemDialogTrxHlp( dialog ),
        SLOT(setTitle(const QString&)) );
    new LiveTranslator( “MyClass”, “Dialog Body”, new SystemDialogTrxHlp( dialog ),
        SLOT(setBody(const QString&)) );
    new LiveTranslator( “MyClass”, “Confirm Button”,
        new SystemUiButtonTrxHlp( dialog->confirmButton() ),
        SLOT(setLabel(const QString&)) );
    new LiveTranslator( “MyClass”, “Cancel Button”,
        new SystemUiButtonTrxHlp( dialog->cancelButton() ),
        SLOT(setLabel(const QString&)) );

    // ---Now for the magic ingredient
    bool success = QObject::connect( LiveTranslator::localeHandler(),
        SIGNAL(localeOrLanguageChanged()), dialog, SLOT(update()) );
    Q_UNUSED(success);
    Q_ASSERT(success);
}

Now for the bad news. See those few lines at the end of the function after the “magic ingredient” comment? Without them live translation of SystemDialog won’t work. Unlike regular UI components, SystemDialog and its brethren don’t automatically repaint themselves or their children when you change one of their attributes. Instead you make all the changes you want and then call or trigger the update() slot. The bad news? That function wasn’t added until the 10.2 API. This means that full live translation of system dialogs is not possible below that API level. I say “full” live translation because even with 10.0 and 10.1 if you leave SystemUiButton labels at their defaults or set them to one of the values that Cascades natively knows how to translate then those labels will be live translated with no additional effort by you. For instance, if you set the SystemDialog confirm button to read “Ok” or “Confirm” then Cascades will automatically add live translation of those words into any language you change your device to and you don’t even need to use the tr() macro when setting them. By carefully choosing your dialog title and body you might be able to get most of the way to live translation even with the lower API levels. Unfortunately, I don’t know of a list of button labels that Cascades can live translate natively so you might need a bit of trial and error. If there is any good news in this it’s that unlike regular screen elements, dialogs are transient entities so the lack of live translation is only evident for a moment. The next time your user opens a dialog, even the same one, it will be correctly translated into the new language.

I have provided the source files for LiveTranslator and some helper classes so all you need to do to get live translation working in your BlackBerry 10 Native C++ code is grab LiveTranslator from github and add it to your project (and any helpers you need too), add a call to LiveTranslator::setLocaleHandler() at the beginning of your main app class constructor and then call new LiveTranslator(…) with the appropriate parameters for each control attribute you want to be live translated. I leave it to the reader to create any additional helper classes they might need. I also created an example app that you can download and run without coding anything yourself. Note that this demo app includes code that live translates a SystemDialog so you must compile it with API 10.2 or better.

The Retranslate class makes it easy to perform live translations from QML, but Cascades does not provide a similar tool for C++ code. A few lightweight classes and extra lines of code bring similar functionality to C++, and best of all you don’t have to rewrite your app to take advantage of it. Just add one line of code for each UI component attribute you want to translate and the LiveTranslate class will take care of the rest.


Cutelyst 0.12.0 is out!

Cutelyst a web framework built with Qt is closer to have it's first stable release, with it becoming 3 years old at the end of the year I'm doing my best to finally iron it to get an API/ABI compromise, this release is full of cool stuff and a bunch of breaks which most of the time just require recompiling.

For the last 2-3 weeks I've been working hard to get most of it unit tested, the Core behavior is now extensively tested with more than 200 tests. This has already proven it's benefits resulting in improved and fixed code.

Continuous integration got broader runs with gcc and clang on both OSX and Linux (Travis) and with MSVC 12 and 14 on Windows (Appveyor), luckily most of the features I wanted where implemented but the compiler is pretty upsetting. Running Cutelyst on Windows would require uwsgi which can be built with MinGW but it's in experimental state, the developer HTTP engine, is not production ready so Windows usefulness is limited at the moment.

One of the 'hypes' of the moment is non-blocking web servers, and this release also fixes this so that uwsgi --async <number_of_requests> is properly handled, of course there is no magic, if you enable this on blocking code the requests will still have to wait your blocking task to finish, but there are many benefits of using this if you have non-blocking code. At the moment once a slot is called to process the request and say you want to do a GET on some webservice you can use the QNetworkAccessManager do your call and create a local QEventLoop so once the QNetworkReply finish() is emitted you continue processing. Hopefully some day QtSql module will have an async API but you can of course create a Thread Queue.

A new plugin called StatusMessage was also introduced which generates an ID which you will use when redirecting to some other page and the message is only displayed once, and doesn't suffer from those flash race conditions.

The upload parser for Content-Type  multipart/form-data got a huge boost in performance as it now uses QByteArrayMatcher to find boundaries, the bigger the upload the more apparent is the change.

Chunked responses also got several fixes and one great improvement which will allow to use it with classes like QXmlStreamWriter by just passing the Response class (which is now a QIODevice) to it's constructor or setDevice(), on the first write the HTTP headers are sent and it will start creating chunks, for some reason this doesn't work when using uwsgi protocol behind Nginx, I still need to dig and maybe disable the chunks markup depending on the protocol used by uwsgi.

A Pagination class is also available to easy the work needed to write pagination, with methods to set the proper LIMIT and OFFSET on Sql queries.

Benchmarks for the TechEmpower framework were written and will be available on Round 14.

Last but not least there is now a QtCreator integration, which allows for creating a new project and Controller classes, but you need to manually copy (or link) the qtcreator directory to ~/.config/QtProject/qtcreator/templates/wizard.

cutelyst-qtwiz

As usual many bug fixes are in.

Help is welcome, you can mail me or hang on #cutelyst at freenode.

Download here.

In Automotive Retailing UX Rubber Hits the CX Road

A popular concept these days is User Experience or UX. Wikipedia defines UX as “the process of enhancing user satisfaction by improving the usability, accessibility and pleasure provided in the interaction between the user and the product.”

A less-used term is Customer Experience or CX. Wikipedia defines that as “the product of an interaction between an organization and a customer over the duration of their relationship. This interaction includes a customer's attraction, awareness, discovery, cultivation, advocacy, and purchase and use of a service.”