Quantcast
Channel: Planet Qt
Viewing all 15410 articles
Browse latest View live

The Qt Company Blog: Qt for WebAssembly

$
0
0

You may have seen the news that Qt Project releasedQt for WebAssembly tech preview.

We useEmscriptento compile Qt into something that runs in a web browser from a webserver. Instead of compiling and deploying for multiple platforms, the idea is to compile and deploy on a web server for any platform that has a browser that supports WebAssembly. Ifyou are an enterprise and have multiple clients that have various platforms in use, you could use Qt for WebAssembly to compile your Qt or Quick app and deploy once.

Qt for WebAssembly build instructions are listed onQt for WebAssembly wikiYou will first need to download and setup theemsdk compiler. It’s fairly trivial to do. We use this as the cross-compiler.

Developing/Debugging

Debugging is a bit arcane as there is no gdb, but there are output statements (std::cout, qDebug and printf) as well as the debugger console in the browser.You might also have to increase theWeb console log limit with (Firefox) “devtools.hud.loglimit.console” from about:config.

To set a breakpoint, add

EM_ASM({ debugger });  

into your code to popup the browser debugger. (Don’t forget to#include<emscripten.h>)The downside is that you need to recompile.

Screenshots

Not everything works perfectly, but here are some screenshots of a few working examples:

collidingmice:

collidingmice-qt-for-webassembly-example

Standarddialogs: showing multiple windows

standarddialogs-qt-for-webassembly-example

QOpenGLWindow works and seems to get near 60 fps. Although they are ‘full screen’ windows currently, which means they will take up the full browser window. QOpenGLWidget still has some issues. Some shaders seem to have some issues.

Emscripten translates OpenGL calls in WegGL, so there are limitations from the desktop and embedded versions.

Openglwindow:

openglwindow-qt-for-webassembly-example

Besides QtBase and QtDeclarative that use the ‘wip/webassembly’ branch, Qt modules known to work are:

  • QtCharts
  • QtGraphicalEffects
  • QtQuickControls
  • QtQuickControls2
  • QtWebSockets
  • QtMqtt (using WebSocketIODevice from the websockets example)

To use QtMqtt, you will need to integrate the WebSocketIODevice class from the websocketsubscription example in QtMqtt into your app.

There is also a WIP MR for a backend to QtSensors for orientation changes on mobiles (including laptops) that I have thrown together which compiles, but hasn’t been tested.

Qml clocks:

screen-shot-2018-05-18-at-15-50-05

Since javascript and webassembly have only one thread, QtDeclarative was made to work with only one thread.

textinsgnode:

screen-shot-2018-05-18-at-15-53-30

 

QtCharts, QtGraphicalEffects, QtQuickcontrols, QtQuickControls2 all work without changes.

QtCharts oscilloscope:

screen-shot-2018-05-18-at-15-55-45

IoT sensor demo showing demo data

screen-shot-2018-05-18-at-15-56-05

There is a WIP merge request for clipboard support, but it is unfinished at this time. It is workingfor simple text.

Things that don’t workQTBUG-63917

  • MultithreadingQTBUG-64700
    • there is a stub QThread
    • disabled in the browsers due to the Spectre vulnerability
  • Most QNetworkQTBUG-63920
    • no DNS lookups due to javascript sandbox
    • simple QNAM requests should work.
  • Local Filesystem accessQTBUG-67834
  • persistent QSettings, it syncs the config rather slow and asynchronouslyQTBUG-63923
  • QOpenGLWIdgetQTBUG-66944
  • Opengl only works fullscreenQTBUG-67717
  • some shadersQTBUG-67338
    • QResource fails to find shaders built-in to Qt
  • The exec loop does not function like other platformsQTBUG-64020
    • exec() event loop will not return where you expect it to
    • Returning values from modal dialogs are known not to work but can be worked around by using non-modal signals and show(). Although modal dialogs/windows will still open.
  • toUpperCaseQTBUG-66621
  • QClipboardQTBUG-64638

Examples

 

The post Qt for WebAssembly appeared first on Qt Blog.


The Qt Company Blog: Qt for WebAssembly – check out the examples!

$
0
0

WebAssembly is now supported by all major web browsers as a binary format for allowing sand-boxed executable code in web pages that is nearly as fast as native machine code. Qt for WebAssembly makes it possible to run Qt applications on many web browsers without any download steps or special server requirements (other than serving the wasm file).

To give you a closer look, we compiled some demos. For best performance, use Firefox.

Here is the complete list along with some descriptions:

http://example.qt.io/qt-webassembly/SensorTagDemo/SensorTagDemo.html
A larger example of an interesting industry automation use case. In principle, it is possible to show live data retrieved using Qt WebSockets, but this is just showing generated dummy data for illustration purposes.

http://example.qt.io/qt-webassembly/quickcontrols2/gallery/gallery.html
A gallery of available controls in Qt Quick Controls 2. This shows that you can use Qt Quick and Qt Quick Controls 2 to make your web-deployed applications.

http://example.qt.io/qt-webassembly/widgets/richtext/textedit/textedit.html
A simple text editor, written with Qt Widgets. This example shows that you can also use Qt Widgets to create your web-deployed applications.

As always, let us know what you think!

The post Qt for WebAssembly – check out the examples! appeared first on Qt Blog.

KDAB on Qt: New in Qt 5.11: improvements to the model/view APIs (part 1)

$
0
0

The Qt model/view APIs are used throughout Qt — in Qt Widgets, in Qt Quick, as well as in other non-GUI code. As I tell my students when I deliver Qt trainings: mastering the usage of model/view classes and functions is mandatory knowledge, any non-trivial Qt application is going to be data-driven, with the data coming from a model class.

In this blog series I will show some of the improvements to the model/view API that KDAB developed for Qt 5.11. A small word of advice: these posts are not meant to be a general introduction to Qt’s model/view (the book’s margin is too narrow… but if you’re looking for that, I suggest you start here) and assumes a certain knowledge of the APIs used.

Implementing a model class

Data models in Qt are implemented by QAbstractItemModel subclasses. Application developers can either choose one of the ready-to-use item-based models coming with Qt (like QStringListModel or QStandardItemModel), or can develop custom model classes. Typically the choice falls on the latter, as custom models provide the maximum flexibility (e.g. custom storage, custom update policies, etc.) and the biggest performance. In my experience with Qt, I have implemented probably hundreds of custom models.

For simplicity, let’s assume we are implementing a table-based model. For this use case, Qt offers the convenience QAbstractTableModel class, which is much simpler to use than the fully-fledged QAbstractItemModel. A typical table model may look like this:

class TableModel : public QAbstractTableModel
{
public:
    explicit TableModel(QObject *parent = nullptr)
        : QAbstractTableModel(parent)
    {
    }

    // Basic QAbstractTableModel API
    int rowCount(const QModelIndex &parent) const override
    {
        return m_data.rowCount();
    }

    int columnCount(const QModelIndex &parent) const override
    {
        return m_data.columnCount();
    }

    QVariant data(const QModelIndex &index, int role) const override
    {
        if (role != Qt::DisplayRole)
            return {};

        return m_data.getData(index.row(), index.column());
    }

private:
    Storage m_data;
};

First and foremost, note that this model is not storing the data; it’s acting as an adaptor between the real data storage (represented by the Storage class) and the views.

When used into a Qt view (for instance a QTreeView), this code works perfectly and shows us a nice table full of data, for instance like this:

Making the code more robust

The code of the class above has a few issues.

The first issue is that the implementation of rowCount() and columnCount() is, generally speaking, wrong. Those functions are supposed to be callable for every model index belonging to this model, plus the root (invalid) model index; the parameter of the functions is indeed the parent index for which we’re asking the row count / column count respectively.

When called with the root index, the functions return the right amount of rows and columns. However, there are no rows and no columns below any of elements in the table (because it is a table). The existing implementation does not make this distinction, and happily returns a wrong amount of rows/columns below the elements themselves, instead of 0. The lesson here is that we must not ignore the parent argument, and handle it in our rowCount and columnCount overrides.

Therefore, a more correct implementation would look like this:

    int rowCount(const QModelIndex &parent) const override
    {
        if (parent.isValid())
            return 0;

        return m_data.rowCount();
    }

    int columnCount(const QModelIndex &parent) const override
    {
        if (parent.isValid())
            return 0;

        return m_data.columnCount();
    }

The second issue is not strictly a bug, but still a possible cause of concern: we don’t validate any of the indices passed to the model’s functions. For instance, we do not check that data() receives an index which is valid (i.e. isValid() returns true), belonging to this very model (i.e. model() returns this), and pointing to an existing item (i.e. its row and column are in a valid range).

    QVariant data(const QModelIndex &index, int role) const override
    {
        if (role != Qt::DisplayRole)
            return {};

        // what happens here if index is not valid, or not belonging to this model, etc.?
        return m_data.getData(index.row(), index.column());
    }

I personally maintain quite a strong point of view about this issue: passing such indices is a violation of the API contract. A model should never be assumed to be able to handle illegal indices. In other words, in my (not so humble) opinion, the QAbstractItemModel API has a narrow contract.

Luckily, Qt’s own views and proxy models honour this practice. (However, be aware that some other bits of code, such as the old model tester from Qt Labs, does not honour it, and will pass invalid indices. I will elaborate more on this in the next blog post.)

Since Qt will never pass illegal indices to a model, it’s generally pointless to make QAbstractItemModel APIs have wide contracts by handling all the possible inputs to its functions; this will just add unnecessary overhead to functions which are easily hotspots in our GUI.

On the other hand, there are cases in which it is desirable to have a few extra safety checks in place, in the eventuality that an illegal index gets passed to our model. This can happen in a number of ways, for instance:

  • in case we are developing a custom view or some other component that uses our model via the model/view API, accidentally using wrong indices;
  • a QModelIndex is accidentally stored across model modifications and then used to access the model (a QPersistentModelIndex should have been used instead);
  • the model is used in combination with one or more proxy models, which may have bugs in the mapping of the indices (from source indices to proxy indices and viceversa), resulting in the accidental passing of a proxy index to our model’s functions.

In the above scenarios, a bug somewhere in the stack may cause our model’s methods to be called with illegal indices. Rather than crashing or producing invalid data, it would be very useful to catch the mistakes, in order to gracefully fail and especially in order to be able to debug them.

In practice all of this means that our implementation of the QAbstractItemModel functions needs some more thorough checks. For instance, we can rewrite data() like this:

    QVariant data(const QModelIndex &index, int role) const override
    {
        // index is valid
        Q_ASSERT(index.isValid());

        // index is right below the root
        Q_ASSERT(!index.parent().isValid());

        // index is for this model
        Q_ASSERT(index.model() == this);

        // the row is legal
        Q_ASSERT(index.row() >= 0);
        Q_ASSERT(index.row() < rowCount(index.parent())); 
        // the column is legal 
        Q_ASSERT(index.column() >= 0);
        Q_ASSERT(index.column() < columnCount(index.parent()));

        if (role != Qt::DisplayRole)
            return {};

        return m_data.getData(index.row(), index.column());
    }

Instead of hard assertions, we could use soft assertions, logging, etc. and returning an empty QVariant. Also, do note that some of the checks could (and should) also be added to the rowCount() and columnCount() functions, for instance checking that if the index is valid then it indeed belongs to this model.

Introducing checkIndex

After years of developing models I’ve realized that I must have written some variation of the above checks countless times, in each and every function of the QAbstractItemModel API. Recently I gave the question some more thought, and I came up with a solution: centralize the above checks, so that I don’t have to re-write them every time.

In Qt 5.11 I have added a new function to QAbstractItemModel: QAbstractItemModel::checkIndex(). This function takes a model index to check, and an option to determine the kind of checks that should be done on the index (see the function documentation for all the details).

In case of failure, the function returns false and prints some information in the qt.core.qabstractitemmodel.checkindexlogging category. This gives us the flexibility of deciding what can be done on failure, and also to extract interesting data to debug an issue.

Using the brand new checkIndex() our data() reimplementation can now be simplified to this:

    QVariant data(const QModelIndex &index, int role) const override
    {
        // data wants a valid index; moreover, this is a table, so the index must not have a parent
        Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid | QAbstractItemModel::CheckIndexOption::ParentIsInvalid));

        if (role != Qt::DisplayRole)
            return {};

        return m_data.getData(index.row(), index.column());
    }

