Monthly Archives: January 2018

Integrating C++ with QML

Introduction

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:

  1. Getting access to functionality outside of the QML/JavaScript environment.
  2. Implementing performance critical functions where native code is desired for efficiency.
  3. Large and/or complex non-declarative code that would be tedious to implement in JavaScript.

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.

Overview

To expose a C++ type having properties, methods, signals, and/or slots to the QML environment, the basic steps are:

  1. Define a new class derived from QObject.
  2. Put the Q_OBJECT macro in the class declaration to support signals and slots and other services of the Qt meta-object system.
  3. Declare any properties using the Q_PROPERTY macro.
  4. 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.

#ifndef KEYGENERATOR_H
#define KEYGENERATOR_H

#include <QObject>
#include <QString>
#include <QStringList>

// Simple QML object to generate SSH key pairs by calling ssh-keygen.

class KeyGenerator : public QObject
{
    Q_OBJECT
    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)

public:
    KeyGenerator();
    ~KeyGenerator();

    QString type();
    void setType(const QString &t);

    QStringList types();

    QString filename();
    void setFilename(const QString &f);

    QString passphrase();
    void setPassphrase(const QString &p);

public slots:
    void generateKey();

signals:
    void typeChanged();
    void typesChanged();
    void filenameChanged();
    void passphraseChanged();
    void keyGenerated(bool success);

private:
    QString _type;
    QString _filename;
    QString _passphrase;
    QStringList _types;
};
#endif

Next, we need to derive our class from QObject. We declare any properties that we want and the associated methods. Notify methods become signals. In our case, we want to have properties for the selected key type, the list of all valid ssh key types, file name and pass phrase. I arbitrarily made the key type a string. It could have been an enumerated type but it would have made the example more complicated.

Incidentally, a new feature of the Q_PROPERTY macro in Qt 5.1.0 is the MEMBER argument. It allows specifying a class member variable that will be bound to a property without the need to implement the setter or getter functions. That feature was not used here.

We declare methods for the setters and getters and for signals. We also declare one slot called generateKey(). These will all be available to QML. If we wanted to export a regular method to QML, we could mark it with Q_INVOCABLE. In this case I decided to make generateKey() a slot since it might be useful in the future but it could have just as easily been an invocable method.

Finally, we declare any private member variables we will need.

C++ Implementation

Now let’s look at the implementation in KeyGenerator.cpp. Here is the source code:

#include <QFile>
#include <QProcess>
#include "KeyGenerator.h"

KeyGenerator::KeyGenerator()
    : _type("rsa"), _types{"dsa", "ecdsa", "rsa", "rsa1"}
{
}

KeyGenerator::~KeyGenerator()
{
}

QString KeyGenerator::type()
{
    return _type;
}

void KeyGenerator::setType(const QString &t)
{
    // Check for valid type.
    if (!_types.contains(t))
        return;

    if (t != _type) {
        _type = t;
        emit typeChanged();
    }
}

QStringList KeyGenerator::types()
{
    return _types;
}

QString KeyGenerator::filename()
{
    return _filename;
}

void KeyGenerator::setFilename(const QString &f)
{
    if (f != _filename) {
        _filename = f;
        emit filenameChanged();
    }
}

QString KeyGenerator::passphrase()
{
    return _passphrase;
}

void KeyGenerator::setPassphrase(const QString &p)
{
    if (p != _passphrase) {
        _passphrase = p;
        emit passphraseChanged();
    }
}

void KeyGenerator::generateKey()
{
    // Sanity check on arguments
    if (_type.isEmpty() or _filename.isEmpty() or
        (_passphrase.length() > 0 and _passphrase.length() < 5)) {
        emit keyGenerated(false);
        return;
    }

    // Remove key file if it already exists
    if (QFile::exists(_filename)) {
        QFile::remove(_filename);
    }

    // Execute ssh-keygen -t type -N passphrase -f keyfileq
    QProcess *proc = new QProcess;
    QString prog = "ssh-keygen";
    QStringList args{"-t", _type, "-N", _passphrase, "-f", _filename};
    proc->start(prog, args);
    proc->waitForFinished();
    emit keyGenerated(proc->exitCode() == 0);
    delete proc;
}

The constructor initializes some of the member variables. For fun, I used the new initializer list feature of C++11 to initialize the _types member variable which is of type QStringList. The destructor does nothing, at least for now, but is there for completeness and future expansion.

Getter functions like type() simply return the appropriate private member variable. Setters set the appropriate variables, taking care to check that the new value is different from the old one and if so, emitting the appropriate signal. As always, please note that signals are created by the Meta Object Compiler and do not need to be implemented, only emitted at the appropriate times.

