Integrating C++ with QML

来源:互联网 发布:上饶网络教育报名时间 编辑:程序博客网 时间:2024/04/30 05:37

Qt quick中C++与QML的整合。

出自:
http://www.ics.com/blog/integrating-c-qml

这里写图片描述

把大象装冰箱里总共分四步:
1. 定义一个类,继承自QObject。
2. 在定义的类中声明Q_OBJECT,这样可以支持signals 和slots和meta-object system。
3. 通过Q_PROPERTY定义一些属性。
4. 在main程序中调用qmlRegisterType() 注册。

keygenerator.h

#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

keygenerator.cpp

#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;}

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("qrc:/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;}

main.qml

// SSH key generator UIimport QtQuick 2.1import QtQuick.Controls 1.0import QtQuick.Layouts 1.0import QtQuick.Dialogs 1.0import com.ics.demo 1.0ApplicationWindow {    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: [ "All files (*)" ]        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()}

.pro文件

TEMPLATE = appQT += qml quickCONFIG += c++11QT += widgetsSOURCES += main.cpp \    keygenerator.cppRESOURCES += qml.qrc# Additional import path used to resolve QML modules in Qt Creator's code modelQML_IMPORT_PATH =# Default rules for deployment.include(deployment.pri)HEADERS += \    keygenerator.h
0 0