Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    [SOLVED]"TypeError: Object [object Object] has no method" w/ qmlRegisterType

    QML and Qt Quick
    2
    3
    5559
    Loading More Posts
    • 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.
    • T
      Tory Gaurnier last edited by

      I'm pretty certain this is the correct thread to post this in. First let me say, I'm very new to QT and QML, I've been working on an app in C and GTK, but for various reasons decided to switch to QML, figuring out how to combine C and C++ was easy enough, what I've had the most difficulty with is creating my Makefile, however after a few days I've gotten that all figured out (I didn't want to use qmake, so I figured out how to manually do a Makefile), my program compiles fine, and my QML gui shows, however when using qmlRegisterType I can't call methods from C++ in QML.

      Ok, here is my gui.h:
      @#ifdef __cplusplus
      #include <QGuiApplication>
      #include <QQuickView>
      #include <QtQml>

      class QmlConnect : public QObject {
      Q_OBJECT
      Q_PROPERTY(QString* getData READ getData)

      public:
      QmlConnect() {

      }
      Q_INVOKABLE QString* getData() {
      static QString data_list[] = {"Data1", "Data2", "Data3", "Data4"};
      return data_list;
      }
      };
      #endif

      #ifdef __cplusplus
      extern "C" {
      #endif
      void gui_Init(int argc, char **argv);
      #ifdef __cplusplus
      }
      #endif@

      Here is my gui.cpp:
      @#include "gui.h"

      extern "C" {
      #include "../globalvars.h"
      #include "../library.h"
      #include "../config.h"
      #include "../misc.h"
      }

      void gui_Init(int argc, char **argv) {
      QGuiApplication q_app(argc, argv);

      // Connect QT C++ to QML
      qmlRegisterType<QmlConnect>("QmlConnect", 1, 0, "QmlConnect");

      // Start QML app
      QQuickView view;
      view.setSource(QUrl::fromLocalFile("gui.qml"));
      view.show();

      q_app.exec();
      }@

      And here's my gui.qml file:
      @import QtQuick 2.0
      import Ubuntu.Components 0.1
      import Ubuntu.Components.ListItems 0.1 as ListItem

      import QmlConnect 1.0

      MainView {
      objectName: "mainView"
      applicationName: "MyApp"
      id: root

      width: units.gu(100)
      height: units.gu(80)

      property real margins: units.gu(2)
      property real buttonWidth: units.gu(9)

      Column {
      id: libraryColumn
      ListItem.Header {text: "Library"}
      ListItem.Standard {text: "Section1"}
      ListItem.Standard {text: "Section2"}
      ListItem.Divider {}
      ListItem.Header {text: "Lists"}

      width: units.gu(10)
      anchors {
      left: parent.left
      top: parent.top
      bottom: parent.bottom
      }
      }
      Grid {
      Component.onCompleted: {
      var data = QmlConnect.getData();
      for(var i = 0; i < data.length; i++) {
      console.log(data[i]);
      }
      }
      }
      }@

      Now what's happening is when my QML file tries to call QmlConnect.getData() it throws the error "TypeError: Object [object Object] has no method 'getData'"

      It doesn't fail to import the class itself, but it can't seem to call the mothod from the class. Any help is greately apprecieated.

      1 Reply Last reply Reply Quote 0
      • C
        chrisadams last edited by

        Hi,

        A couple of issues: your QmlConnect type isn't registered as a singleton type, so you need to instantiate an instance of it, in order to invoke a member function.

        @
        MainView {
        id: root

        QmlConnect {
            id: qmlconnect
        }
        
        // ....
        
        Grid {
            Component.onCompleted: {
                var data = qmlconnect.getData()
                // ...
            }
        }
        

        }
        @

        Secondly, return a QStringList instead of a QString*. The overhead of passing core types by value is very low, as they use copy-on-write implicit sharing, and QML doesn't support returning (or interacting with) pointers unless they're QObject* (or QObject-derived*) - except wrapped in QVariants at which point they're opaque to QML anyway.

        You can also use a Q_PROPERTY instead of a Q_INVOKABLE to be more declarative:

        @
        class QmlConnect : public QObject
        {
        Q_OBJECT
        Q_PROPERTY(QStringList stringArray READ stringArray CONSTANT)

        public:
        QmlConnect(QObject *parent = 0);
        ~QmlConnect();

        QStringList stringArray() const { QStringList retn; retn << "one" << "two" << "three"; return retn; }
        

        };
        @

        Then in the qml, instead of calling getData() just resolve stringArray:

        @
        Component.onCompleted: {
        var data = qmlconnect.stringArray
        // ....
        }
        @

        Cheers,
        Chris.

        1 Reply Last reply Reply Quote 0
        • T
          Tory Gaurnier last edited by

          Your amazing!!! Thank you, now I can move on with my project :D See I'm not even that familiar with C++, I don't even know what a singleton is :P Luckily the amount of C++ going into this will be minimal it's just to get variables from my C functions and pass them along to the QML, and vice versa.

          Is there a way to vote up replies? Or mark them as "Answers"? Like on other forums.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post