Again, the example has an hard assert, which means that the program will crash in case of an illegal index (forcing the developer to do something about it). On the other hand the check will disappear in a release build, so that we don’t pay the price of the check at each invocation of data(). One could instead use a soft assert or just a plain if statement (as many models — unfortunately — do, including the ones coming with Qt) for customizing the outcome of the check.

This is an example of the logging output we automatically get in case we pass an invalid model index, which is not accepted by data():

qt.core.qabstractitemmodel.checkindex: Index QModelIndex(-1,-1,0x0,QObject(0x0)) is not valid (expected valid)

And this is an example of the output in case we accidentally pass an index belonging to another model (which happens all the time when developing custom proxy models):

qt.core.qabstractitemmodel.checkindex: Index QModelIndex(0,0,0x0,ProxyModel(0x7ffee145b640)) is for model ProxyModel(0x7ffee145b640) which is different from this model TableModel(0x7ffee145b660)

Conclusions

I hope that this addition to QAbstractItemModel will help developers build better data models, and to quickly and effectively debug situations where the model API is being misused.

In the next instalment I will talk about other improvements to the model/view framework in Qt 5.11.

About KDAB

KDAB is a consulting company offering a wide variety of expert services in Qt, C++ and 3D/OpenGL and providing training courses in:

KDAB believes that it is critical for our business to contribute to the Qt framework and C++ thinking, to keep pushing these technologies forward to ensure they remain competitive.

The post New in Qt 5.11: improvements to the model/view APIs (part 1) appeared first on KDAB.

KDAB on Qt: QtDay Italy, May 23-24

$
0
0

Once more in Florence, QtDay Italy is almost upon us and we’ll be there.

Giuseppe D’Angelo will be giving a talk on Gammaray, KDAB’s open source profiling and debugging tool.

GammaRay is a “high-level debugger”, able to show the status of various Qt subsystems inside an application, with an easy to use interface (that does not require any knowledge of Qt internals). GammaRay can, amongst other things, show the properties of any QObject in the application, show the status of all state machines, inspect and debug layouting and stacking of both widgets and Qt Quick applications, analyze raster painting, show the 3D geometry in a Qt3D scene, and much more.

This talk introduces the basics of GammaRay usage, with some interesting cases as examples of problem solutions.

See you in Florence!

The post QtDay Italy, May 23-24 appeared first on KDAB.

KDAB on Qt: KDAB at SIGGRAPH 2018

$
0
0

Yes, folks. This year SIGGRAPH 2018 is in Canada and we’ll be there at the Qt booth, showing off our latest tooling and demos. These days, you’d be surprised where Qt is used under the hood, even by the biggest players in the 3D world!

SIGGRAPH 2018 is a five-day immersion into the latest innovations in CG, Animation, VR, Games, Digital Art, Mixed Reality and Emerging Technologies. Experience research, hands-on demos, and fearless acts of collaboration.

Meet us at SIGGRAPH 2018!

Book your place for the most exciting 3D event of the year!

The post KDAB at SIGGRAPH 2018 appeared first on KDAB.

KDAB on Qt: KDAB at Qt Contributor’s Summit 2018, Oslo

$
0
0

KDAB is a major sponsor of this event and a key independent contributor to Qt as our blogs attest.

Every year, dedicated Qt contributors gather at Qt Contributors’ Summit to share with their peers latest knowledge and best practices, ensuring that the Qt framework stays at the top of its game. Be a Contributor to Qt!

We look forward to meeting you in Oslo!

The post KDAB at Qt Contributor’s Summit 2018, Oslo appeared first on KDAB.

The Qt Company Blog: Qt for Python: under the hood

$
0
0

Today I would like to tell you about the “Qt for Python bindings” generation process.

The following diagram shows the most general interaction of the internal process that The Qt Company is using to provide the PySide2 module:

qtforpython-underthehood

