Qt drag和drop演示

来源:互联网 发布:ff14猫娘的捏脸数据 编辑:程序博客网 时间:2024/05/20 06:52
首先,来看效果图:
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效果已实现。
完整源代码点此下载。