2010-09-20 68 views
0

我自己创建了一个小部件,包括QVBoxLayout中的QProgressBar和QLabel。它还具有返回标签文本(自创)的功能。 现在在我的MainWindow中,我有两个其他的QHBoxLayouts,我想将我的小部件从一个拖放到另一个。当我点击QLabel和QProgressBar之间的小空闲空间时,它也可以工作。但是,当我直接点击其中一个时,应用程序就会崩溃并烧伤。
我也知道它失败的地方。我mousePressEvent看起来是这样的:Qt使用自己的小部件拖放?

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(); 
... 

} 

所以,当我点击进度条,它会投的进度,而不是我自己的小工具。并且因为QProgressBar没有像returnLabelText()(但是我的小部件)的功能,所以它失败。
什么是更好的方法来获取我的小部件?

回答

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(); 
    // ... 
} 
+2

qobject_cast会比dynamic_cast的更好,仅供参考.. – ianmac45 2010-09-20 13:47:45

+0

ianmac45是正确的......在QObject对象的情况下,qobject_cast强烈者优先,因为它不依赖于RTTI。 – Fred 2010-09-20 16:56:23