The only non-trivial method is the slot generateKey(). It does some checking of arguments and then creates a QProcess to run the external ssh-keygen program. For simplicity and because it typically executes quickly, I do this synchronously and block on it to complete. When done, we emit a signal that has a boolean argument that indicates the key was generated and whether it succeeded or not.

QML Code

Now let’s look at the QML code in main.qml:

// SSH key generator UI

import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import QtQuick.Dialogs 1.0
import com.ics.demo 1.0

ApplicationWindow {
    title: qsTr("SSH Key Generator")

    statusBar: StatusBar {
    RowLayout {
        Label {
            id: status
            }
        }
    }

    width: 369
    height: 166

    ColumnLayout {
        x: 10
        y: 10

        // Key type
        RowLayout {
            Label {
                text: qsTr("Key type:")
            }
            ComboBox {
                id: combobox
                Layout.fillWidth: true
                model: keygen.types
                currentIndex: 2
            }
        }

        // Filename
        RowLayout {
            Label {
                text: qsTr("Filename:")
            }
            TextField {
                id: filename
                implicitWidth: 200
                onTextChanged: updateStatusBar()
            }
            Button {
                text: qsTr("&Browse...")
                onClicked: filedialog.visible = true
            }
        }

        // Passphrase
        RowLayout {
            Label {
                text: qsTr("Pass phrase:")
            }
            TextField {
                id: passphrase
                Layout.fillWidth: true
                echoMode: TextInput.Password
                onTextChanged: updateStatusBar()
            }

        }

        // Confirm Passphrase
        RowLayout {
            Label {
                text: qsTr("Confirm pass phrase:")
            }
            TextField {
                id: confirm
                Layout.fillWidth: true
                echoMode: TextInput.Password
                onTextChanged: updateStatusBar()
            }
        }

        // Buttons: Generate, Quit
        RowLayout {
            Button {
                id: generate
                text: qsTr("&Generate")
                onClicked: keygen.generateKey()
            }
            Button {
                text: qsTr("&Quit")
                onClicked: Qt.quit()
            }
        }

    }

    FileDialog {
        id: filedialog
        title: qsTr("Select a file")
        selectMultiple: false
        selectFolder: false
        nameFilters: 
        selectedNameFilter: "All files (*)"
        onAccepted: {
            filename.text = fileUrl.toString().replace("file://", "")
        }
    }

    KeyGenerator {
        id: keygen
        filename: filename.text
        passphrase: passphrase.text
        type: combobox.currentText
        onKeyGenerated: {
            if (success) {
                status.text = qsTr('<font color="green">Key generation succeeded.</font>')
            } else {
                status.text = qsTr('<font color="red">Key generation failed</font>')
            }
        }
    }

    function updateStatusBar() {
        if (passphrase.text != confirm.text) {
            status.text = qsTr('<font color="red">Pass phrase does not match.</font>')
            generate.enabled = false
        } else if (passphrase.text.length > 0 && passphrase.text.length < 5) {
            status.text = qsTr('<font color="red">Pass phrase too short.</font>')
            generate.enabled = false
        } else if (filename.text == "") {
            status.text = qsTr('<font color="red">Enter a filename.</font>')
            generate.enabled = false
        } else {
            status.text = ""
            generate.enabled = true
        }
    }

    Component.onCompleted: updateStatusBar()
}

The preceding code is a little long, however, much of the work is laying out the GUI components. The code should be straightforward to follow.

Note that we import com.ics.demo version 1.0. We’ll see where this module name comes from shortly. This makes a new QML type KeyGeneratoravailable and so we declare one. We have access to it’s C++ properties as QML properties, can call it’s methods and act on signals like we do withonKeyGenerated.

A more complete program should probably do a little more error checking and report meaningful error messages if key generation fails (we could easily add a new method or property for this). The UI layout could also be improved to make it properly resizable.

Our main program is essentially a wrapper like qmlscene. All we need to do to register our type with the QML engine is to call:

    qmlRegisterType<KeyGenerator>("com.ics.demo", 1, 0, "KeyGenerator");

This makes the C++ type KeyGenerator available as the QML type KeyGenerator in the module com.ics.demo version 1.0 when it is imported.

Typically, to run QML code from an executable, in the main program you would create a QGuiApplication and a QQuickView. Currently, to use the Qt Quick Components there is some additional work needed if the top level element is an ApplicationWindow or Window. You can look at the source code to see how I implemented this. I basically stripped down the code from qmlscene to the minimum of what was needed for this example.

Here is the full listing for the main program, main.cpp:

#include <QApplication>
#include <QObject>
#include <QQmlComponent>
#include <QQmlEngine>
#include <QQuickWindow>
#include <QSurfaceFormat>
#include "KeyGenerator.h"