When the PySide project was launched back in 2009, the team decided to use external tools to generate Python bindings from Qt C++ headers.
One of the main concerns, besides using a tool that properly handles all the Qt C++ constructs, was the size of the final packages.
The previous choice was using templates excessively, hence another alternative was required.
After analyzing a few other options the team decided to write their own generator, Shiboken.

Shiboken uses an ApiExtractor library (based on an old project called QtScriptGenerator) to parse the Qt Headers and get the information of all the Qt classes, using Clang.
This step is not Qt-dependent, so it can be use for other C++ projects as well.

Additionally, Shiboken has a Typesystem (based on XML) which allows modifying the obtained information to properly represent and manipulate the C++ classes into the Python World.

Through this Typesystem we can remove and add methods to certain classes, and even modify the arguments of each function, which is really necessary when both C++ and Python collide and a decision needs to be made to properly handle the data structures or types.

The outcome of this process is a set of wrappers written in CPython, which allow us to easily compile and then provide you the python module called PySide2.

Official documentation related to the ApiExtractor and Shiboken will be included in the official Qt for Python documentation, so you can get involved in their development, and if you are curious how Shiboken works, stay tuned for the future blog posts!

The post Qt for Python: under the hood appeared first on Qt Blog.

The Qt Company Blog: Porting guide from Qt 1.0 to 5.11

$
0
0

Now that Qt 5.11 is released, it is finally time to upgrade the last Qt 1.0 applications out there… No, not really. 😉 I want to take a look at how well we have kept compatibility in Qt over the years since the first official release.

Qt guarantees source and binary compatibility between minor releases, and we take that seriously. Making sure that you don’t have to rewrite (or even recompile) your application when you upgrade to a newer version of Qt is important to us. However, there are times when we need to make bigger changes in order to keep Qt up to date. This is done in major releases. Since the release of Qt 1.0 in 1996 (almost twenty-two years ago), we have broken source compatibility four times: in 2.0, 3.0, 4.0 (some of you may remember that as a painful transition), and 5.0.

We do try to keep breakages to a minimum, even in the major releases, but the changes do add up. This raises the question: How hard would it be to port a Qt application from Qt 1.0 to 5.11?

To find an answer to this question, I took the tutorial example from the Qt 1.0 release, and tried to compile it against Qt 5. Since the Qt archives only go back to version 1.41, I actually had to retrieve it from ancient history which has been preserved through four different source code control systems …but I digress. Its name is t14 because it is the 14th and final chapter of the tutorial.

Here are the steps I needed to make to get it to build and run.

  • Import tutorial 14 from Qt 1.010 files changed, 798 insertions(+)

    This is the state of the art: the official recommendation from Troll Tech (we weren’t Trolltech yet) on how to write programs with Qt 1.0, in 1996.

  • Translate to qmake3 files changed, 2 insertions(+), 148 deletions(-)
    tmake
    Before qmake, there was tmake. tmake was written in Perl. The basic syntax was the same, except that qmake no longer allows embedding Perl code in the project files. This is probably for the best…

    Also, tmake was not public, so we would generate Makefiles for the release packages. Having completely different internal and external build systems added excitement to the release process.

  • Fix include file names4 files changed, 8 insertions(+), 8 deletions(-)
    includenames
    Back in the old days, Windows only allowed eight character file names. We did have proper include files on Unix, but if you wanted your code to be portable, you had to use wonderful names like "qscrbar.h" and "qbttngrp.h".
  • Add missing includes1 file changed, 3 insertions(+)

    Dependency on indirect includes was a problem back then as well.

  • Change TRUE/FALSE to true/false1 file changed, 13 insertions(+), 13 deletions(-)
    truefalse
    Kids these days. They don’t know how lucky they are. We had to make our own bool type.
  • Fix things moved to the Qt:: namespace3 files changed, 15 insertions(+), 15 deletions(-)
    namespace
    The Qt namespace was introduced in 1998 … as a class, since we didn’t have those fancy namespaces back then.
  • Remove “name” argument6 files changed, 26 insertions(+), 26 deletions(-)
    objectname
    All constructors of QObject subclasses used to take the object name as a parameter.
  • The QScrollBar API has changed1 file changed, 5 insertions(+), 5 deletions(-)
    scrollbarapi
    Sometimes we have to get rid of old, bad APIs. Having individual setter functions is much better than a constructor that takes 7 arguments.
  • Use QString instead of const char *2 files changed, 2 insertions(+), 2 deletions(-)
    qstring
    QString has been in Qt since 1994. It used to be 8 bit Latin1 with an automatic cast to const char*, so the API would use const char * arguments. Unicode support was introduced in Qt 2.0.
  • warning() is called qWarning() now1 file changed, 1 insertion(+), 1 deletion(-)

    We avoid putting identifiers into the global namespace. Except for the letter ‘Q’. We own that.

  • Remove calls to old QApplication functions1 file changed, 2 deletions(-)
    qapp
    Qt does the right thing automatically these days. In 1996, most displays used 8 bits per pixel. You had to tell Qt if you wanted to use other colors than the 256 standard ones.
  • Replace QAccel with QShortcut1 file changed, 4 insertions(+), 3 deletions(-)
    shortcut
    QShortcut is more powerful and easier to use, and the name is not an abbreviation. It was introduced in 2004.
  • Fix repaint logic1 file changed, 7 insertions(+), 7 deletions(-)
    repaint
    In the ’90s, we could just paint directly onto the widgets whenever we wanted. Nowadays everything is buffered and composed, so we have to make an update request, and later repaint the widget when we get a go-ahead. Fortunately, this simplifies the logic.
  • QObject::killTimers() doesn’t exist anymore2 files changed, 3 insertions(+), 2 deletions(-)
    killtimer
    This function was just too dangerous. It would kill all timers belonging to an object, including those used by Qt internally. Now you have to kill timers individually.
  • QWMatrix is now QMatrix1 file changed, 2 insertions(+), 2 deletions(-)

    A simple name change.

  • QWidget::setBackgroundColor() is gone.1 file changed, 3 insertions(+), 1 deletion(-)
    I keep misspelling it as backroundColor
    Backgound color is no longer a separate concept: it’s wrapped inside QPalette together with all the other color roles. Also, child widgets are now transparent by default. We have to tell Qt to draw the background.
  • Can’t fill pixmap with contents of widget anymore1 file changed, 1 insertion(+), 1 deletion(-)
    pixmapfill
    We use a transparent pixmap instead, since Qt supports that now.
  • Rectangle painting has changed since Qt 1.01 file changed, 1 insertion(+), 1 deletion(-)
    drawrect
    This is the worst incompatibility so far: In Qt 4.0 QPainter::drawRect() was changed so that “a stroked rectangle has a size of rectangle.size() plus the pen width”. Therefore, we need to subtract the pen width (i.e. 1) before passing the rectangle to QPainter.

Now we have a fully functional port of the tutorial example, and here is a screenshot:

t14 take one

Oops… Some of the text is clipped. It turns out that the example used hardcoded sizes and positions for most of the elements, and font sizes have changed a bit since 1996. The solution is to use QLayout, which was not available in Qt 1.0 (the first version was added in Qt 1.1, and it was completely rewritten for 2.0).

With this change, everything looks as it should:

t14 with layouts

So, what did we learn? It did not take that much effort to port tutorial 14 from Qt 1.0 to Qt 5.11. It probably took me longer to write this blog post. Most of the 1.0 API still lives on in recognizable form. The incompatible changes have improved the usability, readability and safety of Qt code.

This was just a small example, of course. Porting a full-sized application across multiple major versions would probably be more difficult. Fortunately, we have a vibrant Qt ecosystem with several companies offering consultancy services .

The post Porting guide from Qt 1.0 to 5.11 appeared first on Qt Blog.


The Qt Company Blog: Playing with coroutines and Qt

$
0
0

Hello!
I was recently wondering about the status of the coroutines in C++ and I found several implementations. I decided to choose this one for my experiment.
It’s simple and easy to use and works in Linux and Windows.

My goal was to try to find a way to have code running asynchronously without waiting for signals to trigger my slots and avoiding to call QCoreApplication::processEvents or creating a QEventLoop in the stack.

My first approach was to convert the processEvent function of a custom event dispatcher into a coroutine and use yield. After several failures, I decided not to continue this way.

