Unsolved Call base object method from QML
-
Hello all! I have the following situation: I use FileDialog from Qt.labs.platform 1.1 and pass FileDialog.file to C++ QObject. Before I have used one object with methods and everything works well (QML calls method with QUrl argument which, in turn, calls QString case)
Q_INVOKABLE void saveToFile(QUrl url) {saveToFile(url.toLocalFile())}; Q_INVOKABLE void saveToFile(QString string){//some processing};
Now I have base class with common method and virtual abstract one
Q_INVOKABLE void saveToFile(QUrl url) {saveToFile(url.toLocalFile())}; Q_INVOKABLE virtual void saveToFile(QString string) = 0;
So in the derived class I have different definitions of the method
void saveToFile(QString string)
. Following this idea, I try to callsaveToFile
from QML for the derived objects. But the override method is calling with converting (QML url to Qstring directly). How can I avoid this situation and call base method from QML? Of course I can give different names, but I'm interested in common case and, maybe, good practices. -
In order to call the QUrl overload, you need to pass a
url
variable instead ofstring
. Here is - somewhat hacky - solution:FileDialog { property url myUrl: file } // JS yourCppObject.saveToFile(myUrl)
Not tested - I hope it will work though :P If not, then different method names is the right solution.
-
@sierdzio Hello and thank you for the fast reply! Looks like it failed to be workaround :) Moreover, it says in documentation that
FileDialog.file
is alreadyurl
type. So looks like there is no difference for passing this argument.One more thing that I have tried and it works: redefine the method in the derived class with QUrl argument and call parent method directly:
void Derived::saveToFile(QUrl filename) { Base::saveToFile(filename); }
This workaround works and seems to be ok in my case.
-
Interesting! OK, nice that you've found a solution :-)
-
@St-Stanislav said in Call base object method from QML:
void Derived::saveToFile(QUrl filename) {
Parent::saveToFile(filename);
}This is a C++ 'issue', you have to tell C++ compiler you want to keep previous definition:
class BaseClass : public QObject { Q_OBJECT public: Q_INVOKABLE void saveToFile(QString string){//some processing};; } class DerivedClass : public BaseClass { Q_OBJECT public: using BaseClass::saveToFile; Q_INVOKABLE void saveToFile(QUrl url) {saveToFile(url.toLocalFile()); }; }
==> http://www.cs.technion.ac.il/users/yechiel/c++-faq/hiding-rule.html
-
@KroMignon Yes, I have caught it and solved it in the same way, but I wondered if it's any chance to call base class method from QML directly :)
-
@St-Stanislav said in Call base object method from QML:
if it's any chance to call base class method from QML directly :)
What do you mean?
myCppClass.saveToFile("TEST"); // => should call saveToFile(QString) myCppClass.saveToFile(Qt.resolvedUrl("test.qml")); // => should call saveToFile(QUrl)
-
@KroMignon Well, looks like your solution is also not for me (cause of several methods with one name I have used the second solution from the link you posted). I get why this methods are called, get what solution I can use, but I was wondering if this problem can be solved from QML side :)
I have created tiny example project, but have no idea how to post it here correctly. -
I'm not sure if I understand things with total clarity.
However, if I understand, then these both exist in a base class:
/* (1) */ Q_INVOKABLE void saveToFile(QUrl url) {saveToFile(url.toLocalFile())}; /* (2) */ Q_INVOKABLE virtual void saveToFile(QString string) = 0;
And some QML code is triggering entry/execution into (2) instead of (1).
In that case, I wonder why not just remove
Q_INVOKABLE
from (2) so that it is not-invokable from QML?