Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. " Error : Cannot assign [undefined] to QString " while communicating between C++ and QML

" Error : Cannot assign [undefined] to QString " while communicating between C++ and QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qmlc++qtquick2qproperty
6 Posts 3 Posters 3.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    Quentin91
    wrote on 13 May 2019, 13:39 last edited by
    #1

    Hi !

    I have a QML code whom I am trying to communicate with with a C++ code.
    i have especially some shared object accessed from the QML by :

    testText.text=anchor.message
    

    but when doing this, an error is printed in the console:
    Error: Cannot assign [undefined] to QString
    here is the c++ code of my Anchor class, from QObject

    //Anchor.h
    class Anchor :public QObject
    {
    	Q_OBJECT
    	Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged)
    public:
    	Anchor();
    	Q_INVOKABLE void clicked(/*const QString& clickedStr*/);
    	Q_INVOKABLE int getVal(void);
    
    	QString message(void);
    	void setMessage(QString);
    
    signals:
    	void signalAnchor(QString s);
    	void messageChanged();
    
    public slots:
    	void slotAnchor(QString s);
    private :
    	QString msg;
    };
    
    #include "Anchor.h"
    
    Anchor::Anchor() :msg("I'm da QString m8")
    {
    	TRACE_DEBUG("Construction de l'Anchor ")
    		if(msg!=nullptr) printQStr(msg)//it works and print the string in the console
    }
    
    Q_INVOKABLE void Anchor::clicked(/*const QString& clickedStr*/)
    {
    	qDebug("Méthode invocable appelee sur click");
    }
    
    void Anchor::slotAnchor(QString s)
    {
    	static int i = 0;
    	s.append(" ").append(QString::number(++i));
    	qDebug() << "qDebug  : " << s;
    	emit signalAnchor(s);
    }
    
    Q_INVOKABLE int Anchor::getVal(void)
    {
    	return 124;
    }
    
    QString Anchor::message(void)
    {
    	printf("getMessage\n");
    	return msg;
    }
    void Anchor::setMessage(QString str)
    {
    	msg = str;
    	emit Anchor::messageChanged();
    }
    
    void Anchor::messageChanged(void) {
    	printf("messageChanged\n");
    }
    

    here is the test functions called in the main:

    QGuiApplication app(ai_argc, aipp_argv);
    
    	QQmlApplicationEngine engine;
    	engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml"));
    	Anchor anchor;
    	QString  strCppQml = "transmission de chaine du C++ au QML reussie", strQmlCpp = "transmission de chaine du QML au C++ reussie";
    	anchor.setProperty("strQmlCpp", strQmlCpp);
    	engine.rootContext()->setContextProperty("strCppQml", strCppQml);
    //until now, everythin worked. The problem comes from the anchor, from the Q_PROPERTY
    	engine.rootContext()->setContextProperty("anchor", &anchor);
    	engine.load(QUrl(QML_TEST1_PATH));//the path is correct
    
    	return app.exec();
    

    So i am sure that the QString I'm trying to send is not empty. the object exists
    now, the QML

    import QtQuick 2.5
    import QtQuick.Window 2.5
    import "\Items" as Koala
    //import "../../Anchor"
    
    Window{
        property var value: anchor.getVal();
        visible: true
        id:mainWindow
        width: 150; height: 150
        color: "#000000"
    
        Connections{
            target: anchor
            onSignalAnchor:{
                signalText.text=s
                signalText.x=signalText.x+5;
            }
        }
        Text{
           id: testText
           color: "#ffffff"
           text: anchor.message
           anchors.centerIn: parent
           font.pointSize: 10
           visible: false
        }
        Text {
            id: signalText
            x: 27
            y: 102
            color: "#f0f0f0"
            width: 60
            height: 14
            font.pixelSize: 12
        }
        MouseArea{
            anchors.fill: parent
    
            onClicked:
            {
                anchor.clicked();
                testText.text=anchor.message//there it is!
                testText.visible=true;
                mainWindow.setGeometry(1200,330,500,400)
                signalText.text= value;
            }
            onDoubleClicked: anchor.slotAnchor("calling slotAnchor")
        }
    }
    

    Do you know where does that error comes from ? how can I fix it and FINALLY set an efficient communication ?
    Thanks for reading

    R 1 Reply Last reply 14 May 2019, 05:54
    0
    • M Offline
      M Offline
      mranger90
      wrote on 13 May 2019, 14:35 last edited by
      #2

      This is an immediate problem:

      void Anchor::messageChanged(void) {
      	printf("messageChanged\n");
      }
      

      You've provided a definition for the signal. I don't know how you got it to compile because I couldn't.
      Once I fixed that the code ran as I suppose it's supposed to.

      Q 1 Reply Last reply 13 May 2019, 14:59
      2
      • M mranger90
        13 May 2019, 14:35

        This is an immediate problem:

        void Anchor::messageChanged(void) {
        	printf("messageChanged\n");
        }
        

        You've provided a definition for the signal. I don't know how you got it to compile because I couldn't.
        Once I fixed that the code ran as I suppose it's supposed to.

        Q Offline
        Q Offline
        Quentin91
        wrote on 13 May 2019, 14:59 last edited by
        #3

        @mranger90 you're right, that's stupid.

        I changed it in an empty definition

        void Anchor::messageChanged(void) {}
        

        but I have the error anyway.
        I think I tried everything now. using qmlRegisterType to import my type, a Q_INVOKABLE method, using the Q_PROPERTY.
        In every case, i have this error : cannot assign [undefined] to type
        I tried with double, int, QString...

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mranger90
          wrote on 13 May 2019, 17:01 last edited by
          #4

          No, the point is that you have it defined at all. Signals should never have a body.

          1 Reply Last reply
          2
          • Q Quentin91
            13 May 2019, 13:39

            Hi !

            I have a QML code whom I am trying to communicate with with a C++ code.
            i have especially some shared object accessed from the QML by :

            testText.text=anchor.message
            

            but when doing this, an error is printed in the console:
            Error: Cannot assign [undefined] to QString
            here is the c++ code of my Anchor class, from QObject

            //Anchor.h
            class Anchor :public QObject
            {
            	Q_OBJECT
            	Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged)
            public:
            	Anchor();
            	Q_INVOKABLE void clicked(/*const QString& clickedStr*/);
            	Q_INVOKABLE int getVal(void);
            
            	QString message(void);
            	void setMessage(QString);
            
            signals:
            	void signalAnchor(QString s);
            	void messageChanged();
            
            public slots:
            	void slotAnchor(QString s);
            private :
            	QString msg;
            };
            
            #include "Anchor.h"
            
            Anchor::Anchor() :msg("I'm da QString m8")
            {
            	TRACE_DEBUG("Construction de l'Anchor ")
            		if(msg!=nullptr) printQStr(msg)//it works and print the string in the console
            }
            
            Q_INVOKABLE void Anchor::clicked(/*const QString& clickedStr*/)
            {
            	qDebug("Méthode invocable appelee sur click");
            }
            
            void Anchor::slotAnchor(QString s)
            {
            	static int i = 0;
            	s.append(" ").append(QString::number(++i));
            	qDebug() << "qDebug  : " << s;
            	emit signalAnchor(s);
            }
            
            Q_INVOKABLE int Anchor::getVal(void)
            {
            	return 124;
            }
            
            QString Anchor::message(void)
            {
            	printf("getMessage\n");
            	return msg;
            }
            void Anchor::setMessage(QString str)
            {
            	msg = str;
            	emit Anchor::messageChanged();
            }
            
            void Anchor::messageChanged(void) {
            	printf("messageChanged\n");
            }
            

            here is the test functions called in the main:

            QGuiApplication app(ai_argc, aipp_argv);
            
            	QQmlApplicationEngine engine;
            	engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml"));
            	Anchor anchor;
            	QString  strCppQml = "transmission de chaine du C++ au QML reussie", strQmlCpp = "transmission de chaine du QML au C++ reussie";
            	anchor.setProperty("strQmlCpp", strQmlCpp);
            	engine.rootContext()->setContextProperty("strCppQml", strCppQml);
            //until now, everythin worked. The problem comes from the anchor, from the Q_PROPERTY
            	engine.rootContext()->setContextProperty("anchor", &anchor);
            	engine.load(QUrl(QML_TEST1_PATH));//the path is correct
            
            	return app.exec();
            

            So i am sure that the QString I'm trying to send is not empty. the object exists
            now, the QML

            import QtQuick 2.5
            import QtQuick.Window 2.5
            import "\Items" as Koala
            //import "../../Anchor"
            
            Window{
                property var value: anchor.getVal();
                visible: true
                id:mainWindow
                width: 150; height: 150
                color: "#000000"
            
                Connections{
                    target: anchor
                    onSignalAnchor:{
                        signalText.text=s
                        signalText.x=signalText.x+5;
                    }
                }
                Text{
                   id: testText
                   color: "#ffffff"
                   text: anchor.message
                   anchors.centerIn: parent
                   font.pointSize: 10
                   visible: false
                }
                Text {
                    id: signalText
                    x: 27
                    y: 102
                    color: "#f0f0f0"
                    width: 60
                    height: 14
                    font.pixelSize: 12
                }
                MouseArea{
                    anchors.fill: parent
            
                    onClicked:
                    {
                        anchor.clicked();
                        testText.text=anchor.message//there it is!
                        testText.visible=true;
                        mainWindow.setGeometry(1200,330,500,400)
                        signalText.text= value;
                    }
                    onDoubleClicked: anchor.slotAnchor("calling slotAnchor")
                }
            }
            

            Do you know where does that error comes from ? how can I fix it and FINALLY set an efficient communication ?
            Thanks for reading

            R Offline
            R Offline
            Ronak5
            wrote on 14 May 2019, 05:54 last edited by
            #5

            @Quentin91
            hey did you try marking your qml strings with "qsTr()" ?
            could you try qsTr(anchor.message)?

            Also, you can't define signals as mentioned by @mranger90 as it's already defined in moc code. You will get error as multiple definition of the signal function.
            Thanks.

            1 Reply Last reply
            0
            • Q Offline
              Q Offline
              Quentin91
              wrote on 14 May 2019, 13:49 last edited by Quentin91
              #6

              @Ronak5 no, I didn't. that's probably not the problem any current test is trying to share a bool with QML and the problem is the same. but I'll remember to try it when sharing a string :)

              So here is a simpler project and use a Singleton. One of the problem was that I have to declare my object in the QML when using qmlRegisterType. And I don't want to. So here is the new code, the error is the same.
              I followed the example of the doc here https://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html

              miniModel.h (the singleton)

              #ifndef _MINIMODEL_H_
              #define _MINIMODEL_H_
              #include <stdlib.h>
              #include <stdio.h>
              #include <iostream>
              #include <string>
              #include <QtGui/qguiapplication.h> 
              #include <QtQml/qqmlcontext.h>
              #include <QtQml/qqmlapplicationengine.h>
              #include <QtCore/qdebug.h>
              #include <QtCore/qobject.h>
              #include <QtCore/qvariant.h>
              class MiniModel : public QObject
              {
              	Q_OBJECT
              	Q_PROPERTY(bool miniboule READ miniboule WRITE setMiniboule NOTIFY minibouleChanged)
              public:
              	MiniModel();
              	bool miniboule();
              	void setMiniboule(bool bouboule);
              signals:
              	void minibouleChanged();
              private:
              	bool m_miniboule;
              };
              #endif
              

              main.cpp v1 : singleton using a QObject

              #include "miniModel.h"
              
              //defining a miniModel instance as a singleton
              static QObject* mp_singleton(QQmlEngine* engine, QJSEngine* scriptEngine)
              {
              	Q_UNUSED(engine)
              	Q_UNUSED(scriptEngine)
              
              	MiniModel* miniSingleton = new MiniModel();
              	return miniSingleton;
              }
              
              int main(int argc=0, char* argv[]=nullptr)
              {
              	printf("\n launching \n");
              	QGuiApplication app(argc, argv);
              
              	qmlRegisterSingletonType<MiniModel>("myModel.miniModel", 1, 0, "MiniModel",mp_singleton);
              
              	QQmlApplicationEngine engine;
              
              	engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml"));
              	engine.load(QUrl(QStringLiteral("..\\..\\..\\miniModel.qml")));
              
              	return app.exec();
              }
              

              main.cpp v2 : singletin using QJSValue

              #include "miniModel.h"
              
              static QJSValue m_singletonModel(QQmlEngine* engine, QJSEngine* scriptEngine) {
              	Q_UNUSED(engine)
              
              	static bool m_miniboule;
              	QJSValue miniModel = scriptEngine->newObject();
              	miniModel.setProperty("miniboule", m_miniboule);
              	return miniModel;
              }
              
              int main(int argc = 0, char* argv[] = nullptr)
              {
              	printf("\n launching \n");
              	QGuiApplication app(argc, argv);
              
              	qmlRegisterSingletonType("myModel.miniModel", 1, 0, "MiniModel", m_singletonModel);
              
              	QQmlApplicationEngine engine;
              
              	engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml"));
              	engine.load(QUrl(QStringLiteral("..\\..\\..\\miniModel.qml")));
              
              	return app.exec();
              }
              
              

              and the QML. be careful, it's tough

              import QtQuick 2.5
              import QtQuick.Window 2.5
              import QtQuick.Controls 1.4
              
              import myModel.miniModel 1.0 as MyModel
              ApplicationWindow {
                  id: root
                  width: 300
                  height: 480
                  visible:true
                  Text{
                     id: textTest
                     x: 62
                     y: 75
                     color: "#d21616"
                     text:  "vanilla"
                     visible: false//the text is supposed to appear when clicking in the mouseArea
                  }
                  MouseArea{
                      anchors.fill: parent
                      onClicked: textTest.visible=  MyModel.Minimodel.miniboule//the boolean I want to acess, defined to true
                  }
              }
              

              now, the error changed, since I called MyModel.MiniModel.miniboule instead of just MiniModel.miniboule
              the error is TypeError: Cannot read property 'miniboule' of undefined

              1 Reply Last reply
              0

              6/6

              14 May 2019, 13:49

              • Login

              • Login or register to search.
              6 out of 6
              • First post
                6/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved