Qt Quick’s QML language makes it easy to do many things, especially fancy animated user interfaces. However, some things either can’t be done or are not suitable for implementing in QML, such as:
- Implementing performance critical functions where native code is desired for efficiency.
As we’ll see, Qt makes it quite easy to expose C++ code to QML. In this blog post I will show an example of doing this with a small but functional application.
The example is written for Qt 5 and uses the Qt Quick Components so you will need at least Qt version 5.1.0 to run it.
To expose a C++ type having properties, methods, signals, and/or slots to the QML environment, the basic steps are:
- Define a new class derived from QObject.
- Put the Q_OBJECT macro in the class declaration to support signals and slots and other services of the Qt meta-object system.
- Declare any properties using the Q_PROPERTY macro.
- Call qmlRegisterType() in your C++ main program to register the type with the Qt Quick engine.
For all the details I refer you to the Qt documentation section Exposing Attributes of C++ Types to QML and the Writing QML Extensions with C++ tutorial.
Ssh Key Generator
For our code example, we want a small application that will generate ssh public/private key pairs using a GUI. It will present the user with controls for the appropriate options and then run the program ssh-keygen to generate the key pair.
I implemented the user interface using the new Qt Quick Controls since it was intended as a desktop application with a desktop look and feel. I initially developed the UX entirely by running the qmlscene program directly on the QML source.
The UI prompts the user for the key type, the file name of the private key to generate and an optional pass phrase, which needs to be confirmed.
The C++ Class
Now that have the UI, we will want to implement the back end functionality. You can’t invoke an external program directly from QML so we have to write it in C++ (which is the whole point of this example application).
First, we define a class that encapsulates the key generation functionality. It will be exposed as a new class KeyGenerator in QML. This is done in the header file KeyGenerator.h below.
// Simple QML object to generate SSH key pairs by calling ssh-keygen.
class KeyGenerator : public QObject
Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged)
Q_PROPERTY(QStringList types READ types NOTIFY typesChanged)
Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
Q_PROPERTY(QString passphrase READ filename WRITE setPassphrase NOTIFY passphraseChanged)
void setType(const QString &t);
void setFilename(const QString &f);
void setPassphrase(const QString &p);
void keyGenerated(bool success);
Next, we need to derive our class from QObject. We declare any properties that we want and the