Qt nie jest przeznaczony do obsługi rodzica, który nie jest widgetem, do QWidget
. Osobiście potraktowałbym to jako bezcelowe włamanie w tej chwili. To się skompiluje, ale nigdy nie zadziała. Uważam, że jest to błąd interfejsu API w Qt, ponieważ QWidget
nie jest w pełni sensownym z powodu tego ograniczenia.
Qt 4.x ulegnie awarii podczas próby aktywacji widgetu. Będzie działać, dopóki nie skoncentrujesz aplikacji, a potem się zawiesi.
Qt 5.x zapewnia w QObject::setParent()
.
Twierdzenie można ominąć, choć:
// 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();
}
Będzie on następnie rozbić gdzieś indziej.
Będziesz walczył w bitwach pod górkę, próbując załatać Qt, aby to zadziałało. Uważam, że nie jest to opłacalna walka, chyba że zostanie podjęta decyzja, aby dokonać prawdziwej QWidget
prawdziwie-QObject
i zmienić jego sygnaturę konstruktora. Można to zrobić najwcześniej w Qt 6, ponieważ jest to niezgodna z binarnymi zmianami AFAIK.
Co więcej, to, co próbujesz zrobić, jest w większości niepotrzebne. Z pewnością możesz mieć ukrytego rodzica QWidget
do wielu samodzielnych widgetów najwyższego poziomu.
#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();
}
szczytowy posiadania widget ukryty jest minimalne, nie marnujesz żadnych zasobów za pomocą QWidget
zamiast QObject
dla rodzica.
Po prostu ciekawy: jaki jest powód takiej hierarchii? – vahancho
Co?!? QWidget dziedziczy publicznie z QObject –
'QWidget :: setParent (QWidget *)' ukrywa 'QObject :: setParent (QObject *)'. – Oktalist