Russian Qt Forum
Октябрь 01, 2024, 02:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как сделать Drag-n-Drop самому без SetCapture?  (Прочитано 6152 раз)
Caduceus
Гость
« : Октябрь 26, 2009, 12:29 »

У меня есть Qt-шный QGraphicsView и есть нативное Win-окно - дочернее к основному Qt-ному - то есть как бы и виджет и нативное окно - это контролы внутри основного окна. Мне надо сделать Drag-n-Drop из QGraphicsView  в мое нативное окно. То есть как бы понятно,Ж что там надо обработать захват, потом ловить MouseMove в нативном окне и MouseUp в нативном окне. Проблема в том, что видимо  QGraphicsView   автоматом делает SetCapture и если я начинаю стаскивать объект с QGraphicsView  и веду мышкой надо нативным окном, то туда не приходят MouseMove

Как заставить QGraphicsView  не делать захват мыши?
Записан
Caduceus
Гость
« Ответ #1 : Октябрь 27, 2009, 09:36 »

м-м-м, судя по наплыву отвечающих, вопрос не был понят.

Переформулирую - как сделать Drag-n-Drop из Qt-шного виджета в обычное WinAPI окно?
Записан
shadone
Гость
« Ответ #2 : Октябрь 27, 2009, 13:30 »

м-м-м, судя по наплыву отвечающих, вопрос не был понят.

Переформулирую - как сделать Drag-n-Drop из Qt-шного виджета в обычное WinAPI окно?
mouse press / mouse move не являются механизмом Drag-n-Drop - для него существует отдельный "протокол". Все что нужно сделать со стороны Qt - это начать drag создав объект QDrag. см документаицю по Drag-and-Drop.
На стороне родного Win окна нужно разрешить drop. См документацию по RegisterDragDrop
Записан
SABROG
Гость
« Ответ #3 : Октябрь 27, 2009, 14:59 »

Вроде бы всё работает:

Код
C++ (Qt)
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QtGui/QWidget>
#include <QtGui/QGraphicsRectItem>
 
namespace Ui
{
   class Widget;
}
 
class Widget : public QWidget
{
   Q_OBJECT
 
public:
   Widget(QWidget *parent = 0);
   ~Widget();
 
private:
   Ui::Widget *ui;
};
 
class MyItem : public QGraphicsRectItem
{
public:
   MyItem(const QRectF &rect);
protected:
   virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
   virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
};
 
#endif // WIDGET_H
 
 

Код
C++ (Qt)
#include "widget.h"
#include "ui_widget.h"
 
#include <QtCore/QUrl>
 
#include <QtGui/QDrag>
#include <QtCore/QMimeData>
 
#include <QtGui/QGraphicsSceneMouseEvent>
#include <QtGui/QGraphicsSceneDragDropEvent>
 
Widget::Widget(QWidget *parent)
   : QWidget(parent), ui(new Ui::Widget)
{
   ui->setupUi(this);
 
   ui->graphicsView->setScene(new QGraphicsScene(ui->graphicsView));
   ui->graphicsView->scene()->addItem(new MyItem(QRectF(0, 0, 100, 100)));
}
 
Widget::~Widget()
{
   delete ui;
}
 
MyItem::MyItem(const QRectF &rect) : QGraphicsRectItem(rect)
{
}
 
void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
   if (event->button() == Qt::LeftButton) {
        QDrag *drag = new QDrag(scene()->views()[0]);
        QMimeData *mimeData = new QMimeData;
 
        mimeData->setUrls(QList <QUrl>() << QUrl::fromLocalFile(QCoreApplication::applicationFilePath()));
 
        drag->setMimeData(mimeData);
        drag->exec(Qt::CopyAction);
    }
}
 
void MyItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
   if (event->mimeData()->hasUrls())
   event->acceptProposedAction();
}
 
 

Хватаем мышой квадратик и тащим на рабочий стол. На нем должна появится копия exe'шника программы. Т.е. никакие setCapture не мешают.
Записан
Caduceus
Гость
« Ответ #4 : Ноябрь 02, 2009, 23:16 »

Единственный правльный вариант видимо через  реализацию IDropTarget и RegisterDragDrop для нативного окна. Всяко перепробовал - никак не работает. Черт. Если регистрирую свой IDropTarget и тащу из виджета в это окно, то вообще вся прога падает. В функции IDropTarget-а не заходит... Грустный

Кто-нить может ткнуть в пример чистой реализации IDropTarget и RegisterDragDrop без всяких MFC ?
Записан
shadone
Гость
« Ответ #5 : Ноябрь 02, 2009, 23:31 »

Единственный правльный вариант видимо через  реализацию IDropTarget и RegisterDragDrop для нативного окна. Всяко перепробовал - никак не работает. Черт. Если регистрирую свой IDropTarget и тащу из виджета в это окно, то вообще вся прога падает. В функции IDropTarget-а не заходит... Грустный

Кто-нить может ткнуть в пример чистой реализации IDropTarget и RegisterDragDrop без всяких MFC ?
http://qt.gitorious.org/qt/qt/blobs/4.6/src/gui/kernel/qdnd_p.h#line283 and http://qt.gitorious.org/qt/qt/blobs/4.6/src/gui/kernel/qdnd_win.cpp Улыбающийся
Записан
Caduceus
Гость
« Ответ #6 : Ноябрь 02, 2009, 23:37 »

Черт. Так ведь и делаю. Вот заделал такой класс:
Код:
class MyTarget: public IDropTarget
{
public:
MyTarget(HWND hWnd)
{} ;

public:
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, VOID **ppvObject)
{
if ( riid == IID_IUnknown)
{
AddRef();
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
}

if (riid == IID_IDropTarget)
{
AddRef();
*ppvObject = static_cast<IDropTarget*>(this);
return S_OK;
}

// unknown interface requested
*ppvObject = NULL;     // must set out pointer parameters to NULL
return E_NOINTERFACE;

}
virtual ULONG STDMETHODCALLTYPE AddRef (VOID)
{
return 1;
}
virtual ULONG STDMETHODCALLTYPE Release (VOID)
{  
return 1;
}

public:
virtual HRESULT STDMETHODCALLTYPE DragEnter (IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
return NOERROR;
}
virtual HRESULT STDMETHODCALLTYPE DragOver (DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
return NOERROR;
}
virtual HRESULT STDMETHODCALLTYPE DragLeave (VOID)
{
return NOERROR;
}
virtual HRESULT STDMETHODCALLTYPE Drop (IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
return NOERROR;
}

protected:
HRESULT STDMETHODCALLTYPE ClearTarget (VOID)
{
return NOERROR;
}
HRESULT STDMETHODCALLTYPE DropEffect (DWORD grfKeyState, DWORD *pdwEffect)
{
return NOERROR;
}
}; // MyTarget

Создал глобальный объект этого класса:
Код:
static MyTarget  drop_target;

Регистрю для моего нативного окна вот так:
Код:
HRESULT hr;
hr = RegisterDragDrop(displayWindow, &drop_target);

hr всегда S_OK

И ничего. Виснет программа когда пытюсь стащить что-то в нативное окно... Грустный((

Ни в одну функцию класса MyTarget  кроме AddRef и конструктора не заходит...
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.114 секунд. Запросов: 21.