I want to do something like this
QML app:
{
signal qmlSignal
function qmlFunction
}
And
c++ Hnadler:
{
c++ slot
c++ signal
}
Want to have two way communication with the same qml object. I am referring http://qt-project.org/doc/qt-4.8/qtbinding.html
for changing a value in qml from C++, we can do
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine, "MyItem.qml");
QObject *object = component.create();
QVariant returnedValue;
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));
qDebug() << "QML function returned:" << returnedValue.toString();
delete object;
can be used to call qml function. But with this we cannot use QT method
And
class MyClass : public QObject
{
Q_OBJECT
public slots:
void cppSlot(const QString &msg) {
qDebug() << "Called the C++ slot with message:" << msg;
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QDeclarativeView view(QUrl::fromLocalFile("MyItem.qml"));
QObject *item = view.rootObject();
MyClass myClass;
QObject::connect(item, SIGNAL(qmlSignal(QString)),
&myClass, SLOT(cppSlot(QString)));
view.show();
return app.exec();
}
This can be used for qmlsignal and c++ slot. Is there a way both of these can be done in one object?
=== Updated question ===
You can call slots or Q_INVOKABLE methods just fine in QML to change "C++ properties" from QML. You will need to expose the C++ object as a context property though. You would need to write something like this below:
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(QObject *parent) : QObject(parent) { ... }
Q_INVOKABLE void myInvokable();
public slots:
void mySlot();
...
}
...
MyClass myClassObject;
QQuickView view;
view.rootContext()->setContextProperty("myClassContextProperty", &myClassObject;
view->setSource(QUrl::fromLocalFile("main.qml"));
view->show();
...
Button {
...
// You can replace onClicked with your own custom signal
onClicked: myClassContextProperty.myslot()
// or
onClicked: myClassContextProperty.myInvokable()
...
}
=== Further questions in the comment ===
You would have a Q_PROPERTY in C++, and you bind that property to your property in QML, or catch the onFooChanged signal handler for the property called "foo".
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(foo READ foo NOTIFY fooChanged)
public:
MyClass(QObject *parent) : QObject(parent) { ... }
int foo() const;
public signals:
void fooChanged();
public slots:
void mySlot() { foo = 5; emit fooChanged(); };
private:
int foo;
...
}
...
MyClass myClassObject;
QQuickView view;
view.rootContext()->setContextProperty("myClassContextProperty", &myClassObject;
view->setSource(QUrl::fromLocalFile("main.qml"));
view->show();
...
...
// Bind foo to bar
property int bar: myClassContextProperty.foo
=== Original question ===
It seems that you are trying to ask if you can declare the same both in C++ and QML simultaneously, i.e. some parts of it in QML and then the rest in QML.
I think you would need to register (qmlRegisterMetaType, etc) your C++ type with the Qt meta type system, and then you could use that class as an item in QML (maybe with a parent?) to achieve what you wish.
This is the relevant documentation for further reading:
Registering an Instantiable Object Type
For your convenience, here goes some code inline:
class Message : public QObject
{
Q_OBJECT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
public:
// ...
};
qmlRegisterType<Message>("com.mycompany.messaging", 1, 0, "Message");
...
import com.mycompany.messaging 1.0
Message {
author: "Amelie"
creationDate: new Date()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With