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. [SOLVED]"TypeError: Object [object Object] has no method" w/ qmlRegisterType
QtWS25 Last Chance

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

Scheduled Pinned Locked Moved QML and Qt Quick
3 Posts 2 Posters 5.7k 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.
  • T Offline
    T Offline
    Tory Gaurnier
    wrote on last edited by
    #1

    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
    0
    • C Offline
      C Offline
      chrisadams
      wrote on last edited by
      #2

      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
      0
      • T Offline
        T Offline
        Tory Gaurnier
        wrote on last edited by
        #3

        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
        0

        • Login

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