2013-08-18 12 views
6

Devo creare qualcosa come l'interfaccia iOS, il campo 3x3 di icone che è possibile trascinare per cambiare la loro posizione e quindi ricordarlo nel file XML. Ho deciso di utilizzare la classe Grid (QWidget è padre) come contenitore e il mio clas è stato ereditato da QWidget come elementi. Ora sto cercando di imparare come eseguire un trascinamento per il rilascio di & per QWidget, ma sembra che tu sia in grado di passare a un QWidget, ma è impossibile trascinarlo. È vero o sono solo un ritardato? Come posso spostare questa cosa? x.xTrascinamento di un QWidget in QT 5

+0

Vuoi semplicemente spostare o per trascinarlo/rilasciarlo? Il semplice spostamento è più semplice (http://stackoverflow.com/questions/12219727/dragging-moving-a-qpushbutton-in-pyqt), il trascinamento della selezione diventa complicato (http://stackoverflow.com/questions/24582383/qmimedata -setting-ei-destra-mime-type-per-arbitrari-widget-ottenere-). – neuronet

risposta

3

Trascinare un widget non è così facile. Un sacco di codice che devi fare da solo.

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

Questo significa che, quando il tuo widget riceve un messaggio che è di essere trascinato, per esempio come con un mousepress, deve creare un oggetto QDrag.

Nell'oggetto QDrag è possibile impostare una pixmap, che rappresenta il widget trascinato. Se si nasconde il widget a questo punto, sembra che il puntatore del mouse abbia "preso" il widget.

Inoltre è necessario un oggetto QMimeData. In questo puoi inserire tutti i tipi di dati, che descrivono il tuo widget. Nel tuo caso d'uso qualcosa che ti permette di identificare il tuo widget. Perché, e qui arriva la parte difficile: devi fare il movimento te stesso.

Il widget, che è il padre della griglia, riceve l'evento di rilascio e legge dai dati del mimo, che il widget desidera spostare. Da QDropEvent ottiene il punto in cui il widget deve essere spostato. Questo è ciò che devi codificare: l'effettivo riposizionamento nel tuo layout di griglia. E non dimenticare di aggiornare l'xml.

+0

e, per quanto mi riguarda, mi ricordo che elemento si stava muovendo, ho letto su quale altro elemento è stato rilasciato, quindi ricordo il secondo, sostituirlo con il primo e mettere il secondo sul posto del primo con addWidget() e removeWidget()? –

+0

@Leonid Bor, l'oggetto QDrag ti offre un modo per avere un'icona sotto il puntatore del mouse. E dà un modo per passare i dati sull'oggetto trascinato al ricevitore di rilascio. Se riesci a ottenere questa informazione altrimenti ... nessun problema. addWidget() e removeWidget() sono certamente un modo per eseguire effettivamente la mossa. – Greenflow

0

Il wiki Qt contiene un esempio QtQuick su come emulare l'interfaccia dell'icona iOS con meno di 80 righe di codice.

Potete trovarlo here.

+0

thx, ma il mio capo mi ha impedito di usare questo =/ –

+0

Penso che, se leggi il qml, puoi tradurlo in un layout QGridLayout/QWidget. Dopotutto, qml è solo un altro linguaggio che descrive il layout. –

3

fare un trucco allora si può in grado di trascinare QWidget anche,

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

Ora usano questo widgetPixmap come pixmap per yourDragObject->setPixmap();

esempio,

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

ottengo un errore: impossibile eseguire il rendering con un pittore inattivo – wutzebaer