我自己创建了一个小部件,包括QVrogressBar和QVBoxLayout中的QLabel。它还有一个返回标签文本(自创)的函数。
现在在我的MainWindow中我还有另外两个QHBoxLayouts,我想将我的小部件从一个拖放到另一个。当我点击QLabel和QProgressBar之间的小空闲空间时,它也可以工作。但当我直接点击其中一个时,应用程序崩溃并痛苦地烧毁
我也知道失败的地方。我的mousePressEvent
看起来像这样:
void DragDrop::mousePressEvent(QMouseEvent *event) {
// !!!!---- make sure ONLY MyWidgets are here, else: CRASH ----!!!!
MyWidget *child = static_cast<MyWidget*>(childAt(event->pos()));
if (!child)
return;
qDebug() << child->returnLabelText();
...
}
因此,当我点击ProgressBar时,它会转换ProgressBar,而不是我自己的小部件。并且因为QProgressBar没有returnLabelText()
之类的功能(但我的小部件确实如此),它会失败。
获取我的小部件有什么更好的方法?
答案 0 :(得分:2)
QWidget :: childAt(int,int)返回子小部件,而不是父小部件。在您的情况下,它返回QProgressBar。然后,您尝试转换为MyWidget,而不是。您正在寻找的是QProgressBar(或QLabel)的父级。
static_cast
不会验证您尝试强制转换的对象的类型,并且即使转换无效也将始终生成非空指针。你在这里寻找的是dynamic_cast
,如果对象不是你想要的类型,它将返回NULL。由于您正在查找被单击的窗口小部件的父(或祖先),因此您可以使用循环来遍历单击的窗口小部件的祖先,以查找您正在查找的MyWidget实例。
void DragDrop::mousePressEvent(QMouseEvent *event) {
QWidget *widget = childAt(event->pos());
do {
MyWidget *myWidget = dynamic_cast<MyWidget*>(widget);
widget = widget->parentWidget();
} while (myWidget == NULL && widget != NULL)
if (myWidget == NULL)
return;
qDebug() << myWidget->returnLabelText();
// ...
}