How to run a C++ function when QML button is clicked? Using QQmlApplicationEngine
-
myclass.h
@#ifndef MYCLASS_H
#define MYCLASS_H#include <QDebug>
#include <QObject>class MyClass : public QObject
{
public:
MyClass();public slots:
void buttonClicked();
void buttonClicked(QString &in);
};#endif // MYCLASS_H@
myclass.cpp
@#include "myclass.h"MyClass::MyClass()
{
}void MyClass::buttonClicked()
{
// Do Something
}void MyClass::buttonClicked(QString &in)
{
qDebug() << in;
}@
main.cpp
@#include <QApplication>
#include <QQmlApplicationEngine>
#include <myclass.h>
#include <QQmlContext>int main(int argc, char *argv[])
{
QApplication app(argc, argv);QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); MyClass myClass; // A class containing my functions // Trying to "SetContextProperty" as I saw people do it to achieve C++/QML connection QQmlContext *context = new QQmlContext(engine.rootContext()); context->setContextProperty("_myClass", &myClass); return app.exec();
}@
............
I want to use a function in myClass class which takes a QString parameter when a QML button is clicked ..
When I compile & run .. it all goes smoothly. But when I click on the button .. it shows this error in the debugger:
qrc:///main.qml:80: ReferenceError: _myClass is not defined
~> "Line 80 in my QML file":
@74: MouseArea {
75: id: mouseArea1
76: anchors.fill: parent
77: hoverEnabled: true;
78: onEntered: { rectangle1.border.width = 2 }
79: onExited: { rectangle1.border.width = 1 }
80: onClicked: _myClass.buttonClicked("Worked?")
81: }@ -
Welcome to Qt DevNet!
I think you missed Q_OBJECT macro in MyClass declaration
@
class MyClass : public QObject
{
Q_OBJECT // <-- This one
public:
@ -
[quote author="andreyc" date="1406088144"]Welcome to Qt DevNet!
I think you missed Q_OBJECT macro in MyClass declaration[/quote]
Hi andreyc,
Now myclass.h looks like this:
@#ifndef MYCLASS_H
#define MYCLASS_H#include <QDebug>
#include <QObject>class MyClass: public QObject
{
Q_OBJECTpublic:
MyClass();public slots:
void buttonClicked();
void buttonClicked(QString &in);
};#endif // MYCLASS_H
@But now my code wouldn't compile at all! it gives me this compile error:
@C:\Users\Dell\Documents\Workspace\ProjectOne\myclass.h:7: error: undefined reference to `vtable for MyClass'@ -
Have you rebuild the whole project after you added Q_OBJECT ?
-
[quote author="andreyc" date="1406130397"]Have you rebuild the whole project after you added Q_OBJECT ?[/quote]
Oh sorry, I feel like an idiot now.
I've rebuilt the whole project, and it runs perfectly.But when I click on the button I get this in the debugger:
@qrc:///main.qml:80: ReferenceError: _myClass is not defined@
<~ Same main problem. -
It works for me.
-
main.cpp
@
int main(int argc, char *argv[])
{
QApplication app(argc, argv);QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQmlContext *item = engine.rootContext();
MyClass myClass;
item->setContextProperty("_myClass", &myClass);return app.exec();
}
@ -
MyClass.h
@
class MyClass : public QObject
{
Q_OBJECT
public:
//explicit MyClass(QObject *parent = 0) : QObject(parent) {}
MyClass() {}signals:
public slots:
void buttonClicked(QString in)
{
qDebug() << "buttonClicked" << in;
}
};
@- 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(); } } } Rectangle { id: rectangle1 width: 100 height: 100 color: "red" border.color: "black" border.width: 5 radius: 10 } MouseArea { id: mouseArea1 anchors.fill: parent hoverEnabled: true; onEntered: { rectangle1.border.width = 2 } onExited: { rectangle1.border.width = 1 } onClicked: _myClass.buttonClicked("Worked?") }
}
@ -
-
If your problem is still not resolved, Can you try item->setContextProperty("_myClass", &myClass); before loading the QML ?
-
Thanks guys, it's solved.
I just had to remove the first declaration of my slot:
myclass.h@#ifndef MYCLASS_H
#define MYCLASS_H#include <QDebug>
#include <QObject>class MyClass : public QObject
{
public:
MyClass();public slots:
//void buttonClicked(); <~ This had to be removed in order to make it work
void buttonClicked(QString &in);
};#endif // MYCLASS_H
@