setContextProperty : why is a method of a contextProperty not recognized ?
-
hi !
I created two C++ class which instanciates two others as ContextProperties.
i can call a method of one of the class from the QML and it works fine when I launch it with a button. If I do the same with a method of the other object,
TypeError: Property 'savePreset' of object VIEW::PresetModel<adress> is not a function. Why ?Here are the codes :
setContextProperties :MainModelView* mp_mainModel; PresetModel* mp_presetModel; QQmlContext::PropertyPair m_mainModelProperty, m_presetModelProperty;
this->engine()->addImportPath(QString(QML_HOME)); mp_mainModel = new MainModelView(this); mp_presetModel = new PresetModel(this); QVector<QQmlContext::PropertyPair> w_properties; if (mp_mainModel && mp_mainModel) { m_mainModelProperty.name = "MainModel"; m_mainModelProperty.value = QVariant::fromValue(mp_mainModel); w_properties.append(m_mainModelProperty); m_presetModelProperty.name = "PresetModel"; m_presetModelProperty.value = QVariant::fromValue(mp_presetModel); w_properties.append(m_presetModelProperty); this->engine()->rootContext()->setContextProperties(w_properties); //this->engine()->rootContext()->setContextProperty("MainModel",mp_mainModel); //this->engine()->rootContext()->setContextProperty("PresetModel", mp_presetModel);
(should I use two setContextProperty or one setContextProperties ? the documentation says it's better to set everything at one time but I have to create a vector, two objects, two QVariant casts... is it really more efficient ?)
Prototype of the methods of MainModelView that is working fineQ_INVOKABLE void nameOfTheMethod(void);
QML programm that calls the method that works
EditPanelButton { id: reset_button width: position === Qt.LeftEdge || position === Qt.RightEdge ? parent.width/1.5 : parent.height/1.5 height: width x: position === Qt.LeftEdge || position === Qt.RightEdge ? parent.width/2-width/2 : parent.width-width-10 y: position === Qt.LeftEdge || position === Qt.RightEdge ? parent.height-height-10 : parent.height/2-height/2 text: "RESET" onClicked: {MainModel.resetParameters();console.log("reset_button clicked")} }
and this call doesn't work
EditPanelButton { id: save_preset x: position === Qt.LeftEdge || position === Qt.RightEdge ? limit3.x : limit3.x + 10 y: position === Qt.LeftEdge || position === Qt.RightEdge ? limit3.y + 10 : limit3.y width: position === Qt.LeftEdge || position === Qt.RightEdge ? parent.width/3 : parent.height/3 height: width image: "../../resources/save-128.png" onClicked: { PresetModel.savePreset(); preset_view.currentIndex = preset_view.count-1;console.debug("EditPanel savepreset clicked") } }
how can I launch savePreset() as I launch resetParameters() ?
-
Can you show what is the PresetModel header file ? I suspect the issue with declaration of savePreset().
Can you try registering the objects using setContextProperty & check it works ?
-
-
Thank you very much for your answers
@dheerendra sure, here is the declaration of the class
class PresetModel : public QAbstractListModel { Q_OBJECT private: QQuickView * mp_view; QList<Preset> m_preset_list; /*! * \brief constructeur par copie * * constructeur par copie privé * * \param [IN] air_presetModel : référence à l'objet à copier. */ PresetModel(const PresetModel& air_presetModel); Preset* mp_preset_base; public: enum t_presetRole { NameRole = Qt::UserRole + 1 } mstruct_roles; static const int ms_NameRole = Qt::UserRole +1; /*! * \brief constructeur * * \param [IN] aip_view : pointeur sur la QQuickView correspondant à la fenêtre principale * \param [IN] aip_parent : parent QObject de la classe, null par défaut */ PresetModel(QQuickView* aip_view, QObject* aip_parent = nullptr); /*! * \brief donne le nombre d'éléments du model */ ~PresetModel(); /*! * \brief ajoute un modèle Preset à la fin de la QList * * \param [IN] aip_p : référence const sur le Preset à ajouter */ void addPreset(const Preset& air_p); /*! * \brief donne le nombre d'éléments du model * * \param [IN] air_parent : QModelIndex& qui localise les données dans le model de données * \return int : nombre de lignes du parent */ int rowCount(const QModelIndex& air_parent = QModelIndex())const override; /*! * \brief donne accès à l'objet enregistré sous un certain index * * \param [IN] air_index : QModelIndex& qui localise les données dans le model de données * _param [IN] ai_role : int correspondant au role. Aucune idée de ce que c'est que cette histoire * \return QVariant : nom de l'Item enregistré à l'index donné si tout va bien. Sinon, un QVariant vide */ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; /*! * \brief getter de mstruct_roles * * \return t_presetRole : contenu de la structure. A savoir un integer */ t_presetRole roleName(void); /*! * \brief initilialise un élément de base dans la liste * */ void setPresetBase(void); /*! * \brief * * \param ai_index correspond à la configuration à charger */ Q_INVOKABLE void applyPreset(int ai_index); /*! * \brief sauvegarde la configuration actuelle */ Q_INVOKABLE void savePreset(void); /*! * \brief charge les paramètres des items QML depuis un fichier * */ bool loadPresetFromFile(void); public slots: void onPresetChanged(); };
Can you try registering the objects using setContextProperty & check it works ?
I tried again, the behaviour of the program is exactly the same. Do you think i should use 2 setContextProperty instead of setContextProperties ?
@J-Hilk Yes, the methods are public
Here is the definition of the method savePreset that can't get CALLED. As you can see, it's the simplest I can do.void PresetModel::savePreset(void) { TRACE_DEBUG("presetModel::savePreset....................CALLED"); printf("but does nothing yet\n"); }