Russian Qt Forum

Qt => Общие вопросы => Тема начата: FrankS от Декабрь 14, 2005, 13:57



Название: Перетаскивание файла
Отправлено: FrankS от Декабрь 14, 2005, 13:57
В документации к QT идёт много примеров "Drag and Drop" в которых производяться махинации в рамках окна программы.

Есть ли у кого-нибудь доступный пример, как реализовать перетаскивание файла (т.е., после того как мы перетаскиваем, допустим с рабочего стола файл, на определёный виджет в программе, мы получаем его имя и полный путь).

Заранее спасибо, если примера нет, ткните куда искать...

добавлено спустя:

 Нашёл пример на русском, для версии 3.х
Пока разобраться не удалось.. =/

добавлено спустя 17 минут:

 Хм, вроде бы разобрался... нужно добавить переопределение двух виртуальных фу-ций:

Код:

void img_t::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("text/plain"))
event->acceptProposedAction();
}

void img_t::dropEvent(QDropEvent *event)
{

    QMessageBox::information(this, "",event->mimeData()->text());
    event->acceptProposedAction();
}


Настроил форму в дизайнере, состоящую из главного окна и линейного редактора, поставив обоим acceptDrops=true, откомпилировал проект, но когда я пытаюсь перенести что-нибудь на работающюю программу появляется курсор перечёркнутого круга...

В чем проблема может быть?

добавлено спустя 1 минуту:

 Упс, туплю, всё работает

добавлено спустя 12 минут:

 Другая проблема (точнее продолжение этой):

Форма состоит из главного окна и лейбы по середине его с небольшим отступом, для главного окна стоит acceptDrops=false, для лэйбы acceptDrops=true, перетащить не удаёться, ни туда, ни туда, ставлю для обоих acceptDrops=true - в главное окно перетащить можно, в лэйбу всё равно нельзя... =/

добавлено спустя 1 час 8 минут:

 Ага, я понял почему так происходит... потому что я определил выше указанные фу-ции в классе главного окна...

Простите за такие ошибки, только сегодня начал писать на QT, а до этого пол года занимался исключительно веб-пр.

Можно как-то определить эти фу-ции для нужного мне виджета, не создовая новый класс?

добавлено спустя 11 минут:

 Еще вопрос, как заставить QT адекватно реагировать на gif? Т.е. так же как и на jpg, чтоб работал на него метод QPixmap::load(...


Название: Перетаскивание файла
Отправлено: Dendy от Декабрь 15, 2005, 16:59
:D  Ну ідеальний програмер! Сам запитав, сам порився та відповів собі.

Цитата: "FrankS"
Можно как-то определить эти фу-ции для нужного мне виджета, не создовая новый класс?


Можна!

Код:
MainWindow::MainWindow()
{
  ...
  label = new QLabel( "my drop label", this );
  label->setEventFilter( this );
  ...
}

bool MainWindow::eventFilter( QObject * o, QEvent * e )
{
  if ( o == label )
  {
    switch ( e->type() )
    {
    case QEvent::DragEnter:
    {
      QDragEnterEvent * de = (QDragEnterEvent *)e;
      ...
    }
      break;
    case QEvent::Drop:
    {
      QDropEvent * de = (QDropEvent *)e;
      ...
    }
      break;
    }
  }
  return false;
}


Название: Перетаскивание файла
Отправлено: FrankS от Декабрь 15, 2005, 17:07
Цитата: "Dendy"
:D  Ну ідеальний програмер! Сам запитав, сам порився та відповів собі.


Просто иногда (особенно когда только начинаешь работать), время уже потраченное на поиск решения ошибки, кажеться большим, чем время потраченное на задавание вопроса на форуме :wink: ...

Цитата: "Dendy"

Можна!

Код:
...


Спасибо большое  :!:  :)


Название: Re: Перетаскивание файла
Отправлено: Amouse от Январь 08, 2008, 13:40
Подскажите, плиз.
Мне нужна похожая вещь, тольк drag из своего приложения в Explorer (к примеру).
Моя программа отображает содержимое жесткого диска (ну скажем, как winrar). Надо чтобы из этой программы
можно было перенести файл в Explorer. В обратную сторону (в мою программу - работает), а в Explorer не получается.
Код взят из книжки по Qt, с добавлением пути файла:
(drag and drop раньше не делал)
dragMoveEvent, dragEnterEvent, setDragDropMode, setAcceptDrops - все задействовано.

    QListWidgetItem *item = currentItem();
    if (item) {
        QMimeData *mimeData = new QMimeData;
   QUrl url1( path );
   QList<QUrl> list1;
   list1.append( url1 );
   mimeData->setUrls( list1 );
   //mimeData->setText( path );

        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
        drag->setPixmap(QPixmap(":/images/person.png"));
        if (drag->start(Qt::MoveAction) == Qt::MoveAction)
            delete item;
    }


Название: Re: Перетаскивание файла
Отправлено: Amouse от Январь 16, 2008, 18:01
Так, с этим вопросом разобрался. Появился другой.

Под 4.2.2 "Drop" работает, под 4.3.2 нет. Валится со странной ошибкой. У кого-нибудь такое было в Drag-and-drop?


Название: Re: Перетаскивание файла
Отправлено: Amouse от Январь 16, 2008, 19:21
Уточнение - только в debug версии.
Error:
Debug Assertion failed
dbgheap.c
_CrtIsValidHeapPointer(..)