// Main wrapper program.
// Special handling is needed when using Qt Quick Controls for the top window.
// The code here is based on what qmlscene does.

int main(int argc, char ** argv)
{
    QApplication app(argc, argv);

    // Register our component type with QML.
    qmlRegisterType<KeyGenerator>("com.ics.demo", 1, 0, "KeyGenerator");

    int rc = 0;

    QQmlEngine engine;
    QQmlComponent *component = new QQmlComponent(&engine);

    QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));

    component->loadUrl(QUrl("main.qml"));

    if (!component->isReady() ) {
        qWarning("%s", qPrintable(component->errorString()));
        return -1;
    }

    QObject *topLevel = component->create();
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);

    QSurfaceFormat surfaceFormat = window->requestedFormat();
    window->setFormat(surfaceFormat);
    window->show();

    rc = app.exec();

    delete component;
    return rc;
}

In case it is not obvious, when using a module written in C++ with QML you cannot use the qmlscene program to execute your QML code because the C++ code for the module will not be linked in. If you try to do this you will get an error message that the module is not installed.

Things to Consider When Looking for Affordable Auto Insurance and Best Auto Insurance Companies

Reliable and affordable auto insurance is hard to find if you dont have enough resources. By that, do you have what it takes to get you a reputable company on your side? Prior to joining different auto insurance companies, you need to understand that various insurance companies offer different rates. Therefore, it will be up to you to decide which insurance company you would like to go for.

There are a number of the best auto insurance tips that will absolutely help you obtain an enviable company that provides outstanding vehicle covers. To begin with, you have to perform a comprehensive research on the different insurance websites and compare some of the quotes provided and how best they will fit your budget, you and your car.

Having done this, you can advance ahead and combine all your policies together so as to earn yourself good discounts with your indemnity company when applying for auto insurance. Shopping around is another surefire way of obtaining a highly regarded insurance company for your car. Also, make sure you engage yourself to insurance companies that you find not only interesting but also provide affordable auto insurance to all its consumers.

Raising all your deductibles is also another positive way of getting yourself good car insurance since you will significantly lessen most of your premiums. If then again you have some troubles in obtaining the type of company that best fits you, then you can instead look for some help from an insurance broker who will in turn let you know of what companies have good rates in offers.

But most vital of all is to have a good understanding of what kind of cover you would want and that must be agree with the laws of the state that you reside. In fact, there are so many profitable discounts in offer from most insurance companies providing auto insurance, it will be up to you to choose the one that you find more comfortable with.

And if you are one of those individuals who regularly go for cover quotes through the Internet, then it is greatly believed that falling for a highly regarded company will be incredibly undemanding. Internet is one of the best ways of finding the best auto insurance and affordable auto insurance company. By that, searching insurance company will become handy if you know how to access the Internet and you can do this at the comfort of your home or at the office.

Technology For Women And What It Can Offer Us

The colour pink is often associated with women as more often than not, women look good in pink. Women who have great fashion senses are often eye catching and you may well have noticed that a woman’s fashion sense has begun to extend towards the gadgets that they carry. The rise of feminine technology has been growing steadily and is about to hit a crest. When you say feminine technology what is the first thing that comes to your mind? Pink gadgets!

Since the colour pink has long been associated with women, it doesn’t come as a surprise to see pink mobile phones, pink digital cameras, and pink laptops, among others that can be considered as part of feminine technology. Pink is a dainty colour, eye-candy if you like. Given the choice, fashionable women tend to want to carry trendy gadgets to veer away from the more macho-looking laptops or cellular phones. Women now find it tempting to have a pink gadget, like a pink laptop, to showcase their love for beauty. Most women are aware that most men find a woman to be more feminine if they are wearing something pink, and i have to admit there is something appealing about a confident women seen doing some work on a pink feminine laptop or making a business call with a pink mobile phone.

Technology need not be boring and with the advent of feminine technology, pink and all the other girly colours have become the in thing. Pink may be a favourite, but red is also becoming popular, as well as lavender or pastel colours. You will even see laptops that have designs on it; often utilising many different shades of pink or other feminine colours.

Wouldn’t it be great to take snapshots using your pink digital camera? You will now find digital cameras, mobile phones, and laptops in various shades of pink and as well as other girly colours so finding one that suits your personality is no longer the challenge that it once was. However do not, for a second, think that gadgets with a touch of femininity are lacking in the features or power department. A lot of popular brands now carry fashionable designs but still with the exact same technology and features as more masculine looking gadgets.