My next attempt was to convert a slot into a coroutine:

QTimer::singleShot(0, std::bind(&coroutine::resume, coroutine::create([]() { ... });

Inside this lambda, the CPU will execute the code until the yield, it will jump back to the application event loop.
The full code is:

#include "coroutine.h"
#include 
#include 

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QPushButton fibonacciButton("0: 0");
  fibonacciButton.show();
  QObject::connect(&fibonacciButton, &QPushButton::pressed,
                   std::bind(&coroutine::resume, coroutine::create([&]() {
    qulonglong f0 = 1, f1 = 0, n = 1;
    fibonacciButton.setText(QString("1: 1"));
    coroutine::yield();
    fibonacciButton.setText(QString("2: 1"));
    coroutine::yield();
    forever {
      auto next = f1 + f0;
      f0 = f1;
      f1 = next;
      fibonacciButton.setText(QString("%0: %1").arg(n++).arg(f0 + f1));
      coroutine::yield();
    }
  })));
  return app.exec();
}

Here we can see a button connected to a lambda function which calculates the numbers in the Fibonacci sequence. After calculating the next number, we call yield and this will jump from this function to the event loop. When the user presses the button again, the code will return to the next line after the yield.

This example works because the user needs to press the button again to resume the execution of the code.

However, sometimes we want to resume the execution automatically. To do this, we need to yield the execution and schedule a resume of the execution:

void qYield()
{
  const auto routine = coroutine::current();
  QTimer::singleShot(0, std::bind(&coroutine::resume, routine));
  coroutine::yield();
}

The first line gets the identifier of the coroutine and the second schedules the resume. With yield the CPU will come back to the previous frames and finally to the main loop with a resume enqueued resuming the code unconditionally.

Next step is to try to resume when a condition happens. Qt provides signals that indicate when something happened, so the more optimal way to yield the execution is:

template 
void qAwait(const typename QtPrivate::FunctionPointer::Object *sender, Func signal)
{
  const auto routine = coroutine::current();
  const auto connection = QObject::connect(sender, signal,
                                           std::bind(&coroutine::resume, routine));
  coroutine::yield();
  QObject::disconnect(connection);
}

Instead of enqueuing a resume we create a temporary connection to resume the execution of our slot.

An example of this can be:

#include "coroutine.h"
#include 
#include 
#include 

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QPlainTextEdit textEdit;
  textEdit.show();
  QTimer::singleShot(0, std::bind(&coroutine::resume, coroutine::create([&]() {
    QUrl url("http://download.qt.io/online/qt5/linux/x64/online_repository/Updates.xml");
    QNetworkRequest request(url);
    QNetworkAccessManager manager;
    auto reply = manager.get(request);
    qAwait(reply, &QNetworkReply::finished);
    textEdit.setPlainText(reply->readAll());
    reply->deleteLater();
  })));
  return app.exec();
}

Here, I created a QTextEdit which receives the content of a file from internet. When the QNetworkReply finishes, the data is written in the QTextEdit.

Another example:

#include "coroutine.h"
#include 
#include 
#include 

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QPlainTextEdit edit;
  edit.show();

  QTimer::singleShot(0, std::bind(&coroutine::resume, coroutine::create([&]() {
    auto previousText = edit.toPlainText();
    forever {
      if (edit.toPlainText() == QStringLiteral("quit")) {
        qApp->quit();
      } else if (previousText != edit.toPlainText()) {
        qDebug() << previousText << "->" << edit.toPlainText();
        previousText = edit.toPlainText();
      }
      qAwait(&edit, &QPlainTextEdit::textChanged);
      qDebug() << "QPlainTextEdit::textChanged";
    }
  })));
  return app.exec();
}

This application prints the text every time the user modifies the text, and it finishes the execution when the user writes the word ‘quit.’

The post Playing with coroutines and Qt appeared first on Qt Blog.

The Qt Company Blog: What’s new with the Wayland platform plugin in Qt 5.11?

$
0
0

Wayland is a display server protocol used on modern Linux systems, the Qt Wayland platform plugin lets Qt applications run on Wayland display servers (compositors).

Apart from bug fixes, the Qt 5.11 release contains a substantial amount of improvements, especially for desktop users.

Key composition support

key-composition

Support for compose keys has been missing for a long time and has finally been added. That means you can now enter characters that require a sequence of keys, such as:

  • ¨, A to write “ä”
  • compose key, S, S to write “ß”

Qt Wayland in official binaries

Starting with Qt 5.11 and Qt Creator 4.7, binaries in the official installers now also include Qt Wayland (previously you would have to build it yourself).

So the official build of Qt Creator itself now runs on Wayland, as well as the applications you build with the official Qt packages.

Qt creator 4.7 nightly running on Wayland

Qt creator 4.7 nightly running on Wayland

There are nightlies for QtCreator 4.7 available if you want to try it out before the official release.

Fallback to X11 if Wayland is not available

The common way of selecting a Qt platform plugin, has been to set the environment variable QT_QPA_PLATFORM=wayland. This has been a problem on Linux desktops, because some applications—for instance the official QtCreator package—use a bundled version of Qt that doesn’t include Wayland, and will fail to launch with the following message:

This application failed to start because it could not find or load the Qt platform plugin "wayland" in "".

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, xcb.

Reinstalling the application may fix this problem.

In Qt 5.11 we added support for fallback platform plugins, this means you can now set QT_QPA_PLATFORM="wayland;xcb", which makes Qt use the xcb (X11) plugin if Wayland is not available.

Improved high-dpi support

automatic-dpi-change
If you have a multi-monitor setup with both high-dpi and low-dpi screens, you’ll be happy to hear that windows now switch to the appropriate scale when moved from one screen to another. No more tiny or blurry windows 🙂

Testing and continuous integration

QA-wise Qt Wayland has seen significant improvements lately. We now run a subset of the QtBase unit tests on every patch set submitted, which means we will catch more bugs earlier. However, this is a topic suitable for a separate blog post.

News from the development branch

There has also been many recent changes that didn’t make it into the 5.11 release. State changes, such as resizing or maximizing have seen a lot of work. We now finally support maximizing and full screen on xdg-shell-v6. We have also added a new shell integration for xdg-shell stable.

Qt Wayland backports repository

If you want to test the new features and fixes in Qt Wayland, but don’t want to wait for a release, or if you don’t want to upgrade or compile all of Qt, I have set up an unofficial qtwayland-backports repository.

It contains branches with new versions of Qt Wayland that compile against older versions of Qt. I.e. if you use Qt 5.10.x, you can still test recent changes in the Qt Wayland dev branch using the dev-for-5.10 branch.

Arch Linux users can install the AUR package, qt5-wayland-dev-backport-git, as a drop-in replacement for qt5-wayland. Again, note that these backports are unofficial and there are no guarantees that I will keep updating them.

The post What’s new with the Wayland platform plugin in Qt 5.11? appeared first on Qt Blog.

The Qt Company Blog: Playing with coroutines and QML

$
0
0

** aka Playing with coroutines and Qt (Part II)

From 5747a7530206ac410b6bd7c1b8490d7d389ad3a5JavaScript Generators are supported in QML. This enables to write the Fibonacci example from the previous post using generators and QML.

Mandatory example:

import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.2

Window {
    property var fibonacci: function* () {
        yield "0: 0"
        yield "1: 1"
        var f0 = 1, f1 = 0, n = 2;
        while (true) {
            var next = f1 + f0;
            f0 = f1;
            f1 = next;
            yield n++ + ": " + (f0 + f1);
        }
    }

    visible: true
    width: 640
    height: 480
    title: qsTr("Fibonacci")

    Row {
        anchors.fill: parent
        Button {
            id: button
            property var coroutine: fibonacci()
            width: parent.width / 2; height: parent.height
            text: coroutine.next().value
            onPressed: text = coroutine.next().value
        }

        Button {
            text: "Reset!"
            width: parent.width / 2; height: parent.height
            onPressed: {
                button.coroutine = fibonacci()
                button.text = button.coroutine.next().value
            }
        }
    }
}

Have fun!

The post Playing with coroutines and QML appeared first on Qt Blog.

Cutelyst Framework: Cutelyst 2.4.0 released

