2010-09-20 14 views
0

J'ai créé un petit widget moi-même, y compris un QProgressBar et un QLabel dans un QVBoxLayout. Il a aussi une fonction qui renvoie le texte de l'étiquette (auto-créé). Maintenant dans ma MainWindow j'ai deux autres QHBoxLayouts et je veux glisser et déposer mon widget de l'un à l'autre. Cela fonctionne aussi quand je clique sur le peu d'espace libre entre le QLabel et le QProgressBar. Mais quand j'ai cliqué sur l'un d'entre eux directement, l'application s'est écrasée et a brûlé douloureusement.
Je sais aussi où ça échoue. Mon mousePressEvent ressemble à ceci:Qt glisser-déposer avec ses propres widgets?

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

} 

Alors, quand je clique sur la barre de progression, il sera jeté ProgressBar, pas votre widget. Et parce que le QProgressBar n'a pas une fonction comme returnLabelText() (mais mon widget fait) il échoue.
Quelle est la meilleure méthode pour obtenir mon widget?

Répondre

2

QWidget :: childAt (int, int) renvoie le widget enfant, pas le widget parent. Dans votre cas, il renvoie le QProgressBar. Vous essayez ensuite de lancer dans un MyWidget, ce qui n'est pas le cas. Ce que vous recherchez est pour le parent de QProgressBar (ou QLabel).

static_cast ne vérifie pas le type de l'objet que vous tentez de diffuser et génère toujours un pointeur non nul même si la distribution n'est pas valide. Ce que vous cherchez ici est dynamic_cast, qui retournera NULL si l'objet n'est pas du type que vous recherchez. Puisque vous recherchez le parent (ou un ancêtre) du widget sur lequel vous cliquez, vous pouvez utiliser une boucle pour parcourir l'ascendance du widget cliqué afin de trouver l'instance de MyWidget que vous recherchez.

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 serait mieux que dynamic_cast, juste FYI .. – ianmac45

+0

ianmac45 est juste ... dans le contexte de QObjects, qobject_cast est fortement préféré car il ne dépend pas de RTTI. – Fred