Ok folks, today we are talking about how to load custom QML file and integrate it into your main application? It is useful, for example, to create settings UI for different plugins, when each plugin requires its own UI
So, here is a code:
#ifndef QMLSETTINGSVIEW_H
#define QMLSETTINGSVIEW_H
#include <QObject>
#include <QQuickView>
#include <QQmlApplicationEngine>
#include <QQuickItem>
class QmlSettingsView: public QObject
{
Q_OBJECT
public:
QmlSettingsView(QObject *parent = 0);
~QmlSettingsView();
QQmlApplicationEngine *engine() const;
void setEngine(QQmlApplicationEngine *engine, const QString &qmlpath, const QString &finishedSignal);
void showSettings();
void hideSettings();
bool setSettingsProperty(const char *name, const QVariant &value);
QVariant settingsProperty(const char *name);
public slots:
virtual void settingsFinished() = 0;
QQuickWindow *parentWindow() const;
private:
QQuickView *view_;
QQmlApplicationEngine *engine_;
QQuickItem *root_;
QQuickWindow *parentWindow_;
};
#endif // QMLSETTINGSVIEW_H
#include "qmlsettingsview.h"
#include <QQmlContext>
QmlSettingsView::QmlSettingsView(QObject *parent):
QObject(parent)
, view_(0)
, engine_(0)
, root_(0)
, parentWindow_(0){
}
QmlSettingsView::~QmlSettingsView() {
if (view_)
view_->deleteLater();
}
QQmlApplicationEngine *QmlSettingsView::engine() const {
return engine_;
}
void QmlSettingsView::setEngine(QQmlApplicationEngine *engine, const QString &qmlpath, const QString &finishedSignal) {
engine_ = engine;
if (!engine_)
return;
if (view_) //already created
return;
engine_->clearComponentCache();
if (engine_->rootObjects().count() <= 0)
return;
QObject *topLevel = engine_->rootObjects().value(0);
parentWindow_ = qobject_cast<QQuickWindow *>(topLevel);
if (!parentWindow_)
return;
view_ = new QQuickView(engine, parentWindow_);
if (!view_)
return;
view_->setSource(QUrl(qmlpath));
if (view_->status() != QQuickView::Ready) {
return;
}
root_ = view_->rootObject();
QString f_ = finishedSignal;
f_ = f_.insert(0, "2");
//settingsFinished() must be implemented in child class
connect(root_, f_.toLatin1().data(), this, SLOT(settingsFinished()));
}
void QmlSettingsView::showSettings() {
if (!view_)
return;
view_->show();
}
void QmlSettingsView::hideSettings() {
if (!view_)
return;
view_->hide();
}
bool QmlSettingsView::setSettingsProperty(const char *name, const QVariant &value) {
if (!root_)
return false;
return root_->setProperty(name, value);
}
QVariant QmlSettingsView::settingsProperty(const char *name) {
if (!root_)
return false;
return root_->property(name);
}
QQuickWindow *QmlSettingsView::parentWindow() const {
return parentWindow_;
}
The main purpose to create the code was to implement UI logic for separate plugins, that’s why its naming
Usage example:
#include "qmlsettingsview/qmlsettingsview.h"
class GrayScaleFilterPluginSettings: public QmlSettingsView {
Q_OBJECT
public:
GrayScaleFilterPluginSettings(QObject *parent = 0);
virtual ~GrayScaleFilterPluginSettings();
void settingsFinished();
signals:
void finished();
};
define your new class somewhere in the main code:
GrayScaleFilterPluginSettings qmlsettingsview;
implementation
GrayScaleFilterPluginSettings::GrayScaleFilterPluginSettings(QObject *parent):
QmlSettingsView(parent) {
}
GrayScaleFilterPluginSettings::~GrayScaleFilterPluginSettings() {
}
void GrayScaleFilterPluginSettings::settingsFinished() {
emit finished();
}
connect finished signal to your main class slot, which will deal with the settings etc
connect(&qmlsettingsview, SIGNAL(finished()), this, SLOT(settingsClosed()));
here we show and hide our settings
void GrayScaleFilterPlugin::setupItem(QQmlApplicationEngine *engine) {
if (!engine)
return;
qmlsettingsview.setEngine(engine, "qrc:/gssettings.qml", "finished()");
qmlsettingsview.setSettingsProperty("width", qmlsettingsview.parentWindow()->width());
qmlsettingsview.setSettingsProperty("height", qmlsettingsview.parentWindow()->width());
qmlsettingsview.showSettings();
return;
}
void GrayScaleFilterPlugin::settingsClosed() {
qmlsettingsview.hideSettings();
}
setEngine() sets QML engine, path to your settings qml file and name of signal when the settings are gets closed.
You can read new properties in settingsClosed() slot and save them to file
That’s actually it at the moment
Feel free to ask a questions