首先,来看效果图:
drag演示
drop演示
1、drag效果实现
我这里是对QListWidget的扩充,当然你可以使用其他Widget,实现方法类似,都要重新实现一下mousePressEvent和mouseMoveEvent两个函数,beginPos的作用在后面会提到。
class DragListWidget
:
public QListWidget
{
Q_OBJECT
public :
explicit DragListWidget ( QWidget * parent = 0 );
protected :
void mousePressEvent ( QMouseEvent * event );
void mouseMoveEvent ( QMouseEvent * e );
private :
QPoint beginPos ;
};
{
Q_OBJECT
public :
explicit DragListWidget ( QWidget * parent = 0 );
protected :
void mousePressEvent ( QMouseEvent * event );
void mouseMoveEvent ( QMouseEvent * e );
private :
QPoint beginPos ;
};
首先在构造函数中启用drag。
DragListWidget
:
: DragListWidget ( QWidget
* parent )
:
QListWidget ( parent )
{
setDragEnabled ( true );
}
QListWidget ( parent )
{
setDragEnabled ( true );
}
在mousePressEvent事件处理函数中,判断是否是左键拖动,如果是,保存一下事件发生的位置。
void DragListWidget
:
: mousePressEvent ( QMouseEvent
* event )
{
if ( event - > button () == Qt : : LeftButton )
beginPos = event - > pos ();
QListWidget : : mousePressEvent ( event );
}
{
if ( event - > button () == Qt : : LeftButton )
beginPos = event - > pos ();
QListWidget : : mousePressEvent ( event );
}
在mouseMoveEvent事件的处理函数中,同样先判断是否为左键拖动,计算鼠标移动距离,如果超过拖动的最小距离就当作拖动事件处理,然后获取被拖动到item,存入QMimeData一些在Drop事件中要用到的数据。最后创建QDrag对象,将QMimeData存入QDrag对象中,并设置在拖动过程中显示的图片。
void DragListWidget
:
: mouseMoveEvent ( QMouseEvent
* e )
{
if ( e - > buttons () & Qt : : LeftButton )
{
int nDistance =( e - > pos () - beginPos ). manhattanLength ();
if ( nDistance > = QApplication : : startDragDistance ())
{
QListWidgetItem * item = currentItem ();
if ( item != NULL )
{
QList < QSize > sizes = item - > icon (). availableSizes ();
QSize size = sizes . at ( 0 );
QPixmap pixmap = item - > icon (). pixmap ( size );
QMimeData * mimeData = new QMimeData ;
mimeData - > setText ( item - > text ());
QDrag * drag = new QDrag ( this );
drag - > setMimeData ( mimeData );
drag - > setPixmap ( pixmap );
drag - > setHotSpot ( QPoint ( size . width () / 2 , size . height () / 2 ));
drag - > exec ( Qt : : MoveAction );
} //if
} //if
} //if
}
{
if ( e - > buttons () & Qt : : LeftButton )
{
int nDistance =( e - > pos () - beginPos ). manhattanLength ();
if ( nDistance > = QApplication : : startDragDistance ())
{
QListWidgetItem * item = currentItem ();
if ( item != NULL )
{
QList < QSize > sizes = item - > icon (). availableSizes ();
QSize size = sizes . at ( 0 );
QPixmap pixmap = item - > icon (). pixmap ( size );
QMimeData * mimeData = new QMimeData ;
mimeData - > setText ( item - > text ());
QDrag * drag = new QDrag ( this );
drag - > setMimeData ( mimeData );
drag - > setPixmap ( pixmap );
drag - > setHotSpot ( QPoint ( size . width () / 2 , size . height () / 2 ));
drag - > exec ( Qt : : MoveAction );
} //if
} //if
} //if
}
到此Drag效果已经实现。
2、Drop效果
这里我使用的是QGraphicsScene来实现Drop效果,你可以使用其他可以DropEvent的Widget。重新实现dragEnterEvent、dragMoveEvent和dropEvent三个事件的处理函数。
class WorkspaceScene
:
public QGraphicsScene
{
Q_OBJECT
public :
WorkspaceScene ( QObject * parent = 0 );
protected :
void dragEnterEvent ( QGraphicsSceneDragDropEvent * event );
void dragMoveEvent ( QGraphicsSceneDragDropEvent * event );
void dropEvent ( QGraphicsSceneDragDropEvent * event );
};
{
Q_OBJECT
public :
WorkspaceScene ( QObject * parent = 0 );
protected :
void dragEnterEvent ( QGraphicsSceneDragDropEvent * event );
void dragMoveEvent ( QGraphicsSceneDragDropEvent * event );
void dropEvent ( QGraphicsSceneDragDropEvent * event );
};
这里主要判断DrapEvent的来源,如果是对应当Widget,就接受这个事件。
void WorkspaceScene
:
: dragEnterEvent ( QGraphicsSceneDragDropEvent
* event )
{
DragListWidget * source = qobject_cast < DragListWidget * >(
event - > source ());
if ( source != NULL )
{
event - > setDropAction ( Qt : : MoveAction );
event - > accept ();
}
}
{
DragListWidget * source = qobject_cast < DragListWidget * >(
event - > source ());
if ( source != NULL )
{
event - > setDropAction ( Qt : : MoveAction );
event - > accept ();
}
}
同上
void WorkspaceScene
:
: dragMoveEvent ( QGraphicsSceneDragDropEvent
* event )
{
DragListWidget * source = qobject_cast < DragListWidget * >(
event - > source ());
if ( source != NULL )
{
event - > setDropAction ( Qt : : MoveAction );
event - > accept ();
}
}
{
DragListWidget * source = qobject_cast < DragListWidget * >(
event - > source ());
if ( source != NULL )
{
event - > setDropAction ( Qt : : MoveAction );
event - > accept ();
}
}
这里是DropEvent的处理函数,同样先判断一下来源,再执行相应的操作即可。我这里是为QGraphicsScene添加一个QGraphicsPixmapItem。
void WorkspaceScene
:
: dropEvent ( QGraphicsSceneDragDropEvent
* event )
{
DragListWidget * source = qobject_cast < DragListWidget * >(
event - > source ());
if ( source != NULL )
{
const QMimeData * data = event - > mimeData ();
QPointF pos = event - > scenePos ();
QGraphicsPixmapItem * item = new QGraphicsPixmapItem ;
QString text = data - > text ();
if ( text == "Mark" )
item - > setPixmap ( QPixmap ( ":/images/mark.png" ));
else
item - > setPixmap ( QPixmap ( ":/images/text.png" ));
item - > setPos ( pos );
this - > addItem ( item );
event - > setDropAction ( Qt : : MoveAction );
event - > accept ();
}
}
{
DragListWidget * source = qobject_cast < DragListWidget * >(
event - > source ());
if ( source != NULL )
{
const QMimeData * data = event - > mimeData ();
QPointF pos = event - > scenePos ();
QGraphicsPixmapItem * item = new QGraphicsPixmapItem ;
QString text = data - > text ();
if ( text == "Mark" )
item - > setPixmap ( QPixmap ( ":/images/mark.png" ));
else
item - > setPixmap ( QPixmap ( ":/images/text.png" ));
item - > setPos ( pos );
this - > addItem ( item );
event - > setDropAction ( Qt : : MoveAction );
event - > accept ();
}
}
到此Drop效果已实现。
完整源代码点此下载。
本文详细介绍了如何在Qt环境中实现drag和drop功能,通过自定义DragListWidget类,重写mousePressEvent和mouseMoveEvent,实现拖动效果。同时,利用QGraphicsScene的dragEnterEvent、dragMoveEvent和dropEvent处理拖放到工作区的事件,动态添加QGraphicsPixmapItem。

3536

被折叠的 条评论
为什么被折叠?



