2010-09-20 67 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