问题描述
以下代码完全编译:
QObject* o = new QObject(0);
QWidget* w = new QWidget(0);
qobject_cast<QObject*>(w)->setParent(o);
我不能合法地将 QObject
QWidget
。但是使用 qobject_cast
这是可能的。是否有负面后果?
I cannot legally set QObject
as a parent of QWidget
. But using qobject_cast
it is possible. Are there negative consequences?
推荐答案
Qt不支持非小部件父对象 QWidget
。就我个人而言,我认为它是一个毫无意义的黑客。它会编译,但不会工作。
Qt is not designed to support a non-widget parent to a QWidget
. Personally, I'd treat it as a pointless hack. It'll compile, but won't ever work.
当尝试激活窗口小部件时,Qt 4.x会崩溃。
Qt 4.x will crash when attempting to activate the widget. So it'll work until you focus your application and then will crash.
Qt 5.x在中声明QObject :: setParent()
。
虽然可以忽略断言:
#include <QtWidgets>
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();
}
我会在其他地方失败。
I'll crash somewhere else then.
你会战斗一场艰难的战斗,试图补丁Qt让它工作。这不是一个值得的战斗,我想。
You'd be fighting an uphill battle trying to patch Qt to get it to work. It's not a worthwhile fight, I think.
此外,你想做的是大部分是不必要的。您当然可以有一个隐藏的 QWidget
父对象到多个独立的顶级窗口小部件。
Moreover, what you're trying to do is mostly unnecessary. You can certainly have a hidden QWidget
parent to multiple stand-alone top-level widgets.
#include <QtWidgets>
#include <cstdint>
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((uintptr_t)label->parent(), 0, 16));
label->show();
}
l2.setAttribute(Qt::WA_QuitOnClose, false);
return app.exec();
}
隐藏小部件的开销很小,资源,通过使用 QWidget
而不是父母的 QObject
。
The overhead of having the widget hidden is minimal, you're not wasting any resources by using a QWidget
instead of a QObject
for the parent.
这篇关于强制QObject作为QWidget的父级的后果是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!