Category Archives: Qt

QRPC: A Qt remoting library

This project of mine has been around for quite a while already. I’ve never much publicised it, however, and for the past year the code hasn’t seen any changes (until a few days ago, anyway). But related to my current job, I’ve found a new need for remote procedure calls, so I came back to the code after all.

QRPC is a remoting library tightly integrated with Qt: in simplified terms, it’s an easy way to get signal-slot connections over the network. At least that was its original intention, and hence comes the name (QRPC as in “Qt Remote Procedure Call”).

But actually, it’s a little more than that. QRPC pipes the whole of Qt’s meta-object functionality over a given transport. That can be a network socket, unix domain socket or something more high-level like ZeroMQ. But it could, for example, also be a serial port (not sure why anybody would want that, though).
The actual remoting system works as follows: A server marks some objects for “export”, meaning they will be accessible by clients. Clients can then request any such object by its identifier. The server then serialises the whole QMetaObject hierarchy of the exported object and sends it to the client. There, it is reconstructed and used as the dynamic QMetaObject of a specialised QObject. Thus, the client not only has access to signals and slots, but also to properties and Q_CLASSINFOs (actually anything that a QMetaObject has to offer). The property support also includes dynamic properties, not only the statically defined QMetaProperties.
Method invocations, signal emissions and property changes are serialised and sent over the transport – after all, a QMetaObject without the dynamics isn’t that useful ;).

To give an impression of how QRPC is used, here’s an excerpt from the example included in the repository:

Server:

Client:

Argument or property types have to be registered metatypes (same as when using queued connections) and serialisable with QDataStream. The QDataStream operators also have to be registered with Qt’s meta type system (cf. QMetaType docs).
At the moment, one shortcoming is that references to QObjects (i.e. “QObject*”) can’t be transferred over the network, even if the relevant QObjects are “exported” by the server. Part of the problem is that Qt doesn’t allow us to register custom stream operators for “QObject*”. This could be solved by manually traversing the serialised values, but that will negatively impact the performance. Usually one can work around that limitation, though.

Furthermore, method return values are intentionally not supported. Supporting them would first require a more complex system to keep track of state and secondly impose blocking method invocations, both of which run contrary to my design goals.

In some final remarks, I’d like to point out two similar projects: For one, there’s QtRemoteObjects in Qt’s playground which works quite similarly to QRPC. I began working on QRPC at around the same time as QtRemoteObjects was started and I didn’t know it existed until quite some time later. Having glanced over its source code, I find it to be a little too complex and doing too much for my needs without offering the same flexibility (like custom transports). I must admit that I haven’t checked it out in more detail, though.
Then there’s also QtWebChannel which again offers much of the metaobject functionality over the web, but this time specifically geared towards JavaScript/HTML5 clients and Web apps. I thought about reusing part of its code, but ultimately its focus on JS was too strong to make this a viable path.

QuickPlot: A collection of native QtQuick plotting items

For a project at university I recently needed a plotting widget to display some data. Naturally, Qwt came to my mind. I’ve already been using it in a number of other projects and it works great.

The one drawback, however: The project was intended to be run on the Raspberry Pi. Now the X-Server on the R-Pi doesn’t have any 3D acceleration yet, so the performance of Qwt was subpar.

Luckily, Qt has the eglfs backend (using Broadcom’s EGL libraries), which works very well on the R-Pi. The problem: You have to use QML/QtQuick with that, so Qwt was out of the game (actually, I’ve played around with creating a QtQuick backend for Qwt, but with Qwt being QPainter-based, still, it was nowhere near performant enough). A more QtQuick-like solution was needed.

Since QtQuick supports the HTML5 Canvas API, I thought that maybe some HTML5 chart library like Chart.js could do the trick. The good news: It works pretty much out of the box and you get very pretty charts. The bad news: performance on the Raspberry Pi is more or less abysmal (on a laptop or desktop PC it’s fine, though). Even some hand-crafted plotting code based on the Canvas API ate the better part of the R-Pi’s CPU when displaying a continuous stream of data. This isn’t actually that much of a wonder, considering that it was all based on JavaScript and has redrawn the whole plot area in an FBO every time there was a data update.

So all of the “simple” solutions where dead ends. Eventually I ended up writing my own plot items, this time based on QtQuick’s Scene Graph to get the best performance out of the little computer. I was actually surprised that no-one had done something like this yet – or at least I couldn’t find anything.
Anyway, here’s a screenshot of the thing displaying a sine wave with axes:

The sine wave is actually scrolling through the view, always showing the most recent 300 data points of the data source. It’s even anti-aliased on most hardware, including the R-Pi, just not on my laptop’s Intel GPU on which I took the screenshot. The performance on the Raspberry Pi is now very good, using less than 5% of the CPU, while the other solutions where north of 70% for a continuously updated data source (values from top, not claiming any sort of accuracy).

The API is somewhat inspired by Qwt’s. There’s the PlotArea Item which is responsible for managing all items of the plot. It keeps a collection of PlotItems, displays the axes and makes the used ScaleEngines (used for the axis limits) known to every item and axis in the plot.
I haven’t implemented more than the most basic PlotItems and ScaleEngines at the moment (because those are currently the only things I need):

  • Curve: exactly what the name implies – a set of points connected by lines.
  • ScrollingCurve: A curve which only displays the last N data points. If the data is continuously updated, this looks as if the curve is scrolling from right to left.
  • TightScaleEngine: A ScaleEngine which sets the axis limits to the overall minima and maxima of all the plot items.
  • FixedScaleEngine: A ScaleEngine which sets the axis limits to constant values.

The axis ticks are placed based on the nicenum algorithm from the Graphics Gems book series from Academic Press. The API is designed with C++/Qt data sources in mind: Data is passed as QVector<float> or QVector<QPointF>, preferrably as an argument to a signal-slot connection. Note that the usage of QVector makes setting the data statically from QML a little difficult. I’m open for suggestions to improve this, but I would really like to avoid converting a batch of data to a QVariantList and back just to integrate better with QML/JS.

You can find the code on gitorious GitLab, licensed under the GPLv3: https://gitlab.com/qtquickplot/qtquickplot

Edit: Some example code would probably be nice, so here is the QML code used in the above screen shot:

Edit 2: Due to Gitorious being acquired by GitLab, the code has been moved to the latter: https://gitlab.com/qtquickplot/qtquickplot

Connecting C++11 lambdas to Qt4 Signals with libffi (now portable)

I know that this is probably not very useful, considering that it’s not portable and with Qt5 about to be released in June, but I found it interesting to experiment with the new language features and libffi.

The result is a class which lets you connect any function pointer or lambda, with or without bound variables, to Qt4 signals. Example of what you can do with it:

Quite nice, I think :) You can get the source for lambdaconnection.h here.

Its main drawback is the use of pointers to member functions as ordinary function pointers. It works with gcc and maybe clang, but it’s probably going to break with other compilers and/or operating systems. UPDATE: By converting everything to std::function, we can have one template function which is called by libffi and handles any further lambda calls. No need for member-function-pointers anymore. Portability shouldn’t be an issue anymore, too.

Additionally, to avoid code duplication, it simply converts function pointers to std::function objects. This adds some overhead when calling the function pointer.

Anyway, it’s only an afternoon’s work and it was fun to code. Maybe someone will find this interesting :)