[Interest] Adding a C++ wrapper class renders my QML custom type unusable

Rob Allan rob_allan at trimble.com
Wed Aug 31 08:08:36 CEST 2016


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20160831/91096448/attachment.html>


More information about the Interest mailing list