QT 4.x: как реализовать перетаскивание на рабочий стол или в папку?

Я записал немного приложения передачи файлов, записанного в C++ с помощью QT 4.x... это входит в сервер, показывает пользователю список файлов, доступных на сервере, и позволяет пользователю загрузить или загрузить файлы.

Это все хорошо работает; можно даже опозорить файл от рабочего стола (или от открытой папки), и когда Вы бросаете значок файла в server-files-list-view, перемещаемый файл загружается на сервер.

Теперь у меня есть запрос на противоположное действие, также... мои пользователи хотели бы смочь перетащить файл из server-files-list-view и на рабочий стол, или в открытое окно папки, и иметь тот файл загружается в то местоположение.

Это походит на разумный запрос, но я не знаю, как реализовать его. Существует ли путь к спокойному приложению для обнаружения каталога, соответствующего туда, где "событие отбрасывания" имело место, когда значок был отброшен на рабочий стол или в открытое окно папки? Идеально это было бы Основанным на QT независимым от платформы механизмом, но если это не существует, то определенные для платформы механизмы для MacOS/X и Windows (XP или выше) были бы достаточны.

Какие-либо идеи?

18
задан Rob 27 April 2010 в 19:27
поделиться

3 ответа

Посмотрите QMimeData и его документацию, у него есть виртуальная функция

virtual QVariant retrieveData  ( const QString & mimetype, QVariant::Type type ) const

это означает, что вы перетаскиваете наружу, вы реализуете эти функции соответственно

class DeferredMimeData : public QMimeData
{
  DeferredMimeData(QString downloadFilename) : m_filename(downloadFilename)

  virtual QVariant retrieveData (const QString & mimetype, QVariant::Type type) const 
  {
    if (mimetype matches expected && type matches expected)
    {
       perform download with m_filename
    }
  }
}

Примеры отложенного кодирования демонстрируют этот принцип.

Вам, вероятно, также придется переопределить hasFormat и форматы , чтобы предоставить соответствующие типы, application / octet-stream , вероятно, тот, который может вам помочь По большому счету, вам, вероятно, придется прочитать, как Windows обрабатывает перетаскивание с использованием типов MIME.

Я не знаю, как вы укажете имя файла, под которым он будет сохранен, но вам, вероятно, придется заняться окнами. Также может помочь просмотр источника QWindowsMime . Здесь может быть многоэтапный процесс, в котором вы будете получать запросы на text / uri-list данные для имен файлов, а затем на application / octet-stream для данных.

Надеюсь, это поможет

7
ответ дан 30 November 2019 в 09:27
поделиться

Вы просто реализуете часть перетаскивания . Вам не нужно знать, где происходит сброс, потому что приложение, получающее его, обработает его и решит, где сохранить ваш файл.

Вы создаете QMimeData , не знаете, какой тип, но из того, что я видел здесь и здесь , возможно, «application / octet-stream» с вашим файлом как данные в QByteArray или "text / uri-list" с URL-адресом вашего файла.

Вы создаете QDrag и используете его метод setMimeData () и exec () (не знаете, какой QT :: DropAction выбрать).

Вот пример (отказ от ответственности: я сделал это с цветом, а не с файлами):

void DraggedWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
        start_pos = event->pos();
}

void DraggedWidget::mouseMoveEvent(QMouseEvent *event)
{    
    if (event->buttons() & Qt::LeftButton) {
        int distance = (event->pos() - start_pos).manhattanLength();
        if (distance >= QApplication::startDragDistance())
        {
            /* Drag */
            QMimeData *mime_data = new QMimeData;

            mime_data->setData( ... );

            QDrag *drag = new QDrag(this);
            drag->setMimeData(mime_data);
            drag->exec(Qt::CopyAction);
        }
    }
}

Извините, это неполно, надеюсь, это немного поможет.

2
ответ дан 30 November 2019 в 09:27
поделиться

Я думаю, вы делаете это неправильно.

Вам все равно, куда упадет капля, вы просто знаете, что ее уронили. В DropEvent загрузите файл во временное расположение, а затем установите данные mime в соответствии с тем, что было загружено. Конечно, это может закончиться второй копией на жесткий диск, но с самого начала она будет кроссплатформенной. Возможно, вы сможете оптимизировать его позже с помощью вызовов, специфичных для платформы.

Взгляните на пример дропсайта , чтобы увидеть, как данные mime работают из других источников ...

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

Похоже, что метод двойного копирования является стандартом, если вы этого не сделаете. t написать расширение оболочки (по крайней мере, для Windows). Filezilla и 7zip делают это, они возвращают mime-тип «text / uri-list» с временным местоположением. Таким образом, Explorer копирует данные из временного местоположения в реальное. Ваше приложение может сделать то же самое, создать временный файл (или просто имя) без данных. Используя пример кодирования с задержкой , создайте данные на перетаскивании. Кажется, вся эта операция очень специфична для платформы. В Linux (под управлением KDE) я могу перетаскивать файлы только в зависимости от типа mime. Похоже, окна не такие гибкие.

3
ответ дан 30 November 2019 в 09:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: