2013-08-18 4 views
6

Je dois faire quelque chose comme l'interface iOS, 3x3 champ d'icônes qui peuvent être glissées pour changer leur position, puis se souvenir dans le fichier XML. J'ai décidé d'utiliser la classe Grid (QWidget est parent) comme un conteneur et mes propres clas hérités de QWidget en tant qu'éléments. Maintenant, j'essaie d'apprendre comment effectuer un glisser-déposer pour QWidget, mais il semble que vous ne puissiez que tomber sur un QWidget, mais il est impossible de le faire glisser. Est-ce vrai ou juste que je suis retard? Comment puis-je déplacer cette chose? x.xFaire glisser un QWidget dans QT 5

+0

Voulez-vous simplement déplacer ou le glisser/déposer? Il suffit de le déplacer est plus facile (http://stackoverflow.com/questions/12219727/dragging-moving-a-qpushbutton-in-pyqt), glisser/déposer devient compliqué (http://stackoverflow.com/questions/24582383/qmimedata -setting-and-get-the-right-mime-types-pour-arbitraire-widgets). – neuronet

Répondre

3

Faire glisser un widget n'est pas si simple. Il faut beaucoup de codage à faire soi-même.

De l'Qt Docs:

void MainWindow::mousePressEvent(QMouseEvent *event) 
{ 
    if (event->button() == Qt::LeftButton 
     && iconLabel->geometry().contains(event->pos())) { 

     QDrag *drag = new QDrag(this); 
     QMimeData *mimeData = new QMimeData; 

     mimeData->setText(commentEdit->toPlainText()); 
     drag->setMimeData(mimeData); 
     drag->setPixmap(iconPixmap); 

     Qt::DropAction dropAction = drag->exec(); 
     ... 
    } 
} 

Cela signifie, lorsque votre widget reçoit un message qu'il doit être traîné, par exemple Comme avec un mousepress, il doit créer un objet QDrag.

Dans l'objet QDrag, vous pouvez définir un pixmap qui représente votre widget déplacé. Si vous masquez votre widget à ce stade, il semble que le pointeur de la souris ait «pris» le widget.

De plus, vous avez besoin d'un objet QMimeData. En cela, vous pouvez mettre toutes sortes de données, ce qui décrit votre widget. Dans votre cas d'utilisation quelque chose qui vous permet d'identifier votre widget. Parce que, et voici la partie difficile: Vous devez faire le déplacement vous-même.

Le widget, qui est le parent de la grille, reçoit l'événement drop et lit à partir des données mime, quel widget me souhaite être déplacé. Depuis le QDropEvent, il obtient le point où le widget doit être déplacé. C'est ce que vous devez coder: Le repositionnement réel dans votre disposition de la grille. Et n'oubliez pas de mettre à jour le fichier XML.

+0

et que diriez-vous juste je me souviens quel élément se déplaçait, lire sur quel autre élément il a été abandonné, puis se rappeler le deuxième, le remplacer par premier et mettre deuxième sur la place du premier avec addWidget() et removeWidget()? –

+0

@Leonid Bor, l'objet QDrag vous donne un moyen d'avoir une icône sous le pointeur de votre souris. Et il donne à un moyen de transmettre des données sur l'objet déplacé au récepteur de baisse. Si vous pouvez obtenir cette information autrement ... pas de problème. addWidget() et removeWidget() sont certainement une façon d'effectuer le déplacement. – Greenflow

0

Le wiki Qt contient un exemple QtQuick sur la façon d'émuler l'interface de l'icône iOS avec moins de 80 lignes de code. Vous pouvez le trouver here.

+0

thx, mais mon patron m'a restreint d'utiliser ceci =/ –

+0

Je pense, si vous lisez le qml, vous pouvez le traduire dans une mise en page QGridLayout/QWidget. Après tout, qml est juste un autre langage décrivant la mise en page. –

3

faire un tour, vous pouvez en mesure de faire glisser QWidget aussi,

QPixmap *widgetPixmap = new QPixmap; 
yourWidget->render(widgetPixmap); // rendering the current widget to t_iconTPixmap 

Maintenant, utilisez ce widgetPixmap comme pixmap pour yourDragObject->setPixmap();

exemple,

void MainWindow::mousePressEvent(QMouseEvent *event) 
{ 
if (event->button() == Qt::LeftButton 
    && iconLabel->geometry().contains(event->pos())) { 

    QDrag *drag = new QDrag(this); 
    QMimeData *mimeData = new QMimeData; 

    mimeData->setText(commentEdit->toPlainText()); 

    QPixmap *widgetPixmap = new QPixmap; 
    yourWidget->render(widgetPixmap); 

    drag->setMimeData(mimeData); 
    drag->setPixmap(widgetPixmap); 

    Qt::DropAction dropAction = drag->exec(); 
    ... 
    } 
} 
+0

je reçois une erreur: Impossible de rendre avec un peintre inactif – wutzebaer