Frage

Ich habe Probleme, ein QListWidget mit benutzerdefinierten Elementen zu implementieren, die durch Ziehen und Abfallen neu bestellt werden können. Das Problem ist, wenn ich einen schnellen Doppelklick (ein sehr kurzer Drag & Drop) für einen Artikel mache, verschwindet das Element manchmal aus dem Qlistwidget.

Dies ist der Konstruktor für mein Widget:

ListPopisiDragDrop::ListPopisiDragDrop(QWidget *parent) :
    QListWidget(parent)
{
    setSelectionMode(QAbstractItemView::SingleSelection);
    setDragEnabled(true);
    viewport()->setAcceptDrops(true);
    setDefaultDropAction(Qt::MoveAction);
    setDropIndicatorShown(true);
    setDragDropMode(QAbstractItemView::InternalMove);
}

Auch das Drop -Event:

void ListPopisiDragDrop::dropEvent(QDropEvent *event){

    int startRow=currentIndex().row();

    QListWidget::dropEvent(event);

    int endRow=currentIndex().row();

    //more code...
}

Benutzerdefinierte Elemente werden durch die Implementierung von Paint () und sizeHtHint () -Funktionen von QabstractItemDelegate erstellt.

Wenn das Problem bei Verschwinden von Gegenständen auftritt, wird das DROPEvent nicht einmal angerufen.

Ich weiß wirklich nicht, was passiert und wenn ich etwas falsch mache. Jede Hilfe wird geschätzt.

Vielen Dank!

Bearbeiten: Ich führe die Anwendung auf einem Telefon der Symbian S60 5th Edition aus.

Edit2: Wenn ich diese Zeile dem Konstruktor hinzufüge:

setDragDropOverwriteMode(true);

Der Artikel in der Liste verschwindet immer noch, aber eine leere Reihe bleibt an ihrem Ort.

Edit3: Ich habe diesen Code hinzugefügt, um zu sehen, was passiert:

bool ListPopisiDragDrop::event(QEvent *e){
    qDebug()<<"new event, type: "<<e->type()<<", listCount: "<<this->count();

    QListWidget::event(e);
}

Ich habe auch "Drop Event" gedruckt, wenn das Drop -Event aufgerufen wird. Dies gibt mir die folgende Ausgabe:

...
[Qt Message] new event, type:  12 , listCount:  2 
[Qt Message] new event, type:  12 , listCount:  2 
[Qt Message] new event, type:  68 , listCount:  2 
[Qt Message] DROPEVENT 
[Qt Message] new event, type:  71 , listCount:  2 
[Qt Message] new event, type:  12 , listCount:  2 
[Qt Message] new event, type:  12 , listCount:  2 
[Qt Message] new event, type:  68 , listCount:  2 
[Qt Message] DROPEVENT 
[Qt Message] new event, type:  71 , listCount:  2 
[Qt Message] new event, type:  12 , listCount:  2 
[Qt Message] new event, type:  12 , listCount:  2 
[Qt Message] new event, type:  12 , listCount:  2 
[Qt Message] new event, type:  68 , listCount:  2 
[Qt Message] new event, type:  12 , listCount:  1 
[Qt Message] new event, type:  12 , listCount:  1 
[Qt Message] new event, type:  1 , listCount:  1
...

Wie Sie sehen können, ändert sich nach dem Ereignis Typ 68 der ListCount von 2 auf 1 (ein Element verschwindet). Ich komme immer noch nicht dort, wo das Problem ist ...

Edit4: Ich habe das gleiche Verhalten, auch wenn ich keine benutzerdefinierten Elemente verwende. Ich kann immer noch nicht herausfinden, was los ist.

Edit5: Auch das Beispiel von [1] hat das gleiche Verhalten, wenn es auf dem mobilen Gerät getestet wird. Könnte die QT -Version ein Problem sein? Ich verwende QT für Symbian Devices Version 4.6.3 ...

1] http://www.java2s.com/code/cpp/qt/qlistwidgetDraganddrop.htm

War es hilfreich?

Lösung

Ich kann mir zwei Gründe für dieses Verhalten vorstellen: Das Signal itemdoublleclicked wird irgendwo in Ihrem Qlistwidget behandelt und macht etwas Unintendet oder Ihr "mehr Code" in Dropevent macht etwas Schlimmes, wenn Quelle und Ziel gleich sind (Sie können überprüfen, ob der Startrow gleich ist zu beenden und in diesem Fall nichts zu tun).

Bearbeiten:

Funktioniert dieses Programm für Sie:

#include <QApplication>
#include <QListWidget>

int main(int argc, char **argv)
{
    QApplication a(argc, argv);

    QListWidget lw;

    for(int i = 1; i < 10; ++i)
        lw.addItem(new QListWidgetItem(QString("Item %1").arg(i)));
    lw.setDragEnabled(true); // ***
    lw.viewport()->setAcceptDrops(true); // ***
    lw.setDefaultDropAction(Qt::MoveAction); // ***
    lw.setDropIndicatorShown(true); // ***

    lw.setDragDropMode(QAbstractItemView::InternalMove);

    lw.show();

    a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
    a.exec();
}

Linien mit drei Sternen können gelöscht werden. Dieses Programm funktioniert bei Windows XP mit QT 4.7.1, zusammengestellt mit VS2010.

Andere Tipps

Hatte einmal auf Desktop mit SelectionMode, InternalMove usw. genau wie gezeigt. Ich hatte auch mein eigenes Modell für die Ansicht, also habe ich es einfach so zurückgekehrt: so:

Qt::ItemFlags MyModel::flags(const QModelIndex& index) const
{
    if (index.isValid())
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled;
}

Arbeitete gut mit mir.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top