Muszę stworzyć coś takiego jak interfejs iOS, pole 3x3 ikon, które można przeciągnąć w celu zmiany ich pozycji, a następnie zapamiętywać w pliku XML. Postanowiłem użyć klasy Grid (QWidget jest rodzicem) jako kontenera i moje własne klasy odziedziczone z QWidget jako elementy. Teraz próbuję dowiedzieć się, jak wykonać przeciągnięcie & drop dla QWidget, ale wydaje się, że jesteś w stanie rzucić tylko na QWidget, ale nie można go przeciągnąć. Czy to prawda, czy po prostu jestem opóźniony? Jak mogę to przenieść? x.xPrzeciąganie QWidget w QT 5
Odpowiedz
Przeciąganie widżetu nie jest takie proste. Mnóstwo kodowania musisz zrobić sam.
Z 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();
...
}
}
Oznacza to, gdy widżet otrzymuje wiadomość, że ma być przeciągnięty, na przykład podobnie jak przy użyciu myszy, musi utworzyć obiekt QDrag.
W obiekcie QDrag można ustawić pixmapę, która reprezentuje przeciągnięty widget. Jeśli ukryjesz widżet w tym miejscu, wygląda na to, że wskaźnik myszy "wziął" widżet.
Dodatkowo potrzebny jest obiekt QMimeData. W tym miejscu możesz umieścić wszystkie rodzaje danych, które opisują Twój widget. W twoim przypadku użyj czegoś, co pozwoli ci zidentyfikować twój widget. Ponieważ, i tu pojawia się trudna część: Musisz wykonać ruchy samodzielnie.
Widżet będący rodzica siatki odbiera zdarzenie upuszczenia i odczytuje dane z mime, który to widget chce przenieść. Z QDropEvent otrzymuje punkt, w którym widżet ma zostać przeniesiony. To właśnie musisz zakodować: Rzeczywiste repozycjonowanie w układzie siatki. I nie zapomnij zaktualizować xml.
a co dopiero pamiętam, który element się poruszał, czytam, na którym innym elemencie został on upuszczony, a następnie zapamiętaj drugi, zastąp go pierwszym i umieść drugi na miejscu pierwszego z addWidget() i removeWidget()? –
@Leonid Bor, obiekt QDrag daje sposób na umieszczenie ikony pod wskaźnikiem myszy. I daje sposób przekazywania danych o przeciągniętym obiekcie do odbiornika kropel. Jeśli możesz uzyskać te informacje w przeciwnym razie ... nie ma problemu. addWidget() i removeWidget() są z pewnością jednym ze sposobów na wykonanie tego ruchu. – Greenflow
Wiki Qt zawiera przykład QtQuick opisujący emulację interfejsu ikony iOS za pomocą mniej niż 80 linii kodu.
Możesz go znaleźć here.
thx, ale mój szef ograniczył mnie do korzystania z tego =/ –
Myślę, że jeśli czytasz qml, możesz przetłumaczyć go na układ QGridLayout/QWidget. W końcu qml jest po prostu innym językiem opisującym układ. –
zrobić trick następnie można stanie przeciągnąć QWidget również
QPixmap *widgetPixmap = new QPixmap;
yourWidget->render(widgetPixmap); // rendering the current widget to t_iconTPixmap
teraz skorzystać z tej widgetPixmap
jak pixmapy dla yourDragObject->setPixmap();
przykład
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();
...
}
}
Wystąpił błąd: nie można renderować z nieaktywnym malarzem – wutzebaer
Czy po prostu chcesz przenieść to lub przeciągnij/upuść? Po prostu przeniesienie jest łatwiejsze (http://stackoverflow.com/questions/12219727/dragging-moving-a-qpushbutton-in-pyqt), przeciąganie/upuszczanie staje się skomplikowane (http://stackoverflow.com/questions/24582383/qmimedata -stawianie-i-uzyskiwanie-właściwych-mime-typów-dla-dowolnych-widżetów). – neuronet