QListWidget перетаскивает элементы, исчезающие из списка на Symbian

У меня проблемы с реализацией QListWidget с настраиваемыми элементами, которые можно переупорядочить, перетаскивая их. Проблема в том, что когда я делаю быстрый двойной щелчок (очень короткое перетаскивание) по элементу, элемент иногда исчезает из QListWidget.

Это конструктор моего виджета:

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

также событие drop:

void ListPopisiDragDrop::dropEvent(QDropEvent *event){

    int startRow=currentIndex().row();

    QListWidget::dropEvent(event);

    int endRow=currentIndex().row();

    //more code...
}

Пользовательские элементы создаются путем реализации функций paint () и sizeHint () из QAbstractItemDelegate.

Когда возникает проблема с исчезновением элементов, dropEvent даже не вызывается.

Я действительно не знаю, что происходит и делаю ли я что-то не так. Любая помощь приветствуется.

Спасибо!

Изменить: я запускаю приложение на телефоне Symbian S60 5th edition.

Edit2: если я добавлю эту строку в конструктор:

setDragDropOverwriteMode(true);

элемент в списке все равно исчезнет, ​​но пустая строка останется на своем месте.

Edit3: я добавил этот код, чтобы увидеть, что происходит:

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

    QListWidget::event(e);
}

Я также напечатал «событие перетаскивания», когда вызывается событие перетаскивания. Это дает мне следующий результат:

...
[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
...

Как видите, после типа события 68 listCount изменяется с 2 на 1 (исчезает один элемент). Я все еще не понимаю, в чем проблема ...

Edit4: у меня такое же поведение, даже когда я не использую настраиваемые элементы. Все еще не могу понять, что случилось.

Edit5: Даже пример из [1] имеет такое же поведение при тестировании на мобильном устройстве. Может ли быть проблема с версией Qt? Я использую Qt для устройств Symbian версии 4.6.3 ...

[1] http://www.java2s.com/Code/Cpp/Qt/QListWidgetdraganddrop.htm


person ppalasek    schedule 27.12.2010    source источник
comment
тип 68 = добавлен ребенок, 71 = удален ребенок, 12 = краска, 1 = таймер   -  person hmuelner    schedule 28.12.2010


Ответы (2)


Я могу придумать 2 причины такого поведения: сигнал itemDoubleClicked обрабатывается где-то в вашем QListWidget и делает что-то непреднамеренное, или ваш «дополнительный код» в dropEvent делает что-то плохое, когда источник и место назначения совпадают (вы можете проверить, равно ли startRow to endRow и в этом случае ничего не делать).

Редактировать:

Эта программа работает для вас:

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

Строки с тремя звездочками можно удалять. Эта программа у меня работает в Windows XP с Qt 4.7.1, скомпилированной с VS2010.

person hmuelner    schedule 27.12.2010
comment
Спасибо за Ваш ответ. Я обрабатываю сигнал itemDoubleClicked, но нигде ничего не удаляю. Кроме того, при возникновении проблемы не вызывается itemDoubleClicked и не запускается dropEvent. Я даже ничего не делаю, если startRow и endRow равны ... Я отредактирую свой вопрос с дополнительной информацией через минуту. - person ppalasek; 27.12.2010
comment
Да, эта программа отлично работает на компьютере, как и моя, но обе они ведут себя странно при запуске на мобильном телефоне. Попробую обновиться до Qt 4.7.1 - person ppalasek; 28.12.2010
comment
Вы не упомянули, что эта проблема только на мобильном телефоне. Возможно, вам стоит проверить трекер ошибок Qt? - person hmuelner; 28.12.2010

Однажды была такая же проблема на рабочем столе, с SelectionMode, InternalMove и т. Д. Точно так, как показано. Также у меня была собственная модель для представления, поэтому я просто вернул ее таким образом:

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;
}

Со мной все работало нормально.

person MasterAler    schedule 08.06.2015