У меня есть два класса, как это:
class Foo { public: Foo(int i) : _i(i) {} int _i; }; Q_DECLARE_METATYPE(Foo*)
class Bar : public Foo
{
public:
Bar(int i, int j) : Foo(i), _j(j) {}
int _j;
};
Q_DECLARE_METATYPE(Bar*)
Моя скамейка такая:
int main(int argc, char *argv[]) { QApplication a(argc, argv); Bar* bar = new Bar(10,11); QVariant var = QVariant::fromValue(bar); Foo * foo = var.value<Foo*>(); // foo IS NULL QPushButton * b = new QPushButton(); QVariant v = QVariant::fromValue(b); QObject * object = v.value<QObject*>(); // object IS NOT NULL return a.exec(); }
Почему foo
ноль ?
QVariant
позволяет полиморфизм, так как у меня нет проблем с object
Так как Foo
не является производным от QObject
а также QVariant
поддерживает только полиморфизм для QObject
Типы
От QVariant :: value документация:
Если QVariant содержит указатель на тип, производный от QObject, тогда T может быть любым типом QObject. Если указатель, сохраненный в QVariant, может быть qobject_cast для T, то этот результат возвращается. В противном случае возвращается нулевой указатель. Обратите внимание, что это работает только для подклассов QObject, которые используют макрос Q_OBJECT.
(Акцент мой). Это перефразировано в части о QVariant::canConvert
на него ссылаются ниже, и нет ничего более о преобразовании указателя. QVariant
просто не поддерживает ваш сценарий.
Плюс в том, что если вы сделаете Foo
подкласс QObject
Вы не должны беспокоиться о Q_DECLARE_METATYPE
больше.
Проблема в том, что нет метаданных о наследовании и нет виртуальной таблицы, поэтому QVariant
не имеет данных о наследовании. Вы можете попробовать добавить какой-нибудь виртуальный метод в базовый класс (лучше всего использовать деструктор), это может помочь (в этом случае будут некоторые данные о наследовании во время выполнения), но я не думаю, что этого достаточно.
Как и в других ответах, эта функция наверняка будет работать QObject
s.
Вы также можете попробовать добавить Q_GADGET
макрос для предоставления метаданных, но я сомневаюсь, что это решит проблему.