Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ class exposed to QML error in fashion TypeError: Property '...' of object is not a function

Tags:

qt

qml

qtquick2

I've successfully exposed a C++ class to QML. It is registered and found in Qt Creator. It's purpose is to connect to a database, as shown in following code:

#ifndef UESQLDATABASE_H
#define UESQLDATABASE_H

#include <QObject>
#include <QtSql/QSqlDatabase>

class UeSqlDatabase : public QObject
{
    Q_OBJECT

    Q_PROPERTY(bool m_ueConnected READ isConnected WRITE setConnected NOTIFY ueConnectedChanged)

private:
    bool m_ueConneted;

    inline void setConnected(const bool& ueConnected)
        { this->m_ueConneted=ueConnected; }

public:
    explicit UeSqlDatabase(QObject *parent = 0);

    Q_INVOKABLE inline const bool& isConnected() const
        { return this->m_ueConneted; }

    ~UeSqlDatabase();

signals:
    void ueConnectedChanged();

public slots:
    void ueConnectToDatabase (const QString& ueStrHost, const QString& ueStrDatabase,
                              const QString& ueStrUsername, const QString& ueStrPassword);
};

#endif // UESQLDATABASE_H

However, when I try to call method isConnected() from the following QML code

import QtQuick 2.0

Rectangle
{
    id: ueMenuButton

    property string ueText;

    width: 192
    height: 64
    radius: 8

    states: [
        State
        {
            name: "ueStateSelected"

            PropertyChanges
            {
                target: gradientStop1
                color: "#000000"
            }

            PropertyChanges
            {
                target: gradientStop2
                color: "#3fe400"
            }
        }
    ]

    gradient: Gradient
    {
        GradientStop
        {
            id: gradientStop1
            position: 0
            color: "#000000"
        }

        GradientStop
        {
            position: 0.741
            color: "#363636"
        }

        GradientStop
        {
            id: gradientStop2
            position: 1
            color: "#868686"
        }

    }

    border.color: "#ffffff"
    border.width: 2
    antialiasing: true

    Text
    {
        id: ueButtonText
        color: "#ffffff"
        text: qsTr(ueText)
        clip: false
        z: 0
        scale: 1
        rotation: 0
        font.strikeout: false
        anchors.fill: parent
        font.bold: true
        style: Text.Outline
        textFormat: Text.RichText
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        font.pixelSize: 16
}

    MouseArea
    {
        id: ueClickArea

        antialiasing: true
        anchors.fill: parent

        onClicked:
        {
            uePosDatabase.ueConnectToDatabase("127.0.0.1",
                                              "testDb",
                                              "testUser",
                                              "testPassword");
            if(uePosDatabase.isConnected()==true)
            {
                ueMenuButton.state="ueStateSelected";
            }
            else
            {
                ueMenuButton.state="base state"
            }
        }
    }
}

I get the following error:

qrc:/UeMenuButton.qml:92: TypeError: Property 'isConnected' of object UeSqlDatabase(0x1772060) is not a function

What am I doing wrong?

like image 763
KernelPanic Avatar asked Jul 25 '15 19:07

KernelPanic


3 Answers

You have this error because you have declared the property isConnected in C++ but you're calling it from QML in the wrong way: uePosDatabase.isConnected is the correct way, not uePosDatabase.isConnected().

If you want to call the function isConnected() you should change its name to differate it from the property, like getIsConnected(). Given your property declaration, you neither need to call this function directly nor you need to make it callable from QML with the Q_INVOKABLE macro.

like image 137
Mido Avatar answered Nov 19 '22 14:11

Mido


You must first create the object you want in QML code and then use the function:

your QML Code:

import QtQuick 2.0
import QSqlDatabase 1.0

Rectangle {
    id: ueMenuButton

    QSqlDatabase {
        id: uePosDatabase
    }
.
.
.
    MouseArea
    {
        id: ueClickArea
        antialiasing: true
        anchors.fill: parent

        onClicked: {
            console.log(uePosDatabase.isConnected())
        }
    }
}
like image 30
mass shabani Avatar answered Nov 19 '22 14:11

mass shabani


Be aware in case of an error some lines earlier in the same .js file can lead to this problem. The following code will not be executed.

like image 1
Kombinator Avatar answered Nov 19 '22 14:11

Kombinator