Qt non è progettato per supportare un genitore senza widget su un QWidget
. Personalmente, lo tratterei come un hack inutile al momento. Si compilerà, ma non funzionerà mai. Lo considero un bug API in Qt, dal momento che un QWidget
non è completamente un QObject
nel senso Principio di sostituzione di Liskov a causa di questa limitazione.
Qt 4.x si blocca quando si tenta di attivare il widget. Quindi funzionerà finché non focalizzi la tua applicazione e poi si bloccherà.
Qt 5.x asserisce in QObject::setParent()
.
L'affermazione può essere aggirato, anche se:
// 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();
}
andrà in crash da qualche altra parte, allora.
Sareste combattendo una battaglia in salita cercando di applicare Qt per farlo funzionare. Non è una lotta utile, credo - a meno che non venga presa una decisione per rendere un QWidget
un vero QObject
e cambiare la sua firma del costruttore. Questo può essere fatto al più presto in Qt 6 dato che è un cambiamento binario incompatibile con AFAIK.
Inoltre, quello che stai cercando di fare è per lo più inutile. È sicuramente possibile avere un genitore nascosto QWidget
in più widget di livello superiore autonomi.
#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();
}
Il sovraccarico di avere il widget di nascosto è minima, non stai sprecando le risorse utilizzando una QWidget
invece di un QObject
per il genitore.
Solo curioso: qual è la ragione di tale gerarchia? – vahancho
Cosa?!? QWidget eredita pubblicamente da QObject –
'QWidget :: setParent (QWidget *)' nasconde 'QObject :: setParent (QObject *)'. – Oktalist