【QT】 实现在两个独立控件之间拖放(或不同窗体)

一.拖放操作简介

1.拖放的启动和结束

1)、启动拖放:拖放通过调用QDrag::exec()函数而启动,这意味着在拖放操作结束之前,不会返回该函数,调用QDrag::exe()函数后,Qt拥有对拖动对象的所有权,并会在必要时将其删除
2)、结束拖放:当用户放下拖动或取消拖动操作时结束拖放。
3)、MIME类型使用QMimeData类来描述。MIME类型通常由剪贴板和拖放系统使用,以识别不同类型的数据

2.拖放事件

1)、QDragEnterEvent:拖动进入事件。当拖动操作进入部件时,发送该事件
2)、QDragMoveEvnet:拖动移动事件。当拖动操作正在进行时,发送该事件
3)、QDropEvent:放下事件。在完成拖放操作时发送该事件,即当用户在部件上放下一个对象时,发送此事件
4)、QDragLeaveEvent:当拖放操作离开部件时发送该事件

二.常用方法

setAcceptDrops(true); //设置能否拖动
setDragEnabled(true); //设置能否放置
setDropIndicatorShown(false);//显示拖放指示器
setDropAction(Qt::MoveAction) //设置拖动动作
QDrag::exe(Qt::MoveAction | Qt::CopyAction); //可能的拖放动作(移动、复制)

三.使用步骤

1)、调用setAcceptDrops()、setDragEnabled()函数以使该部件能接受拖放事件。
2)、启动拖放:通常在mousePressEvent()或mouseMoveEvent()函数中启动拖放,记住启动拖放就是调用QDrag对象的exec()函数,在此步把需要拖动的数据保存在QMimeData对象中。
3)、重新实现需要接受放下数据的部件的dragEnterEvent()事件处理函数。
4)、根据需要重新实现dragMoveEvent或dropEvent()函数

以上讲解原文链接

四、具体使用

1.拖动控件设置(QTreeView)

先设置可拖拽属性

this->setSelectionMode(QAbstractItemView::ExtendedSelection); //设置选中模式
this->setDragEnabled(true);       //设置可拖拽
this->setAcceptDrops(true);       //设置能否放置
this->setDefaultDropAction(Qt::MoveAction);//设置拖动动作,当支持的操作支持复制行动时,丢弃操作是复制行动。

重载事件

void ToolBoxShow::mousePressEvent(QMouseEvent * event)
{
	if (event->buttons() & Qt::LeftButton){
		m_startPos = event->pos();
	}
	QTreeView::mousePressEvent(event);
}
	
void ToolBoxShow::mouseMoveEvent(QMouseEvent * event)
{
	if (event->buttons()&Qt::LeftButton){
		m_toolType = getSelectToolType();
		if (INVALID == m_toolType){
			return;
		}
		if ((event->pos() - m_startPos).manhattanLength() < QApplication::startDragDistance()){
			QDrag* drag = new QDrag(this);
			QMimeData* data = new QMimeData;
			QIcon icon;
			data->setImageData(0x1000 + m_toolType);
			drag->setMimeData(data);
			for each (ToolStruct var in m_toolStructV)
			{
				if (m_toolType == var.type){
					icon = var.icon;
				}
			}
			QPixmap pixmap(icon.pixmap(QSize(50, 50)));
			QPainter painter(&pixmap);
			drag->setPixmap(pixmap);
			drag->setHotSpot(QPoint(15, 15));
			drag->exec(Qt::MoveAction);
		}
	}
}

2.放置控件的设置(QTableWidget)

//开启鼠标跟踪
setMouseTracking(true);

2.重载函数

//鼠标事件
void dropEvent(QDropEvent * event);//放下
void dragEnterEvent(QDragEnterEvent * event);//拖入
void dragMoveEvent(QDragMoveEvent * event);//拖动

3.重写事件在相应函数

void ProcessUnitBar::dropEvent(QDropEvent * event)
{
	//添加算子
		if (QApplication::keyboardModifiers() == Qt::ControlModifier)
		{
			_TRY_
			int currentMousePosItemIndex = getCurrentMousePosItem(event->pos());
			QString name;
			int data = event->mimeData()->imageData().toInt();
			if ((data & 0x1000) == 0x1000) {                 //增加配置项
				name = getItemCmdDescription(data - 0x1000);
			}
			int type = data - 0x1000;
			newUnit createUnit = createNewUnit;
			m_pFDetectionProcessManger->unitInsert(currentMousePosItemIndex,type, name, createUnit);
			//m_pFDetectionProcessManger->unitInsert(currentMousePosItemIndex, data - 0x1000, name);
		    this->update();
			this->selectRow(currentMousePosItemIndex + 1);
			_CATCH_
		}
		else
		{
			int data = event->mimeData()->imageData().toInt();
			if ((data & 0x1000) == 0x1000) {                 //增加配置项
				emit addAlgSignal(data - 0x1000);
			}
		}
}

void ProcessUnitBar::dragEnterEvent(QDragEnterEvent * event)
{
	event->accept();
}

void  ProcessUnitBar::dragMoveEvent(QDragMoveEvent * event)
{
	event->accept();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值