Сначала это казалось простой задачей, но, честно говоря, я борюсь. У меня есть карта профилей, которую я загружаю при запуске, и профили можно добавлять и удалять во время выполнения. Эти профили должны быть указаны как RadioButtons или какой-либо другой элемент для выбора / редактирования в моем пользовательском интерфейсе.
Я пробовал использовать createQMLObject () во время цикла через геттер QVariantMap:
profile.h
#ifndef PROFILE_H
#define PROFILE_H
#include <QObject>
class Profile final : public QObject
{
Q_OBJECT
public:
Profile(QObject *parent = nullptr);
~Profile(){}
Profile(QString profileName = "default", QObject *parent = nullptr);
QString getProfileName() const;
void setProfileName(const QString &value);
private:
QString profileName;
};
#endif // PROFILE_H
profile. cpp
#include "profile.h"
Profile::Profile(QString profileName, QObject *parent)
: QObject(parent), profileName{ profileName }{}
QString Profile::getProfileName() const
{
return profileName;
}
void Profile::setProfileName(const QString &value)
{
profileName = value;
}
controller.h
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include "profile.h"
#include <QObject>
#include <QQmlEngine>
class Controller : public QObject
{
Q_OBJECT
public:
Controller(QObject *parent = nullptr);
~Controller(){}
static QObject* controllerSingletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine);
static Controller* instance();
Q_INVOKABLE void addProfile(QString profileName);
Q_INVOKABLE QVariantList getLoadedProfiles(){
QVariantList rval;
foreach (QString key, loadedProfiles.keys()) {
rval.append(QVariant::fromValue<Profile*>(loadedProfiles[key].get()));
}
return rval;
};
private:
QMap<QString, std::shared_ptr<Profile>> loadedProfiles;
signals:
};
#endif // CONTROLLER_H
контроллер. cpp
#include "controller.h"
Controller::Controller(QObject *parent) : QObject(parent){}
void Controller::addProfile(QString profileName)
{
std::shared_ptr<Profile> profile{std::make_shared<Profile>(profileName)};
loadedProfiles[profile->getProfileName()] = profile;
}
QObject* Controller::controllerSingletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return Controller::instance();
}
Controller* Controller::instance(){
static Controller* controller = new Controller();
return controller;
}
основной. cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <controller.h>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterSingletonType<Controller>("com.controller", 1, 0, "Controller", Controller::controllerSingletonProvider);
Controller::instance()->addProfile("Profile1");
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import com.controller 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Column {
id: radioButtonColumn
Component.onCompleted: {
for(var profile in Controller.getLoadedProfiles()){
var obj = Qt.createQmlObject('import QtQuick 2.12; RadioButton { id: '+ profile.getProfileName() +';
text: '+ profile.getProfileName() +'; }', radioButtonColumn, "dynamicSnippet1");
}
}
}
}
Я пробовал использовать сигнал, отправленный с моего синглтона контроллера с помощью Connections, но параметр сигнала не приходит. Однако я могу вызывать свои функции Controllers c ++ из qml. Я опубликую только изменения в предыдущем примере кода:
изменения main.qml:
Connections {
target: Controller
onProfileAdded: {
var obj = Qt.createQmlObject('import QtQuick 2.12; RadioButton { id: '+ profileName +';
text: '+ profileName +'; }', radioButtonColumn, "dynamicSnippet1");
console.log("Value changed")
}
}
изменения controller.h:
signals:
void profileAdded(QString &profileName);
};
контроллер. cpp изменения:
void Controller::addProfile(QString profileName)
{
std::shared_ptr<Profile> profile{std::make_shared<Profile>(profileName)};
loadedProfiles[profile->getProfileName()] = profile;
emit profileAdded(profileName);
}
основной. cpp изменения:
engine.load(url);
Controller::instance()->addProfile("Profile2");
return app.exec();
Edit: Любопытно, что мне пришлось изменить свой onProfileAdded в controller.h на profileAdded, чтобы сигнал работал. Однако я все еще не получаю параметр profileName в моем qml.
Я хотел бы спросить, как лучше всего справиться с таким требованием. Может быть, есть другой, более простой способ?