以下代码完美编译:
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?
强制 QObject 作为 QWidget 的父级有什么后果?
What are consequences of forcing QObject as a parent of QWidget?
不可撤销的未定义行为.
Irrevocable undefined behavior.
Qt 并非旨在支持 QWidget 的非小部件父级.我认为这是 Qt 中的一个 API 错误,因为由于这种限制,QWidget 在 Liskov 替换原则意义上并不完全是 QObject.
Qt is not designed to support a non-widget parent to a QWidget. I consider it an API bug in Qt, since a QWidget isn't fully a QObject in the Liskov Substitution Principle sense because of that limitation.
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() 中断言.
Qt 5.x asserts in 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();
}
然后它会在其他地方崩溃.
It will crash somewhere else then.
您会在尝试修补 Qt 以使其正常工作时进行一场艰苦的战斗.我认为这不是一场值得的斗争 - 除非决定使 QWidget 真正成为 QObject 并更改其构造函数签名.这最早可以在 Qt 6 中完成,因为它是一个二进制不兼容的更改 AFAIK.
You'd be fighting an uphill battle trying to patch Qt to get it to work. It's not a worthwhile fight, I think - not unless a decision is made to make a QWidget truly-a QObject and change its constructor signature. That can be done at the earliest in Qt 6 since it's a binary-incompatible change AFAIK.
此外,您尝试做的事情大多是不必要的.您当然可以为多个独立的顶级小部件设置一个隐藏的 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 <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 为父级浪费任何资源.
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 的父级有什么后果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
如何在 C++ 中读取和操作 CSV 文件数据?How can I read and manipulate CSV file data in C++?(如何在 C++ 中读取和操作 CSV 文件数据?)
在 C++ 中,为什么我不能像这样编写 for() 循环:In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,为什么我不能像这样编写 for() 循环: for(
OpenMP 如何处理嵌套循环?How does OpenMP handle nested loops?(OpenMP 如何处理嵌套循环?)
在循环 C++ 中重用线程Reusing thread in loop c++(在循环 C++ 中重用线程)
需要精确的线程睡眠.最大 1ms 误差Precise thread sleep needed. Max 1ms error(需要精确的线程睡眠.最大 1ms 误差)
是否需要“do {...} while ()"?环形?Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?环形?)