$
0
0

Cutelyst, the C++/Qt web framework got another up.

This release includes:

  • Fix for our EPoll event loop spotted by our growing community
  • An Sql query conversion optimization (also from community), we have helper methods to create QVariantHash, QVariantMap, QVariantList... from QSqlQuery to be used by Grantlee templates
  • New Sql query conversion to JSON types (QJsonObject, QJsonArray..) making it easier and faster to build REST services as shown on our blog post about Creating RESTful applications with Qt and Cutelyst
  • New boolean methods to test for the HTTP method used (isPUT(), isDelete()...) easing the work on REST apps
  • Fix for our CPU affinity logic, thanks to the TechEmpower benchmarks I found out that when creating many workers process they were all being assigned to a single CPU core, I knew that pre-fork was usually slower than threads on modern CPUs but was always intrigued why the difference was so big. Hopefully it will be smaller now.

Since I'm currently building a REST service OAuth2 seems to be something that would be of good use, one user has started working on this, hopefully this will soon be ready.

Have fun https://github.com/cutelyst/cutelyst/releases/tag/v2.4.0

 

The Qt Company Blog: Vulkan for Qt on macOS

$
0
0

Sometimes, development efforts align such that new use cases can be enabled with modest extra effort. The QtBase dev branch (which will become Qt 5.12) now has experimental Vulkan support, courtesy of MoltenVK and prior work in Qt. Let’s take a look at what has happened.

hellomacosvulcancubes

Backstory

Last year, Laszlo wrote about Vulkan support in Qt on Windows, Linux, and Android. This work included adding QSurface::VulkanSurface and also adding cross-platform classes such as QVulkanInstance and QVulkanWindow

Then, a couple of months ago, the MoltenVK Vulkan to Metal translation library was open sourced. One of the issues raised in the bug reporter was how to make this work with Qt; this requires configuring the NSView used by QWindow to be layer-backed by a CAMetalLayer.

And, as it happens we were already looking at making use of Metal in Qt, starting with adding support for CAMetalLayer as a backing layer. We’re also looking at different ways to integrate application Metal code with Qt, but that’s a topic for another blogpost.


// Snippet from Qt internal layer management code

@implementation QT_MANGLE_NAMESPACE(QNSView) (DrawingAPI)

- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
{
    // We need to set this this excplicitly since the super implementation
    // returns LayerContentsRedrawNever for custom layers like CAMetalLayer.
    return NSViewLayerContentsRedrawDuringViewResize;
}

- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
{
    CGSize drawableSize = layer.bounds.size;
    drawableSize.width *= layer.contentsScale;
    drawableSize.height *= layer.contentsScale;
    layer.drawableSize = drawableSize;
}

- (void)layoutSublayersOfLayer:(CALayer *)layer
{
    if ([layer isKindOfClass:CAMetalLayer.class])
        [self updateMetalLayerDrawableSize:static_cast(layer)];
}

- (void)viewDidChangeBackingProperties
{
    CALayer *layer = self.layer;
    if (!layer)
        return;

    layer.contentsScale = self.window.backingScaleFactor;

    // Metal layers must be manually updated on e.g. screen change
    if ([layer isKindOfClass:CAMetalLayer.class]) {
        [self updateMetalLayerDrawableSize:static_cast(layer)];
        [self setNeedsDisplay:YES];
    }
}

@end

With all this in place the missing parts was then the platform plugin glue code which adds support for QSurface::VulkanSurface (on macOS) and also implements a QPlatformVulkanInstance subclass that abstracts over platform-specific Vulkan tasks such as creating a Vulkan surface for a native surface.

How do I use it?

The minimal way

Call setSurfaceType(QSurface::VulkanSurface) in the constructor of your QWindow subclass. You can now access the NSView with QWindow::winId(), and pass that on to MoltenVK. The NSView is configured in such a way that MoltenVK can render to it. See also MotelVK issue #78 for more info. Note that I have not actually tried this myself 🙂

This does not require enabling Vulkan support when building Qt, which again means that the Qt binary package can be used (from 5.12 onwards).

The using the Qt API way

This makes using QVulkanWindow and friends possible, at the cost of having to build Qt from source.

Configure and build Qt with Vulkan support by adding the MoltenVK includes (build MoltenVK according to instructions first):

./confgure -I /path/to/MoltenVK/Package/Release/MoltenVK/include

You should now see “Vulkan: yes” on the configure report; if so the QVulkan* classes are available.

Then, tell Qt the location of libMoltenVK.dylib before starting apps or examples:

export QT_VULKAN_LIB=
  /path/to/MoltenVK/Package/Release/MoltenVK/macOS/libMoltenVK

This re-uses the existing Qt code which loads and resolves the Vulcan library at run-time. On macOS we might want to link against MoltenVK.framework instead, but we’ll leave that as a future improvement for now.

Finally

I’d like to round off by repeating the “experimental” warning. In particular we don’t have enough insight into the inner workings of MoltenVK to know if there are potential points of incompatibility. Please report any findings below or in a QTBUG.

The post Vulkan for Qt on macOS appeared first on Qt Blog.

The Qt Company Blog: Released and Certified: Qt Safe Renderer – An ASIL-D Functional Safety Solution

$
0
0

We are pleased to announce that the Qt Safe Renderer has been certified to meet the following functional safety standards:

  • ISO 26262:2011-6, ISO 26262:2011-8 (ASIL-D) (road vehicles functional safety)
  • IEC 61508:2010-3 7.4.4 (SIL 3) (electrical/electronic/programmable safety-related systems)
  • EN 50128:2011 6.7.4 (SIL 4) (railway applications)
  • IEC 62304:2015(2006+A1) (medical devices)

With this certification, the Qt Safe Renderer is now commercially available with all certification artifacts provided to customers.

The Qt Safe Renderer solves functional safety requirements in the Automotive, Medical, Automation and multiple other industries.

qt-safe-renderer-certificate-document

Risk Mitigation

The Qt Safe Renderer offers a high level of reliability and risk mitigation to any application where the correct rendering of graphical information is of paramount safety. An example for this from the automotive industry would be the warning icons on a car’s dashboard (for example in the images below). For medical devices, it would be critical patient readings.

Functional Safety Icons

Achieving certification requires rigorous development processes, from requirements, to architectural design, to implementation, to testing. When we built the Qt Safe Renderer, we documented every single one of these steps. This documentation, specifically the design documentation, the safety manual, and verification documentation are all provided in the software delivery. This gives companies peace of mind that their safety-critical UI systems will be easier to certify end-to-end when using the Qt Safe Renderer and of course they save time and money along the way by using a pre-certified component.

Designer Tooling

In addition to the certified run-time, Qt Safe Renderer also comes with designer tooling. This tooling allows designers to easily add safety critical elements to their designs. When they run and test their design on the desktop, these items run like regular graphical elements. When built for an embedded safety-critical system, the tooling separates out the safety-critical elements for execution by the Qt Quick Renderer run-time. This is performed seamlessly, making development cycles quick and easy and leaving designers to focus on what they do best.

qsr-build-tooling_

Further Information

We’ve written quite a few blogs in the past that include technical details on Functional Safety and our solution which can found here. Make sure to watch this webinar where we talk about functional safety and how the Qt Safe Renderer can be used to create functionally safe systems.

To learn more click on the button below.

qsr_release_blog_cta_image

The post Released and Certified: Qt Safe Renderer – An ASIL-D Functional Safety Solution appeared first on Qt Blog.

The Qt Company Blog: Serialization in and with Qt

$
0
0

In our first part of this series, we looked at how to set up messages, combine them, and reduce their overhead in the context of telemetry sensors.

This part focuses on the payload of messages and how to optimize them.

There are multiple methods to serialize an object with Qt. In part one, we used JSON. For this, all sensor information is stored in a QJsonObject and a QJsonDocument takes care to stream values into a QByteArray.

QJsonObject jobject;

jobject["SensorID"] = m_id;

jobject["AmbientTemperature"] = m_ambientTemperature;

jobject["ObjectTemperature"] = m_objectTemperature;

jobject["AccelerometerX"] = m_accelerometerX;

jobject["AccelerometerY"] = m_accelerometerY;

