你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> Qt之拖放

Qt之拖放

編輯:IOS開發綜合
拖放是應用程序內或者應用程序之間數據傳遞的一種方式。通常是提供數據的復制和移動。拖放主要包括拖動和放下。有些窗口可能只需要提供拖動功能,有些窗口可能只需要放下,有些窗口可能兩者功能都需要具備。Qt的一些控件不需要進行任何設置,就具備拖放功能,比如QLineEdit、QTextEdit。 QLineEdit可以接受拖動過來的字符串,而QTextEdit可以接受拖動的字符串以及拖動文件的路徑。所需要做的就是創建一個對象,然後顯示,如下: QLineEdit lineEdit;
lineEdit.show();
QTextEdit textEdit;
textEdit.show(); QLineEdit接受文字拖放,測試效果: \
  QTextEdit接受文件拖放,顯示文件的路徑,支持多個文件一起拖放,測試效果: \   QWidget實現拖放,需要設置接受拖放, setAcceptDrops(true); 並實現下面事件: void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event); 如果我們只需要QWidget接受放下,那麼就不需要實現: void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event); 這兩個事件主要是,當我們需要QWidget實現拖動時才需要的。 QApplication提供了兩種方式來啟動一個拖動操作:
QApplication::startDragDistance():通過鼠標移動的距離來判斷是否啟動拖放,默認是10個像素點。但也可以通過static void setStartDragDistance(int l);來進行自定義開始拖放的距離。 QApplication::startDragTime():通過鼠標點擊的時長來判斷是否啟動拖放,默認是500ms。也可以通過static void setStartDragTime(int ms);來自定義按壓時長。 為了實現拖放,我們需要在mousePressEvent內記錄鼠標按下的坐標點或者時間點,然後在mouseMoveEvent判斷鼠標移動的距離或者按壓時間是否滿足拖放要求,從而啟動拖放。   執行拖放操作,我們需要創建一個QDrag對象,此對象包含QMimeData,這裡保存著我們需要拖動的數據。 示例:
void QDragDrop::mousePressEvent(QMouseEvent *event)
{
	__super::mousePressEvent(event);
	mStartPoint = event->pos();//起點
}

void QDragDrop::mouseMoveEvent(QMouseEvent *event)
{
	__super::mouseMoveEvent(event);
	if ((event->pos() - mStartPoint).manhattanLength() > QApplication::startDragDistance())//判斷是否執行拖動
	{ 
		QDrag *drag = new QDrag(this);
		QMimeData *mimeData = new QMimeData;
		QByteArray byteArray;//存儲數據
		QDataStream stream(&byteArray,QIODevice::WriteOnly);//流,寫數據
		stream << QImage("C:\\Users\\dlp\\Desktop\\2.png");//讀取一個圖片的數據
		mimeData->setData("MyImage", byteArray);//設置數據
		drag->setMimeData(mimeData);//設置數據
		drag->exec(Qt::MoveAction);//執行拖動
		delete drag;
	}
}
上述示例,讀取了一個圖片的數據保存在QMimeData裡面,作為要傳遞的數據。並且設置了自定義格式"MyImage"。 效果如下: \ 示例代碼如下:
#ifndef QDRAGDROP_H
#define QDRAGDROP_H

#include 
#include 
#include 

class QDragDrop : public QWidget
{
	Q_OBJECT

public:
	QDragDrop(QWidget *parent = 0);
	~QDragDrop();

protected:
	void dragEnterEvent(QDragEnterEvent *event);
	void dragMoveEvent(QDragMoveEvent *event);
	void dropEvent(QDropEvent *event);
	void mousePressEvent(QMouseEvent *event);
	void mouseMoveEvent(QMouseEvent *event);

private:
	QPoint mStartPoint;
	QHBoxLayout  *m_HBox;
};

#endif // QDRAGDROP_H
#include "qdragdrop.h"
#include 
#include 
#include 
#include 

QDragDrop::QDragDrop(QWidget *parent)
	: QWidget(parent)
{
	mStartPoint = QPoint(0, 0);
	m_HBox = new QHBoxLayout(this);
	setAcceptDrops(true);
	setWindowTitle("QWidget");
}

QDragDrop::~QDragDrop()
{

}

void QDragDrop::mousePressEvent(QMouseEvent *event)
{
	__super::mousePressEvent(event);
	mStartPoint = event->pos();//起點
}

void QDragDrop::mouseMoveEvent(QMouseEvent *event)
{
	__super::mouseMoveEvent(event);
	if ((event->pos() - mStartPoint).manhattanLength() > QApplication::startDragDistance())//判斷是否執行拖動
	{ 
		QDrag *drag = new QDrag(this);
		QMimeData *mimeData = new QMimeData;
		QByteArray byteArray;//存儲數據
		QDataStream stream(&byteArray,QIODevice::WriteOnly);//流,寫數據
		stream << QImage("C:\\Users\\dlp\\Desktop\\2.png");//讀取一個圖片的數據
		mimeData->setData("MyImage", byteArray);//設置數據
		drag->setMimeData(mimeData);//設置數據
		drag->exec(Qt::MoveAction);//執行拖動
		delete drag;
	}
}

void QDragDrop::dragEnterEvent(QDragEnterEvent *event)
{
	__super::dragEnterEvent(event);
	if (event->mimeData()->hasFormat("MyImage"))
		event->acceptProposedAction();
}

