Can you provide a small, reproducible example?

From: Interest [mailto:interest-bounces+mitch.curtis=qt...@qt-project.org] On 
Behalf Of Rob Allan
Sent: Wednesday, 31 August 2016 8:09 AM
To: interest@qt-project.org
Subject: [Interest] Adding a C++ wrapper class renders my QML custom type 
unusable


I have a custom QML type, CustomButton, defined in CustomButton.qml. Initially 
this was a fairly simple type, with a 'clicked' signal, and a few JavaScript 
functions that set up the button content. I was able to use this custom button 
from other QML files, and from C++ code (using QMetaObject::invokeMethod() to 
invoke its methods), and it all worked pretty well.

As this button became more complex, I realised that I really needed a C++ 
wrapper class (or backing class?) to deal with some of the additional 
complexity. I've added C++ wrapper classes to other QML types before, with 
varying degrees of success, and I think I understand the basic steps involved. 
I did the following:

  1.  Created a minimal wrapper in CustomButton.h and CustomButton.cpp (I made 
this as minimal as possible to begin with so as not to affect the existing 
behavior - I thought!):

#include <QQuickItem>



class CustomButton : public QQuickItem

{

    Q_OBJECT



public:

    CustomButton();

};

  1.  Added the necessary qmlRegisterType() call to my application startup code:

qmlRegisterType<CustomButton>("com.glob.myApp", 1, 0, "CustomButton");

  1.  Added an import statement to my CustomButton.qml file:

import com.glob.myApp 1.0

  1.  Changed the root item in CustomButton.qml from 'Item' to 'CustomButton'.

So far all appeared to be OK - the project compiled, and CustomButton.qml 
appeared to be error-free in the QML editor. But then things started going 
downhill.

I noticed that, in another QML file that used CustomButton, it could no longer 
'see' the signals on my type - a reference to 'onClicked' was red-underlined, 
and hovering over it showed 'Invalid property name'. At runtime, it failed to 
create the referencing QML object due to this error. It looks as if the 
introduction of the C++ wrapper class has 'hidden' the signals defined in the 
original CustomButton.qml file.

I found I could get past this error by deleting the signal definitions from 
CustomButton.qml, and instead adding them to CustomButton.h:

signals:

    void clicked(const QString text, int eventCode);

    etc...

That allowed it to build and run. I'm not sure whether this was correct and the 
signals would now have worked, because I then struck another problem - my 
existing C++ code could no longer invoke the JavaScript functions defined in 
CustomButton.qml. For example, when I tried to invoke a method 'setContent' 
(which previously worked just fine) I now got this runtime error:

QMetaObject::invokeMethod: No such method 
CustomButton::setContent(QVariant,QVariant)

Again, it appears that adding a C++ wrapper class has 'hidden' the function 
definitions in the QML file, that were previously available to the rest of the 
system.

OK, I thought, maybe I have to define these functions on the C++ class in some 
way. I tried declaring an INVOKABLE function in the .h file that matched my 
JavaScript function, and that failed with a link error - the compiler wanted me 
to define an implementation for this function in my CPP file - but I don't want 
to implement it in my CPP file, as the implementation exists in the QML file! 
Just to see where it got me, I tried adding an implementation to the CPP file, 
and inside this function, attempted to "invoke" the JavaScript function. That 
failed, presumably because I had now introduced a kind of circularity and was 
probably attempting to invoke the same handler that I was already in!

I also tried declaring these functions as 'slots' on the C++ class, but fared 
no better - the compiler still wanted a CPP implementation, and I wasn't sure 
if I was really meant to add one, and if I did, how I would then invoke the 
JavaScript function from it.

In short - adding a C++ wrapper class (with almost nothing in it) has broken a 
previously functional QML type implementation, by apparently 'hiding' signals 
and functions that exist in the QML.

Can anyone advise what I'm doing wrong here? Or suggest some relevant 
documentation that might give me the answers I need?

Thanks,
Rob
_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to