jobject["AccelerometerZ"] = m_accelerometerZ;

jobject["Altitude"] = m_altitude;

jobject["Light"] = m_light;

jobject["Humidity"] = m_humidity;

QJsonDocument doc( jobject );

 

return doc.toJson();

JSON has several advantages:

  • Textual JSON is declarative, which makes it readable to humans
  • The information is structured
  • Exchanging generic information is easy
  • JSON allows extending messages with additional values
  • Many solutions exist to receive and parse JSON in cloud-based solutions

However, there are some limitations to this approach. First, creating a JSON message can be a heavy operation taking many cycles. The benchmark in part 2 of our examples repository highlights that serializing and de-serializing 10.000 messages takes around 263 ms. That might not read like a significant number per message, but in this context time equals energy. This can significantly impact a sensor which is designed to run for years without being charged.

Another aspect is that the payload for an MQTT message per sensor update is 346 bytes. Given that the sensor sends just eight doubles and one capped string, this can be a potentially huge overhead.

Inside the comments of my previous post, using QJsonDocument::Compact has been recommended, which reduces the payload size to 290 bytes in average.

So, how can we improve on this?

Remember I was referring to textual JSON before? As most of you know, there is also binary JSON, which might reduce readability, but all other aspects are still relevant. Most importantly, from our benchmarks we can see that a simple switch of doc.toJson() to doc.toBinaryJson() will double the speed of the test, reducing the iteration of the benchmark to 125msecs.

Checking on the payload, the message size is now at 338 bytes, the difference is almost neglectable. However, this might change in different scenarios, for instance, if you add more strings inside a message.

Depending on the requirements and whether third-party solutions can be added to the project, other options are available.

In case the project resides “within the Qt world” and the whole flow of data is determined and not about to change, QDataStream is a viable option.

Adding support for this in the SensorInformation class requires two additional operators

QDataStream &operator<<(QDataStream &, const SensorInformation &);
QDataStream &operator>>(QDataStream &, SensorInformation &);

The implementation is straightforward as well. Below it is shown for the serialization:

QDataStream &operator<<(QDataStream &out, const SensorInformation &item)
{
    QDataStream::FloatingPointPrecision prev = out.floatingPointPrecision();
    out.setFloatingPointPrecision(QDataStream::DoublePrecision);
    out << item.m_id
        << item.m_ambientTemperature
        << item.m_objectTemperature
        << item.m_accelerometerX
        << item.m_accelerometerY
        << item.m_accelerometerZ
        << item.m_altitude
        << item.m_light
        << item.m_humidity;
    out.setFloatingPointPrecision(prev);
    return out;}

 

Consulting the benchmarks, using QDataStream resulted in only 26 msecs for this test case, which is close to 10 times faster to textual JSON. Furthermore, the average message size is only 84 bytes, compared to 290. Hence, if above limitations are acceptable, QDataStream is certainly a viable option.

If the project lets you add in further third-party components, one of the most prominent serialization solutions is Google’s Protocol Buffers (protobuf).

To add protobuf to our solution a couple of changes need to be done. First, protobuf uses an IDL to describe the structures of data or messages. The SensorInformation design is

syntax = "proto2";

package serialtest;

message Sensor {
    required string id = 1;
    required double ambientTemperature = 2;
    required double objectTemperature = 3;
    required double accelerometerX = 4;
    required double accelerometerY = 5;
    required double accelerometerZ = 6;
    required double altitude = 7;
    required double light = 8;
    required double humidity = 9;
}

To add protobuf’s code generator (protoc) to a qmake project, you must add an extra compiler step similar to this:

PROTO_FILE = sensor.proto
protoc.output = $${OUT_PWD}/${QMAKE_FILE_IN_BASE}.pb.cc
protoc.commands = $${PROTO_PATH}/bin/protoc -I=$$relative_path($${PWD}, $${OUT_PWD}) --cpp_out=. ${QMAKE_FILE_NAME}
protoc.variable_out = GENERATED_SOURCES
protoc.input = PROTO_FILE
QMAKE_EXTRA_COMPILERS += protoc

Next, to have a comparable benchmark in terms of object size, the generated struct is used as a member for a SensorInformationProto class, which inherits QObject, just like for the QDataStream and JSON example.

class SensorInformationProto : public QObject
{
    Q_OBJECT
    Q_PROPERTY(double ambientTemperature READ ambientTemperature WRITE setAmbientTemperature NOTIFY ambientTemperatureChanged)
[...]

public:
    SensorInformationProto(const std::string &pr);
[...]

     std::string serialize() const;
 [...]

private:
    serialtest::Sensor m_protoInfo;
};

The serialization function of protoInfo is generated by protoc, so the step to create the payload to be transmitted looks like this:

std::string SensorInformationProto::serialize() const
{
    std::string res;
    m_protoInfo.SerializeToString(&res);
    return res;
}

 

Note that compared to the previous solutions, protobuf uses std::string. This means you are losing capabilities of QString, unless the string is stored as a byte array (manual conversion is required). Then again, this will slow down the whole process due to parsing.

From a performance perspective, the benchmarks results look promising. The 10.000 items benchmark only takes 5 ms, with an average message size of 82 bytes.

As a summary, the following table visualizes the various approaches:

Payload SizeTime(ms)
JSON (text)346263
JSON (binary)338125
QDataStream8426
Protobuf825

 

One promising alternative is CBOR, which is currently getting implemented by Thiago Macieira for Qt 5.12. However, as development is in progress it has been too early to be included in this post. From discussions on our mailing list, results are looking promising though, with a significant performance advantage over JSON, but with all its benefits.

We have seen various approaches to serialize data into the payload of an MQTT message. Those can be done purely within Qt, or with external solutions (like protobuf). Integration of external solutions into Qt is easy.

As a final disclaimer, I would like to highlight that those benchmarks are all based on the scenario of the sensor demo. The amount of data values per message is fairly small. If those structs are bigger in size, the results might differ and different approaches might lead to the better results.

In our next installment, we will be looking at message integration with DDS. For an overview of all the articles in our automation mini-series, please check out Lars’ post.

The post Serialization in and with Qt appeared first on Qt Blog.


The Qt Company Blog: Write your own Python bindings

$
0
0

Hi.

In a previous blog post we touched upon the topic of creating Python bindings for the Qt libraries.

Today however, we’ll take a sneak peek at how you can create bindings for your own project.

We are happy to announce that Qt for Python will also include Shiboken– our binding generation tool.

Read the material below and you’ll obtain an understanding of how to generate Python bindings for a simple C++ library. Hopefully it will encourage you to do the same with custom libraries of your own.

As with any Qt project we are happy to review contributions to Shiboken, thus improving it for everyone.

Sample library

icecream
For the purposes of this post, we will use a slightly nonsensical custom library called Universe. It provides two classes: Icecream and Truck.
Icecreams are characterized by a flavor. And Truck serves as a vehicle of Icecream distribution for kids in a neighborhood. Pretty simple.

We would like to use those classes inside Python though. A use case would be adding additional ice cream flavors or checking whether ice cream distribution was successful.

In simple words, we want to provide Python bindings for Icecream and Truck, so that we can use them in a Python script of our own.

We will be omitting some content for brevity, but you can check the full source code inside the repository under pyside-setup/examples/samplebinding.

The C++ library

First, let’s take a look at the Icecream header:

class Icecream
{
public:
    Icecream(const std::string &flavor);
    virtual Icecream *clone();
    virtual ~Icecream();
    virtual const std::string getFlavor();

private:
    std::string m_flavor;
};

and the Truck header:

class Truck {
public:
    Truck(bool leaveOnDestruction = false);
    Truck(const Truck &other);
    Truck& operator=(const Truck &other);
    ~Truck();

    void addIcecreamFlavor(Icecream *icecream);
    void printAvailableFlavors() const;

    bool deliver() const;
    void arrive() const;
    void leave() const;

    void setLeaveOnDestruction(bool value);
    void setArrivalMessage(const std::string &message);

private:
    void clearFlavors();

    bool m_leaveOnDestruction = false;
    std::string m_arrivalMessage = "A new icecream truck has arrived!\n";
    std::vector m_flavors;
};