void QDragDrop::dragMoveEvent(QDragMoveEvent *event)
{
	__super::dragMoveEvent(event);
	if (event->mimeData()->hasFormat("MyImage"))
		event->acceptProposedAction();
}

void QDragDrop::dropEvent(QDropEvent *event)
{
	__super::dropEvent(event);
	if (event->mimeData()->hasFormat("MyImage"))
	{
		QByteArray byteArray = event->mimeData()->data("MyImage");//取數據
		QDataStream stream(&byteArray, QIODevice::ReadOnly);//流,讀數據
		QImage image;
		stream >> image;
		QLabel *pLabel = new QLabel(this);
		pLabel->setPixmap(QPixmap::fromImage(image));
		m_HBox->addWidget(pLabel);
	}
}
如果我們只需要接收放下,不需要拖動的話,那麼就不需要上述示例中的兩個鼠標事件。下面實現了一個拖動圖片到窗口並使用QLabel顯示出來的示例: 效果: \ 示例代碼:
#ifndef QSHOWIMAGE_H
#define QSHOWIMAGE_H

#include 
#include 
#include 
#include 

class QShowImage : public QWidget
{
	Q_OBJECT

public:
	QShowImage(QWidget *parent = 0);
	~QShowImage();

protected:
	void dragEnterEvent(QDragEnterEvent *event);
	void dropEvent(QDropEvent *event);

private:
	QHBoxLayout *mLayout;
};

#endif // QSHOWIMAGE_H
#include "QShowImage.h"
#include 
#include 

QShowImage::QShowImage(QWidget *parent)
	: QWidget(parent)
{
	mLayout = new QHBoxLayout(this);
	setAcceptDrops(true);
	setWindowTitle("ShowImage");
}

QShowImage::~QShowImage()
{

}

void QShowImage::dragEnterEvent(QDragEnterEvent *event)
{
	__super::dragEnterEvent(event);
	if (event->mimeData()->hasUrls())
		event->acceptProposedAction();
}

void QShowImage::dropEvent(QDropEvent *event)
{
	__super::dropEvent(event);
	if (event->mimeData()->hasUrls())
	{
		QList urls = event->mimeData()->urls();
		for each (QUrl url in urls)
		{
			QLabel *pLabel = new QLabel(this);
			QImage image(url.toString().mid(8));
			pLabel->setPixmap(QPixmap::fromImage(image));
			mLayout->addWidget(pLabel);
		}
	}
}

對於QListWidget來說,拖放並不像上面那樣復雜,僅僅設置一下,就可以實現QListWidgetItem的拖動: setDragEnabled(true);
\
實現代碼:
QListWidget qlistWidget;
	QStringList strList = { "Item1", "Item2", "Item3", "Item4", "Item5" };
	qlistWidget.addItems(strList);
	qlistWidget.setViewMode(QListView::IconMode);
	qlistWidget.setDragEnabled(true);
	qlistWidget.show();
但是上述只是移動了位置,Item的具體索引並沒有發生改變。而且如果我們需要實現其他拖放功能,並不能滿足我們的需求。那麼我們就需要重新實現拖放事件,來自定義我們自己需要實現的功能。我實現了如何拖動Item,然後再添加一個Item的功能,兩個QListWidgetItem並沒有什麼關聯,只是為了展示如何實現。 效果: \ 示例代碼:
#ifndef LISTWIDGET_H
#define LISTWIDGET_H

#include 
#include 

class ListWidget : public QListWidget
{
	Q_OBJECT

public:
	ListWidget(QWidget *parent = 0);
	~ListWidget();

	void dragEnterEvent(QDragEnterEvent *event);
	void dragMoveEvent(QDragMoveEvent *event);
	void dropEvent(QDropEvent *event);
private:
	
};

#endif // LISTWIDGET_H
#include "ListWidget.h"
#include 
#include 
#include 

ListWidget::ListWidget(QWidget *parent)
	: QListWidget(parent)
{
	QStringList strList = { "Item1", "Item2", "Item3", "Item4", "Item5" };
	addItems(strList);
	setViewMode(QListView::IconMode);
	setDragEnabled(true);
	setWindowTitle("QListWidget");
}

ListWidget::~ListWidget()
{

}

void ListWidget::dragEnterEvent(QDragEnterEvent *event)
{
	__super::dragEnterEvent(event);
	ListWidget *pList = qobject_cast(event->source());//拖動的源對象
	if (pList && pList == this)
	{
		event->setDropAction(Qt::DropAction::CopyAction);//設置拖動動作,影響鼠標光標
		event->accept();
	}
}

void ListWidget::dragMoveEvent(QDragMoveEvent *event)
{
	__super::dragMoveEvent(event);
	ListWidget *pList = qobject_cast(event->source());//拖動的源對象
	if (pList && pList == this)
	{
		event->setDropAction(Qt::DropAction::CopyAction);//設置拖動動作,影響鼠標光標
		event->accept();
	}
}

void ListWidget::dropEvent(QDropEvent *event)
{
	__super::dropEvent(event);
	ListWidget *pList = qobject_cast(event->source());//拖動的源對象
	if (pList && pList == this)
	{
		QListWidgetItem *pItem = new QListWidgetItem(this);//執行釋放後,要做的事情
		pItem->setText(QString("Item").append(QString::number(count())));
		addItem(pItem);
	}
}
 
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved