Qt drag和drop演示

本文详细介绍了如何在Qt环境中实现drag和drop功能,通过自定义DragListWidget类,重写mousePressEvent和mouseMoveEvent,实现拖动效果。同时,利用QGraphicsScene的dragEnterEvent、dragMoveEvent和dropEvent处理拖放到工作区的事件,动态添加QGraphicsPixmapItem。
首先,来看效果图:
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 ;

};
 
首先在构造函数中启用drag。
DragListWidget : : DragListWidget ( QWidget * parent ) :
QListWidget ( parent )
{
setDragEnabled ( true );
}
 
在mousePressEvent事件处理函数中,判断是否是左键拖动,如果是,保存一下事件发生的位置。
void DragListWidget : : mousePressEvent ( QMouseEvent * 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
}
到此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 );

};
 
这里主要判断DrapEvent的来源,如果是对应当Widget,就接受这个事件。
void WorkspaceScene : : dragEnterEvent ( QGraphicsSceneDragDropEvent * event )
{
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 ();
}
}

这里是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 ();
}
}
到此Drop效果已实现。
完整源代码点此下载
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值