Qt не предназначен для поддержки родителя без виджета QWidget
. Лично я рассматривал бы это как бессмысленный хак на данный момент. Он будет компилироваться, но никогда не будет работать. Я считаю это ошибкой API в Qt, поскольку QWidget
не является полностью QObject
в смысле Принципа замены Лискова из-за этого ограничения.
Qt 4.x будет поврежден при попытке активации виджета. Так что это сработает, пока вы не сфокусируете свое приложение и не сработаете.
Qt 5.x утверждает в QObject::setParent()
.
утверждение можно обойти, хотя:
// https://github.com/KubaO/stackoverflown/tree/master/questions/widget-parent-28992276
#include <QApplication>
#include <QLabel>
class ParentHacker : private QWidget {
public:
static void setParent(QWidget * child_, QObject * parent) {
// The following line invokes undefined behavior
auto child = static_cast<ParentHacker*>(child_);
Q_ASSERT(child->d_ptr->isWidget);
child->d_ptr->isWidget = 0;
child->QObject::setParent(parent);
child->d_ptr->isWidget = 1;
}
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QLabel w{"Hello!"};
w.setMinimumSize(200, 100);
w.show();
ParentHacker::setParent(&w, &app);
return app.exec();
}
Это будет врезаться куда-нибудь потом.
Вы будете сражаться в гору, пытаясь исправить Qt, чтобы заставить его работать. Думаю, что это не достойный бой, если не принято решение сделать QWidget
по-настоящему QObject
и изменить его подпись конструктора. Это можно сделать как можно скорее в Qt 6, поскольку это двоично-несовместимое изменение AFAIK.
Более того, то, что вы пытаетесь сделать, в основном не нужно. У вас наверняка есть скрытый родитель QWidget
для нескольких автономных виджетов верхнего уровня.
#include <QApplication>
#include <QLabel>
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QWidget parent;
QLabel l1{"Close me to quit!"}, l2{"Hello!"};
for (auto label : {&l1, &l2}) {
label->setMinimumSize(200, 100);
label->setParent(&parent);
label->setWindowFlags(Qt::Window);
label->setText(QString("%1 Parent: %2.").
arg(label->text()).arg((quintptr)label->parent(), 0, 16));
label->show();
}
l2.setAttribute(Qt::WA_QuitOnClose, false);
return app.exec();
}
Накладные иметь виджет скрытый минимален, вы не тратить любые ресурсы, используя QWidget
вместо QObject
для родителей.
Просто любопытно: в чем причина такой иерархии? – vahancho
Что?!? QWidget наследуется публично из QObject –
'QWidget :: setParent (QWidget *)' скрывает 'QObject :: setParent (QObject *)'. – Oktalist