2013-08-18 7 views
6

Ich muss so etwas wie iOS-Schnittstelle, 3x3 Feld von Symbolen, die gezogen werden können, um ihre Position zu ändern, und dann merken Sie sich in XML-Datei. Ich entschied mich dafür, die Grid-Klasse (QWidget ist übergeordnet) als Container zu verwenden und meine eigenen Klassen von QWidget als Elemente zu übernehmen. Jetzt versuche ich zu lernen, wie man einen Drag & Drop für QWidget durchführt, aber es scheint, als ob du nur auf ein QWidget fallen kannst, aber es ist unmöglich es zu ziehen. Ist es wahr oder nur ich bin zurückhaltend? Wie bewege ich dieses Ding? x.xZiehen eines QWidget in QT 5

+0

Wollen Sie nur bewegen es oder Drag/Drop es? Einfach verschieben ist einfacher (http://stackoverflow.com/questions/12219727/dragging-moving-a-qpushbutton-in-pyqt), Drag & Drop wird kompliziert (http://stackoverflow.com/questions/24582383/qmimedata - setze-und-bekomme-die-richtige-Pantomime-Typen-für-beliebige-Widgets). – neuronet

Antwort

3

Das Ziehen eines Widgets ist nicht so einfach. Viel Code, den Sie selbst tun müssen.

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

Das bedeutet, wenn Ihr Widget eine Nachricht empfängt, die es zu gezogen werden, z.B. Wie bei einer Mausdruck muss ein QDrag-Objekt erstellt werden.

Im QDrag-Objekt können Sie eine Pixmap festlegen, die Ihr gezogenes Widget darstellt. Wenn Sie Ihr Widget an diesem Punkt ausblenden, sieht es so aus, als würde Ihr Mauszeiger das Widget "übernehmen".

Zusätzlich benötigen Sie ein QMimeData-Objekt. Darin können Sie alle Arten von Daten ablegen, die Ihr Widget beschreiben. In Ihrem Anwendungsfall etwas, mit dem Sie Ihr Widget identifizieren können. Denn und hier kommt der schwierige Teil: Du musst das Bewegen selbst machen.

Das Widget, das das übergeordnete Element des Rasters ist, empfängt das Ereignis drop und liest aus den MIME-Daten, die das Widget für mich verschoben haben soll. Aus dem QDropEvent wird der Punkt ermittelt, an den das Widget verschoben werden soll. Das müssen Sie programmieren: Die eigentliche Neupositionierung in Ihrem Rasterlayout. Und vergiss nicht, das XML zu aktualisieren.

+0

und was ist, ich erinnere mich nur, welches Element bewegte sich, lesen Sie auf welches andere Element es fallen gelassen wurde, dann erinnere mich an das zweite, ersetzen Sie es mit dem ersten und setzen Sie das erste mit addWidget() und removeWidget()? –

+0

@Leonid Bor, das QDrag-Objekt gibt Ihnen eine Möglichkeit, ein Symbol unter Ihrem Mauszeiger zu haben. Und es gibt eine Möglichkeit, Daten über das gezogene Objekt an den Drop-Empfänger zu übergeben. Wenn Sie diese Information sonst bekommen können ... kein Problem. addWidget() und removeWidget() sind sicherlich eine Möglichkeit, den Umzug tatsächlich durchzuführen. – Greenflow

0

Das Qt-Wiki enthält ein QtQuick-Beispiel zur Emulation der iOS-Symbolschnittstelle mit weniger als 80 Codezeilen.

Sie können es here finden.

+0

thx, aber mein Chef hat mich davon abgehalten, dieses zu verwenden =/ –

+0

Ich denke, wenn Sie das qml lesen, können Sie es in ein QGridLayout/QWidget-Layout übersetzen. Schließlich ist qml nur eine andere Sprache, die das Layout beschreibt. –

3

einen Trick tun, dann können Sie auch in der Lage ziehen QWidget,

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

nun diese widgetPixmap als pixmap verwenden für yourDragObject->setPixmap();

Beispiel

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

Ich bekomme einen Fehler: Kann nicht mit einem inaktiven Maler rendern – wutzebaer