Most of the API should be easy enough to understand, but we’ll summarize the important bits:

  • Icecream is a polymorphic type and is intended to be overridden
  • getFlavor() will return the flavor depending on the actual derived type
  • Truck is a value type that contains owned pointers, hence the copy constructor and co.
  • Truck stores a vector of owned Icecream objects which can be added via addIcecreamFlavor()
  • The Truck’s arrival message can be customized using setArrivalMessage()
  • deliver() will tell us if the ice cream delivery was successful or not

Shiboken typesystem

To inform shiboken of the APIs we want bindings for, we provide a header file that includes the types we are interested in:

#ifndef BINDINGS_H
#define BINDINGS_H
#include "icecream.h"
#include "truck.h"
#endif // BINDINGS_H

In addition, shiboken also requires an XML typesystem file that defines the relationship between C++ and Python types:

The first important thing to notice is that we declare "bool" and "std::string" as primitive types.
A few of the C++ methods use these as parameter / return types and thus shiboken needs to know about them. It can then generate relevant conversion code between C++ and Python.
Most C++ primitive types are handled by shiboken without requiring additional code.

Next, we declare the two aforementioned classes. One of them as an “object-type” and the other as a “value-type”.

The main difference is that object-types are passed around in generated code as pointers, whereas value-types are copied (value semantics).

By specifying the names of the classes in the typesystem file, shiboken will automatically try to generate bindings for all methods declared in the classes, so there is no need
to mention all the method names manually…

Unless you want to somehow modify the function. Which leads us to the next topic: ownership rules.

Shiboken can’t magically know who is responsible for freeing C++ objects allocated in Python code. It can guess, but it’s not always the correct guess.
There can be many cases: Python should release the C++ memory when the ref count of the Python object becomes zero. Or Python should never delete the C++ object assuming that it will
be deleted at some point inside the C++ library. Or maybe it’s parented to another object (like QWidgets).

In our case the clone() method is only called inside the C++ library, and we assume that the C++ code will take care of releasing the cloned object.

As for addIcecreamFlavor(), we know that a Truck owns an Icecream object, and will remove it once the Truck is destroyed. Thus again, the ownership is set to “c++.”
If we didn’t specify the ownership rules, in this case, the C++ objects would be deleted when the corresponding Python names go out of scope.

Building

To build the Universe custom library and then generate bindings for it, we provide a well-documented, mostly generic CMakeLists.txt file, which you can reuse for your own libraries.

It mostly boils down to calling “cmake .” to configure the project and then building with the tool chain of your choice (we recommend the ‘(N)Makefiles’ generator though).

As a result of building the project, you end up with two shared libraries: libuniverse.(so/dylib/dll) and Universe.(so/pyd).
The former is the custom C++ library, and the latter is the Python module that can be imported from a Python script.

Of course there are also intermediate files created by shiboken (the .h / .cpp files generated for creating the Python bindings). Don’t worry about them unless you need to
debug why something fails to compile or doesn’t behave as it should. You can submit us a bug report then!

More detailed build instructions and things to take care of (especially on Windows) can be found in the example README.md file.

And finally, we get to the Python part.

Using the Python module

The following small script will use our Universe module, derive from Icecream, implement virtual methods, instantiate objects, and much more:

from Universe import Icecream, Truck

class VanillaChocolateIcecream(Icecream):
    def __init__(self, flavor=""):
        super(VanillaChocolateIcecream, self).__init__(flavor)

    def clone(self):
        return VanillaChocolateIcecream(self.getFlavor())

    def getFlavor(self):
        return "vanilla sprinked with chocolate"

class VanillaChocolateCherryIcecream(VanillaChocolateIcecream):
    def __init__(self, flavor=""):
        super(VanillaChocolateIcecream, self).__init__(flavor)

    def clone(self):
        return VanillaChocolateCherryIcecream(self.getFlavor())

    def getFlavor(self):
        base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor()
        return base_flavor + " and a cherry"

if __name__ == '__main__':
    leave_on_destruction = True
    truck = Truck(leave_on_destruction)

    flavors = ["vanilla", "chocolate", "strawberry"]
    for f in flavors:
        icecream = Icecream(f)
        truck.addIcecreamFlavor(icecream)

    truck.addIcecreamFlavor(VanillaChocolateIcecream())
    truck.addIcecreamFlavor(VanillaChocolateCherryIcecream())

    truck.arrive()
    truck.printAvailableFlavors()
    result = truck.deliver()

    if result:
        print("All the kids got some icecream!")
    else:
        print("Aww, someone didn't get the flavor they wanted...")

    if not result:
        special_truck = Truck(truck)
        del truck

        print("")
        special_truck.setArrivalMessage("A new SPECIAL icecream truck has arrived!\n")
        special_truck.arrive()
        special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream"))
        special_truck.printAvailableFlavors()
        special_truck.deliver()
        print("Now everyone got the flavor they wanted!")
        special_truck.leave()

After importing the classes from our module, we create two derived Icecream types which have customized “flavours”.

We then create a truck, add some regular flavored Icecreams to it, and the two special ones.

We try to deliver the ice cream.
If the delivery fails, we create a new truck with the old one’s flavors copied over, and a new *magical* flavor that will surely satisfy all customers.

The script above succinctly shows usage of deriving from C++ types, overriding virtual methods, creating and destroying objects, etc.

As mentioned above, the full source and additional build instructions can be found in the project repository under pyside-setup/examples/samplebinding.

We hope that this small introduction showed you the power of Shiboken, how we leverage it to create Qt for Python, and how you could too!

Happy binding!

The post Write your own Python bindings appeared first on Qt Blog.

The Qt Company Blog: Meet us at TU Automotive Detroit 2018 – Booth #B136

$
0
0

meetqt_tuautomotive_boston2018_facebook_1200x900_shared-img

Are you going to TU Automotive Detroit this year? So are we! Join us at the Qt booth #B136, have a chat and check out what’s new in the world of automotive HMIs with our latest demos #builtWithQt. 

  • A certifiably functionally safe digital cockpit with Hypervisor. Build multi-process UIs and incorporate external applications in a certified functionally safe two-screen UI. 
  • E-bike with fastboot. An E-bike instrument cluster concept designed and implemented with Qt Quick, that shows how great an HMI on a low-end SoC, even without a GPU, can look.  

If you are attending the event and would like to set up a meeting with us contact Chuck Mallory, Director of Strategic Accounts, Automotive, at Chuck.Mallory@qt.io or 1(419) 305-0018.   

Looking forward to seeing you there! 

The post Meet us at TU Automotive Detroit 2018 – Booth #B136 appeared first on Qt Blog.

The Qt Company Blog: QML and Qt for Python interaction

$
0
0

Besides QtWidgets for desktop applications, Qt has another UI technology, QML.
Today, I would like to show how QML interacts with Qt for Python, roughly based on the tutorial example declarative/extending/chapter3-bindings.

First, let’s have a look at the typical boiler plate code for loading a .qml file. We instantiate a QGuiApplication and a QQuickView.
We set its resize mode property to SizeRootObjectToView so that the QML element is expanded to the view size.

app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)

We then instruct the view to load the QML file, using the method setSource.
Since a QML file typically is to be found next to the Python script, we construct a complete path using functions of the os module:

current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'app.qml')
view.setSource(QUrl.fromLocalFile(qmlFile))
if view.status() == QQuickView.Error:
    sys.exit(-1)

Now, the view can be shown and the application run. To ensure the correct destruction order, del must be invoked on the view object before quitting the application

view.show()
res = app.exec_()
del view
sys.exit(res)

With this code, we can display QML files. For example, a minimal hello world is shown when creating app.qml as follows:

import QtQuick 2.0

Text {
    text : 'Hello, world!'
}

Extending QML by using classes written in Python

Let’s implement something on top of QQuickPaintedItem:

class PieChart (QQuickPaintedItem):
    def __init__(self, parent = None):
        QQuickPaintedItem.__init__(self, parent)
        self.color = QColor()

    def paint(self, painter):
        pen = QPen(self.color, 2)
        painter.setPen(pen);
        painter.setRenderHints(QPainter.Antialiasing, True);
        # From drawPie(const QRect &rect, int startAngle, int spanAngle)
        painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1),
            90 * 16, 290 * 16);

    def getColor(self):
        return self.color

    def setColor(self, value):
        if value != self.color:
            self.color = value
            self.update()
            self.colorChanged.emit()

    colorChanged = Signal()
    color = Property(QColor, getColor, setColor, notify=colorChanged)

