QML - Q_INVOKABLE functions

12,167

Judging by what you pasted here, a cursory inspection indicates that you've managed to do what we all start out by doing:

You forgot the Q_OBJECT macro in your QObject based class.

Without that one, you won't get the a metaobject generated for your class, and thus signals, slots and other similar functionality (such as Q_INVOKABLE) will not function as expected. Hope that helps :)

Share:
12,167
marmistrz
Author by

marmistrz

Updated on July 09, 2022

Comments

  • marmistrz
    marmistrz almost 2 years

    I have a problem with QML, with calling Q_INVOKABLE functions. Although I marked functions as Q_INVOKABLE I'm getting errors

    TypeError: Result of expression 'azdownloader.setData' is not a function
    TypeError: Result of expression 'azdownloader.perform' is not a function
    

    I have this class:

    typedef QString lyricsDownloaderString;
    
    class lyricsDownloader : public QObject
    {
    public:
        Q_INVOKABLE virtual short perform() = 0;
        Q_INVOKABLE inline void setData(const string & a, const string & t); // set artist and track
     // some other data
    
    protected:
        lyricsDownloader(const string & a, const string & t ) : artist(a), track(t) {} 
      /*other data*/
    };
    
    class AZLyricsDownloader : public lyricsDownloader
    {
    public:
        AZLyricsDownloader() : lyricsDownloader("", "") {}
        AZLyricsDownloader(const string & a, const string & t) : lyricsDownloader(a, t) {}
        Q_INVOKABLE short perform();
        Q_INVOKABLE inline void setData(const string & a, const string & t);// set artist and track
     /*other data*/
    

    In main.cpp

    Q_DECL_EXPORT int main(int argc, char *argv[])
    {
            QApplication app(argc, argv);
    
            mainWindow viewer;
    
            qmlRegisterUncreatableType<lyricsDownloader>("MaeLyrica", 1, 0, "lyricsDownloader", "");
            qmlRegisterType<AZLyricsDownloader>("MaeLyrica", 1, 0, "AZLyricsDownloader");
            viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
            viewer.setMainQmlFile(QLatin1String("qml/maelyrica/main.qml"));
            viewer.showFullScreen();
    
            return app.exec();
    }
    

    in main.qml

    import QtQuick 1.1
    import com.nokia.meego 1.0
    import com.nokia.extras 1.0
    import MaeLyrica 1.0
    
    //property color fontcolor: "white"
    
    PageStackWindow
    {
        id: pagestackwindow
        visible: true
        MainPage
        {
            id: mainview
        }
        initialPage: mainview
        AZLyricsDownloader
        {
            id: azdownloader
        }
    }
    

    And in the pages

    import QtQuick 1.1
    import com.nokia.meego 1.0
    
    Page
    {
     /*some gui elements*/
    
            Button
            {
                id: go
                text: "Go!"
                width: parent.width
                onClicked:
                {
                    goLoader.source = "ShowLyricsPage.qml"
                    pageStack.push(goLoader.item)
                    azdownloader.perform()
                    showLyricsPage.busyind.visible = false
                }
            }
        }
    /*dialogs and toolbar definitions*/
    }
    

    The other one:

    import QtQuick 1.1
    import com.nokia.meego 1.0
    
    Sheet {
        id: sheet
    
        acceptButtonText: "Save"
        rejectButtonText: "Cancel"
        onAccepted:
        {
            if ( artistfield.text == "" || trackfield.text == "" ) // check whether empty
            {
                emptyfieldsdialog.open()
            }
            else
            {
                selecttrack.text = artistfield.text + " - " + trackfield.text
                azdownloader.setData(artistfield.text, trackfield.text)
            }
        }
    
        content: Rectangle { /*some content here*/ }
    
        /*dialog definition*/
    

    What am I doing wrong?

  • marmistrz
    marmistrz almost 12 years
    Now I'm getting moc_lyricsDownloader.cpp:76: error: undefined reference to `lyricsDownloader::setData(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
  • marmistrz
    marmistrz almost 12 years
    EDIT: after adding the functions body to the class definition everything's ok.