2

I want to call a c++ function from my QML code.

For example in the following code i have a window with 2 inputs : quantity and price I want to call a c++ function which evaluates the subtotal and adds 5% tax to it.

I have tried searching many places but couldn't get complete working code with this latest version of QT5. Please tell me how to call a C++ function from QML.

main.qml :

import QtQuick 2.2
import QtQuick.Controls 1.1

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }

    Column{
        Label {
            text: qsTr("Enter the number of items purchased: ")
        }
        TextField {
            id: in1
            objectName: "in1"
        }
        Label {
            text: qsTr("Enter the price per item ($):")
        }
        TextField {
            id: in2
            objectName: "in2"
        }
        Button {
            id: button
            objectName: "button"
            text: "Compute"
            onClicked: {
                total.text = "Final bill, including 5% tax, is $" + clickedButton(in1.text, in2.text); // here i'm calling the c++ function
            }
        }
        Label {
            id: total
            objectName: "total"
            text: "Final bill, including 5% tax, is $____"
        }
    }
}

main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

double clickedButton(int number, int price){
    const double TAX_rate = 0.05;
    double subtotal;
    subtotal = price*number;
    return (subtotal + subtotal*TAX_rate);
}

3 Answers 3

2

Create a class like :

class BillCalculator : public QObject
{
   Q_OBJECT
   Q_PROPERTY(double totalPrice READ totalPrice WRITE setTotalPrice NOTIFY totalPriceChanged)
public:
   BillCalculator(QObject *parent = 0) :
     QObject(parent),
    mTotalPrice(0.0)
   {
   }

   double totalPrice() const { return mTotalPrice; }
signals:
   void totalPriceChanged();
public slots: 
   void setTotalPrice(const double &arg) 
   {
     if(mTotalPrice != arg)
     {
       mTotalPrice = arg;
       emit totalPriceChanged();
     }
   }
   void calculateTotalPrice(int number, int price)
   {
    const double TAX_rate = 0.05;
    double subtotal;
    subtotal = price*number;
    setTotalPrice(subtotal + subtotal*TAX_rate);
   }
protected:
   double mTotalPrice;
};

in your main.cpp, include <QQmlContext> and modify as below

  QQmlApplicationEngine engine;
  engine.rootContext()->setContextProperty("billCalculator", new BillCalculator);
  engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

modify your main.qml file as below

   Button {
            id: button
            objectName: "button"
            text: "Compute"
            onClicked: {
                billCalculator.calculateTotalPrice(parseInt(in1.text), parseInt(in2.text));
            }
        }
        Label {
            id: total
            objectName: "total"
            text: "Final bill, including 5% tax, is $" + (billCalculator.totalPrice > 0 ? billCalculator.totalPrice.toFixed(2) : "____")
        }
Sign up to request clarification or add additional context in comments.

2 Comments

I think you forgot to add declaration for mTotalPrice in the class. But when i added the declaration, it is giving errors : :-1: error: symbol(s) not found for architecture x86_64 & :-1: error: linker command failed with exit code 1 (use -v to see invocation)
Yes, you're right, fixed it; for your linker errors; create a seperate billcalculator.h and define the BillCalculator class there
1

You need to declare clickedButton as Q_INVOKABLE like this:

 public:
 Q_INVOKABLE void cppMethod(const QString &msg) {
     qDebug() << "Called the C++ method with" << msg;
 }

See this sample: http://qt-project.org/doc/qt-4.8/qtbinding.html

Comments

1

Simply use:

engine.rootContext()->setContextProperty("yourName", new yourClass());

In your qml you can call the function with yourname.yourfunction() Additional in your class you have to make your Function Q_INVOKABEL

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.