This overrides the QQuickPaintedItem.paint() method to draw simple pie chart. The color is defined as property so that it is exposed to Qt. To make the type known to QML, we insert:

qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart');

right after creating the QGuiApplication.

app.qml can then be changed to:

import Charts 1.0
import QtQuick 2.0

Item {
    width: 300; height: 200

    PieChart {
        id: chartA
        width: 100; height: 100
        color: "red"
        anchors.centerIn:parent
    }

    MouseArea {
        anchors.fill: parent
        onClicked: { chartA.color = "blue" }
    }

    Text {
        anchors {
            bottom: parent.bottom;
            horizontalCenter: parent.horizontalCenter;
            bottomMargin: 20
        }
        text: "Click anywhere to change the chart color"
    }
}

for our custom type to appear.
Additionally, clicking with the mouse will change the color property.

The post QML and Qt for Python interaction appeared first on Qt Blog.

The Qt Company Blog: Generating Third-Party Attribution Documents

$
0
0

In this post, I’ll show you how to use the qtattributionsscanner tool and Python to generate an attribution document for third-party code in Qt.

Qt and Third-Party Code

Qt is available under both opensource and commercial licenses. While commercial users are free to hide their use of Qt, GPL and LGPL mandate that the use of Qt is properly attributed. In addition, several Qt modules contain third-party code that are bundled under their own licenses. We make sure that the licenses are liberal, so that they do not restrict the use of Qt too much. However, several of them do require attribution, too. Typically, in the documentation of the final product.

We actually go to a great length to make sure that third-party code is correctly attributed in our documentation. We have a process in place that requires any change of third-party code to be carefully reviewed. Additions of new third-party code to a Qt library, or significant updates, need to be approved by Lars Knoll, the chief maintainer of the Qt Project. We use tools like Fossology to double check correct attributions. All third-party code will be listed in the documentation of the respective Qt module, but also in the Licenses used in Qt overview section of the documentation. Significant changes of third-party modules are listed in the respective modules change log. Starting with Qt 5.11, we also will list changes in a separate documentation page.

If you bundle Qt in your application or device, you also need to provide these attributions – usually in the form of an attribution section of your documentation. The most straightforward way to create such a document is to copy the sections in the Qt documentation. However, this is a lot of work and can lead to errors. Luckily, there is now a cleaner way. Since Qt 5.9, the attributions are not written in plain qdoc markup. Instead, they are saved as qt_attribution.json files that are located close to the actual source code. The format of these JSON files is simple and documented (see QUIP-7). Now we just need an application that finds the files and generates attribution documents in a format of your choice.

qtattributionsscanner

It turns out that we already have an application for the collection of qt_attribution.json files: The qtattributionsscanner command line tool. You can find it in the bin directory of Qt.

When you specify a source directory for the tool, it recursively searches for qt_attribution.json files in there, and parses them. In addition, it takes an -output-format parameter, which currently supports qdoc and json as arguments. qdoc output is the default, because the tool was developed for generating Qt documentation. json generates a document in the same format as the input files. As a result, the attributions from the directory tree are placed into one document.

You might ask yourself, how can you generate other formats besides json and qdoc? My first hack, when I had the need to generate a PDF, was to add a markdown argument to qtattributionsscanner. Markdown is easy to read by itself, and there are tools available that convert it to HTML, which in turn can be used to generate a PDF. Anyhow, this is just one format, and the exact layout and content were hard-coded to my needs, so I surely didn’t want to merge this. Wouldn’t it be more flexible to use a template engine, so that you can generate attribution files with the exact format and layout you want?

qtattributionsformatter

What we want is an application that generates documents out of a JSON document and a template file. In the spirit of “not reinventing the wheel”, let’s use a language and library that makes this easy. I’ve been going for Python, using the Jinja2 templating engine. This is the Python file for setting up the engine:

import argparse
import io
import json
import os
import sys
from jinja2 import Environment, FileSystemLoader, Template

parser = argparse.ArgumentParser()
parser.add_argument("-f", "--file", nargs="?", help="qt_attribution.json file",
                    type=argparse.FileType('r'), default=sys.stdin)
parser.add_argument("-o", "--out", nargs="?", help="file to write to",
                    type=argparse.FileType('w'), default=sys.stdout)
parser.add_argument("-t", "--template", help="template file to use", default="markdown.md")
parser.add_argument("-v", "--verbose", action="store_true")
args = parser.parse_args()

# Set up jinja2
env = Environment(
  loader = FileSystemLoader(os.path.dirname(os.path.realpath(__file__)) + "/templates")
)
template = env.get_template(args.template)

# Read in qt_attribution.json file
attributions = json.load(args.file)

# Load content of license files directly into the structure
for entry in attributions:
  if entry['LicenseFile']:
    if (args.verbose):
      sys.stderr.write("Loading " + entry['LicenseFile'] + "...\n")
    with io.open(entry['LicenseFile'], mode='r', encoding='utf-8', errors='replace') as content:
      entry['LicenseText'] = content.read()

# Render
result = template.render(attributions = attributions)
args.out.write(result.encode('UTF8'))

And this is the markdown.md file template:

# Attributions for Qt Libraries

{% for entry in attributions -%}
{%- if "libs" in entry.QtParts -%}
## {{entry.Name}}

Copyright

```
{{entry.Copyright}}
```

License: {{entry.License}}

```
{{entry.LicenseText}}
```
{%- endif %}
{%- endfor %}

With {%- if "libs" in entry.QtParts -%} ... %{-endif}, we filter out attributions that are not part of Qt libraries, but examples, tools, or tests.

You can also find the sources at https://git.qt.io/kakoehne/qtattributionsformatter.

Putting It Together

To generate a list of attributions in Qt in Markdown, we can now combine the qtattributionsscanner for the collection part and the new qtattributionsformatter.py for the formatting part:


qtattributionsscanner --output-format json qt-everywhere-src-5.11.0-rc1/ | python qtattributionsformatter.py > qt_attributions.md

Outlook

This was easy enough. So you might ask yourself why isn’t this part of Qt yet, in this form or in a similar form? That is because there are some shortcomings:

  • Chromium uses its own file format, which qtattributionsscanner does not understand yet. Therefore, the output does not include third-party code inside Qt WebEngine yet.
  • You need a Qt source code checkout. I think we should package the JSON files as part of the build artifacts so that you can also generate documentation for a binary installation of Qt.
  • The attribution text is unnecessarily long, because a lot of license texts are duplicated.
  • When running on the default Qt checkout, the tool will pick up attributions for all Qt libraries, even if your application does not use a particular library. For now, you can limit this by either tweaking the source tree or adding some basic filtering to Python. Int the long run, this should be done automatically for you. The deployqt tools (windeploqt, macdeployqt…) can determine which libraries to package and similar logic could be used for generating code attribution documentation.
  • Even if you just take the libraries into account, there might be code that your Qt build doesn’t use. A lot of the third party code is in fact optional and only used on some platforms or in some setups.

The last issue raises some interesting questions. Should we use the Qt configuration system to select the necessary attributions? Or should we use Quartermaster, which uses a build graph to determine which attributions are needed? How big of a problem do ‘false positives’ present?

Even though more research is needed before making the generation of attribution files an official feature, I hope anybody struggling with this issue will find this proof-of-concept helpful.

The post Generating Third-Party Attribution Documents appeared first on Qt Blog.

KDAB on Qt: KDAB at Italian Cpp 2018

$
0
0

KDAB is proud to be bronze sponsor at Italian C++ Conference, the largest conference in Italy specifically focused on C++ development for professionals, students and businesses using C++.

It’s free, organized by the Italian C++ community, and there’s Italian icecream to think about too… It’s an offer you can’t refuse 😉

Sign up and see you in Milan in June!

The post KDAB at Italian Cpp 2018 appeared first on KDAB.

Viewing all 15410 articles
Browse latest View live