Название: Re: Перетаскивание файла
Отправлено: Amouse от Февраль 11, 2008, 17:47
Прошу прощенья, еще вопрос по drag..

запускаем драг -
QDrag *drag = new QDrag(this);
drag->start(Qt::CopyAction);

у меня эта ф-ция ("start") завершает работу только при завершении копирования файла (немаленькое время, если файл большой).
Но насколько я понял из книжки по Qt, она должна возвращать управление сразу, после того как мы отпустили перетаскиваемый объект.
?


Название: Re: Перетаскивание файла
Отправлено: ритт от Февраль 11, 2008, 18:57
в венде не возвращает (только в венде)
попробуй, например, тот же файл в эксплорере из одной папки в другую скопировать, а пока будет копироваться, потяни диалог с прогрессом за тайтл - пока тайтл не отпустишь, прогресс будет стоять на месте

когда-то видел как этот бред обходится, но уже не вспомню


Название: Re: Перетаскивание файла
Отправлено: Вячеслав от Февраль 11, 2008, 20:11
а сунуть его (Drag) в поток низя ?


Название: Re: Перетаскивание файла
Отправлено: Amouse от Февраль 12, 2008, 11:37
да, речь о windows, спасибо.
Сунуть в поток конечно можно, просто я думал что я что-то накосячил с реализацией drag-and-drop.


Название: Re: Перетаскивание файла
Отправлено: Amouse от Февраль 12, 2008, 14:48
а хотя с потоком не все так просто -
"The QDrag must be constructed on the heap with a parent QObject to ensure..."

что-то с ходу у меня не получилось..


Название: Re: Перетаскивание файла
Отправлено: Вячеслав от Февраль 12, 2008, 23:10
ну таки скажи new QDrag(this) ы ? Тут-то чего думать ? ;) Трясти надо .....


Название: Re: Перетаскивание файла
Отправлено: Grekon от Июль 15, 2009, 17:45
Добрый день. Пишу архиватор. Отображаю содержимое архива в QTreeWidget. Хотелось бы, чтобы файл из архива распаковывался при перетаскивании объекта QTreeWidgetItem в окно проводника. Drag & Drop реализую первый раз. Разобрался, что нужно переопределить методы mousePressEvent и mouseMoveeEvent. А вот как правильно создать объект QMimeData не соображу.
Для извлечения файла написан метод uncompress (). Но как узнать, в какую папку пользователь перетащил файл?


Название: Re: Перетаскивание файла
Отправлено: Авварон от Июль 15, 2009, 18:35
самый простой вариант - при drag start распаковываешь файлы в темп, а затем в mime data сохраняешь список url этих файлов - получается структура, понятная проводнику, который ее и интерпретирует как надо (ну и + надо ковырять действие по дефолту - что бы оно перемещалось, а не копировалось)


Название: Re: Перетаскивание файла
Отправлено: Grekon от Июль 15, 2009, 21:35
Авварон, а если пользователь перетащил не в проводник, а еще куда нибудь (случайно или по неопытности). Выходит оно будет распаковываться в темп все равно?
Интересно, как это в WinRar реализовано?


Название: Re: Перетаскивание файла
Отправлено: Авварон от Июль 16, 2009, 11:16
что-то я подвис на этой задаче:) просто так в миме дата ссылку на темп передавать не получится, потому что в момент завершения дропа файлов-то еще нет( но идея верная, тк винрар распаковывает сначала куда-то во временную папку, а уже ПОТОМ перемещает


Название: Re: Перетаскивание файла
Отправлено: Grekon от Июль 16, 2009, 14:02
на сколько я разобрался, узнать, куда пользователь перетащил файл, механизм drag&drop не позволяет?


Название: Re: Перетаскивание файла
Отправлено: IGHOR от Январь 07, 2011, 03:26
перетаскиваю файл из експлорера в приложение,
как вытащить превьюшку файла ту что при драге с експлорера на самого себя видно?
нужно ее оставить и сделать аналог подписи действия как на скрине в мое приложение


Название: Re: Перетаскивание файла
Отправлено: Пантер от Январь 10, 2011, 10:31
Если я правильно понял, то
Код
C++ (Qt)
QIcon QFileIconProvider::icon ( const QFileInfo & info ) const


Название: Re: Перетаскивание файла
Отправлено: IGHOR от Февраль 14, 2011, 05:39
Если я правильно понял, то
Код
C++ (Qt)
QIcon QFileIconProvider::icon ( const QFileInfo & info ) const

спасибо, это очень полезная функция, раньше я это на WinApi делал, теперь запомню.

Но если пользователь тащит много файлов, то превью под мышкой состоит из сетки файлов,
именно ее (точную копию) я и хотел сохранить на приложении. Это возможно?
Это первое, а второе, появилась проблема, при перетаскивании файла из експлорера на виджет с зажатым Shift файл почему-то перемещается в корзину. В общем я бы и сам фильтровал модифиеры.. как исправить это?
Можно ли достучаться к объекту QDrag при перетаскивании файла с експлорера на виджет?
И я еще не разобрался откуда получать сигналы о изменении Qt::DropAction .. фильтрую таймером модифиеры :)
Помогите кто чем может :)