This is true especially for laptops. Pink laptops may look dainty and beautiful yet you can be sure that you can still surf the net with ease and do some office or school work simultaneously without having your workflow slowed by unresponsive technology. It is just as important to take note that when you shop for a gadget that will showcase your feminine side, make sure that you check the features as well as the prices first before settling with one particular unit.

So when you talk of feminine technology, it is not only about trends and beauty, functionality is also a must have and one that manufacturers are increasingly more aware of.

Launch of Remodeled Website by limoserviceoakland.net

Limoserviceoakland.net, a premier ground transportation provider, has recently launched their remodeled website. Their remodeled website aims to improve the user experience and offer better insight of their business model. Their remodeled website has tons of new features and user-friendly navigation structure to benefit the customers.

“Any business has to keep up with the improving technology in order to stay in the business. The basic idea behind remodeling the website was to make our services and fleet information available to the customers with utmost ease. The customers will find complete specifications and technical details with the images of the fleet in the new website for determining the profitability of the vehicle. Additionally, we have included many features that can help the customers in comparing the vehicles and choosing the best one for the tours. Of course, the best search engine optimization was also the main aspect behind the remodeling of the website.” – said Ruben, a manager of limoserviceoakland.net

They have used dynamic approach to remodel the website to make it visually appealing and informative for the customers. The remodeled website offers the benefit of accessing the required information with only a few clicks. Their remodeled website includes complete information about the services like wine tour, casino trips, airport transfers, concerts, sports events, night on the town and corporate events. Their website has dedicated pages focusing on the luxury transportation options for the occasions like wedding, birthday parties, proms, bachelor parties and bachelorette parties. Their new website has state-wise recommendation about the most popular destinations, hotels and restaurants for the benefits of the customers.

They have showcased their wide ranges of limo collection that includes Escalade Limo, Lincoln Stretch Limo, Rolls Limo, Hummer Limo, Range Rover Limo and Chrysler 300 Stretch Limo in their fleet. Some other fleet information like features available in 20 passenger party bus, 28 passenger party bus and 45 passenger party bus are also listed on their website with the high-definition images. The information about their wide range of exotic cars such as Bentley Flying Spur, Mercedes-Benz S500, Ranger Rover SUV, Rolls Royce Phantom, Ferrari and Lamborghini Gallardo are now available on their new website.

They have also included the complete information about the different tour packages and their features in the website for better understanding. The customers can now subscribe to their newsletter to know about the release of new packages, deals, services and fleet. They have also included the online vehicle reservation facility on the new website to offer the convenience of booking the most appropriate vehicle with utmost ease. The customers can visit http://www.limoserviceoakland.net to check out the new features of the remodeled website or book a limousine for tours and travels.

POSqx booming the restaurant industry with New point of sale technology

For running the restaurant in more advanced way, you need to use high-end best POS point of sale technology. A Point of sale technology can manage the lot in your restaurant fairly comfortably and precisely. Most importantly, New point of sale technology can process all sales made in your store be it credit card, debit card or cash payment. Unsurprisingly, the Business point of sale technology is equipped with a full payment processing system and from your part; you should take no chances in ensuring that the Best POS point of sale technology is fully safe for such processing.

Your customers may opt to pay through different means where it may be cash, credit cards or cash cards; even some of them may be your usual customers whom you will charge seldom. So, Best POS point of sale technology vendors gives sufficient fondness for collecting and processing payments in dissimilar modes. The New point of sale technology should also facilitate you to bring together payments from customers whose records are saved in the main database of the best restaurant management software.

Under standard conditions, your customer will dine in your restaurant, walk up to the cash-counter or the payment processing systems console and pay using his cash/credit card or simple cash. Now, if the customer pays in cash, the best Point of sale technology software will open up the cash-drawer robotically the moment the cashier enters the cash details in the console. For credit/debit card dealing out, you will get your customer’s card swiped in the system and the amount will be routinely updated in the best restaurant management software.

All POS inventory system is equipped with adequate security features to prevent mal-practices. As you get various reports on the data collected in the POS inventory system, any discrepancy will be easily noticeable to you. The information of your customers’ credit or debit cards is completely encrypted through the Business point of sale technology so that they can dine and enjoy in the restaurant generously. A number of best Point of sale technology are also equipped with online payment gateways to full transactions over the web from the POS inventory system console.

It is vital to run your restaurant with an optimized system offering the customer with an immense dining skill. So, to linger in the business fruitfully, you need to have Best POS point of sale technology besides efficient workforce and sufficient infrastructure. Ultimately, your New point of sale technology makes the difference and takes you towards achievement.

Tags:
Point of sale technology, New point of sale technology, Business point of sale technology, POS point of sale technology, Best POS point of sale technology, POS inventory system