Вчера меня попросили воссоздать обычную форму QT с использованием QML (это была моя первая попытка когда-либо использовать QLM). Все шло хорошо, пока я не попытался использовать методы C++ в QML. Это, очевидно, не исходный код, но сценарий выглядит примерно так:Не удается получить доступ к методам подкласса C++ QOBject из QML
У меня есть супер класс, производный от QObject, с некоторыми свойствами, методами и даже виртуальными методами:
class SuperClass : public QObject {
Q_OBJECT
Q_PROPERTY(QString someProperty READ someProperty WRITE setSomeProperty)
protected:
QString m_someProperty;
public:
QString someProperty(void){return m_someProperty;} //get method
void setSomeProperty(QString newValue){m_someProperty = newValue;} //set method
Q_INVOKABLE virtual QString printSomething(void) = 0;
}
И тогда я класс, происходящий от суперкласса (например, специализации) с некоторыми более специфическими свойствами и методами, и, конечно же, реализации виртуальных методов и прочее:
class DerivedClass : public SuperClass {
Q_PROPERTY(QString someSpecificProperty READ someSpecificProperty WRITE setSomeSpecificProperty)
private:
QString m_someSpecificProperty;
public:
QString specificProperty(void){return m_someSpecificProperty;} //get method
void someSpecificProperty(QString newValue){m_someSpecificProperty = newValue;} //set method
QString printSomething(void){return QString("Something!");} //SuperClass virtual method
Q_INVOKABLE QString printSomethingSpecific(void){return QString("Something Specific!");}
}
ОК, это он! Теперь при условии, что DerivedClass конкретизируется и добавляется в контексте QML правильно под названием «DrvClass», например, и что у меня есть некоторый контроль QML вроде TextField, который имеет «текст:» свойство:
text: DrvClass.someProperty
используя свойства MasterClass, он работает отлично.
text: DrvClass.printSomething()
Использование виртуальных методов из MasterClass, которые реализованы в производном классе, отлично работает. но ...
text: DrvClass.someSpecificProperty
не работает, и я получаю что-то вроде "Невозможно присвоить [неопределенными] для QString"
text: DrvClass.printSomethingSpecific()
также не работает! "TypeError: свойство 'printSomethingSpecific' объекта SuperClass() не является функцией« И странная часть заключается в том, что она говорит, что это не функция из SuperClass, являющаяся экземпляром класса Derived!
Я искал похожие ошибки, но большую часть времени от людей, которые просто забыли включить макрос Q_OBJECT ... Мой там точно! Кажется, что QML не любит много классов, происходящих из других классов, которые происходят из QObjects: -/Вероятно, что-то связано с метаобъектным компилятором, который ищет только invokable методы, где он находит макрос Q_OBJECT, а не его подклассы!
Так что вы, ребята, думаете, что решение для этого может быть? Я могу просто добавить макрос Q_OBJECT в DerivedClasses вместо SuperClass, но мне действительно нужен SuperClass для QObject из-за сигналов и т. Д.! Итак, есть ли другой макрос, который я должен добавить к DerivedClass, чтобы moc «видел» его? Или это просто плод неопытности, и я что-то делаю глупой ошибкой?
Заранее спасибо за время, потраченное в ответе мне ;-)
Вы должны использовать макрос Q_OBJECT в ** каждом ** подклассе QObject, который использует свойства или invokable. Кстати, ваше личное наследование сознательное? – jbh
Нет, на самом деле опечатка: -/ Я попытался добавить добавление Q_OBJECT в производный класс раньше, но он жалуется на что-то во время компиляции ... Я не помню, что это было, но я думаю, что речь шла о виртуальной таблице Да, неопределенная ссылка на «vtable» int the DerivedClass – RuiDo
Как вы применили привязку класса к QMContext, через setContextProperty? И какой экземпляр был привязан к движку QML, m - производному или базовому классу? Вы устали использовать производную? – KimKulling