Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: unkier от Апрель 26, 2010, 20:40



Название: разное поведение drag&drop в win и lin
Отправлено: unkier от Апрель 26, 2010, 20:40
в линуксе всё пашет.

сначало Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
патом на принимающей стороне внутри dropEvent если всё ок то event->acceptProposedAction();
(и тогда drag->exec возвращает нужный dropaction)
или event->ignore(); (и тогда drag->exec возвращает Qt::IgnoreAction)

собрал под виндой и косяк. тот же код работает по другому. drag->exec никогда не возвращает IgnoreAction и получается что дроп на все итемы работает :(

в чём я не прав ?


Название: Re: разное поведение drag&drop в win и lin
Отправлено: SABROG от Апрель 26, 2010, 21:12
Выкладывай минимальный компилируемый пример с ошибкой, будем смотреть.


Название: Re: разное поведение drag&drop в win и lin
Отправлено: unkier от Апрель 28, 2010, 19:44
вот пример. в винде проверил. поведение всё тоже. всегда дропается, даже когда евент игнорится.


Название: Re: разное поведение drag&drop в win и lin
Отправлено: SABROG от Апрель 29, 2010, 00:11
Смотри чего получается. У тебя есть 2 возможности проигнорить перетаскивание итема. Первая это пока мышь зажата и ты таскаешь по виджету итем. Если в этом эвенте ты будешь делать проверку, так например:

Код:
void QDropTreeWidget::dragEnterEvent(QDragEnterEvent *event)
{
// виджет разрешает любые операции по перетаскиванию, когда на него пытаются что-то перетащить
    event->accept();
}

void QDropTreeWidget::dragMoveEvent(QDragMoveEvent *event)
{
// проверяем условия, которые нам подойдут пока пользователь таскает мышку по виджету. Например место вставки итема посреди других итемов.

    if (condition)
        event->acceptProposedAction(); // меняем курсор и позволяем вставку
    event->ignore; // по хорошему это должно отменять предыдущую дозволенную вставку, если условия поменялись
}

То курсор смениться на знак "стоп", при отпускании мышки ты будешь получать свой Qt::IgnoreAction, так как acceptProposedAction() не вызывался.

Второй вариант это делать проверку в момент отпускания мыши.

Код:
void QDropTreeWidget::dragEnterEvent(QDragEnterEvent *event)
{
    event->accept(); // просто позволяем виджету таскать по себе всякий хлам
}

Затем

Код:
void QDropTreeWidget::dragMoveEvent(QDragMoveEvent *event)
{
// если под курсором находится итем, то сигнализируем пользователю изменением курсора и позволяем на него класть. В противном случае твердо стоим на красном перечеркнутом кружке.
  QTreeWidgetItem *item = this->itemAt(event->pos());

  if (item != NULL)
  {
    event->acceptProposedAction();
  }
  else
  {
    event->ignore();
    qDebug() << "NULL";
  }
}

И вот ключевой момент

Код:
void QDropTreeWidget::dropEvent(QDropEvent *event)
{
// делаем дополнительные проверки после того как юзер отпустил мышку, но перед тем как что-либо делать с итемами
    if (!condition)
        event->setDropAction(Qt::IgnoreAction); // итем не тот или звезды не благоволят, отказываем юзеру
}

Код:
void QDragListWidget::mouseMoveEvent(QMouseEvent *event)
{
...
// Если в итоге Qt::IgnoreAction не был установлен, то возвращается действо по умолчанию (Qt::MoveAction)
    Qt::DropAction dropAction = drag->exec(Qt::MoveAction);
    if (dropAction == Qt::MoveAction)
    {
      delete item;
    }
}

P.S.: форматирование не ставил, так как русские комментария коцаются.


Название: Re: разное поведение drag&drop в win и lin
Отправлено: unkier от Апрель 29, 2010, 20:11
спасибо огромное. сразу в точку.