国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Qt學習筆記-----拖放

2019-11-11 00:59:32
字體:
來源:轉載
供稿:網友

拖放,拖動和釋放(Drag and Drop),允許用戶利用鼠標在不同組件之間或一個組件上進行數據的拖動。如果哪個組件支持拖放操作,就在該組件的設計上實現某些必要的函數。比如說,我們可能需要在MainWindow這個主窗口上實現拖放,那就在這個類中實現一些函數。如果我們自定義了一個組件,比如說定義了一個類MyDnDWidget繼承自QWidget,我們就在MyDndWidget類中實現特定的函數來支持拖放。

Drag and Drop Types

QMimeData類是Qt內部的一個容器,它記錄著大量擁有Mime Type(元類型)的數據??梢园阉敵墒且粋€map,每一個元素都是”Mime Type, Mime Data”這樣的鍵值對,但是使用的時候不要像map一樣使用,只是用于理解。

拖放操作不只局限在文本和圖像上,任何類型的信息在拖放操作中都能被轉換。為了在應用之間拖動信息,這些應用彼此都應該知道他們允許接收哪種數據格式,同時也應該知道他們可以產生哪種數據格式。這個是由MIME Types實現的。

被構造的QDrag對象包含MIME Types的列表,它能使用這些去表現數據,同時接收拖動數據的那個窗體使用這些MIME Types中的一個去訪問數據。Mime Type可以是Qt中提供的,也可以是用戶自定義的,如果需要自定義一個Mime Type,可以重新實現mimeTypes()函數:

mimeTypes

QStringList QAbstractItemModel::mimeTypes() const

這個函數返回允許的Mime Types列表。默認情況下,內置的models和views使用內部的Mime Type,比如text/uri-list。 當重新實現一個支持拖放操作的model時,如果設計者想要返回的數據格式不同于內部的Mime Type,那就需要重新實現這個函數來返回自定義的Mime Types列表。通常的實現形式為:

QStringList types;types << /* the custom mime types */;return types;

如果在自定義model中重新實現了這個函數,那么同時也需要重新實現mimeData()和dropMimeData()函數:

mimeData

QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const

這個函數返回一個QMimeData *類型的對象,這個對象包含序列化的數據元素,而那些數據元素存儲在形參indexes中。換句話說,就是將模型索引列表indexes中的數據序列化,然后存儲在一個QMimeData中,最后返回這個QMimeData指針。序列化的方法是使用QByteArray和QDataStream兩個類。通常的實現格式為:

if(indexes.isEmpty()) return 0;QMimeData *mimeData = new QMimeData;QByteArray encodeData;QDataStream stream(&encodeData, QIODevice::WriteOnly);foreach(QModelIndex index, indexes){ if(index.value()) { /* 將index中存儲的數據取出來 */ stream << /* 數據1 */ << /* 數據2 */ << /* ... */; }}mimeData->setData(/* your custom mime types */, encodeData);return mimeData;

需要注意的是,當模型索引列表indexes為空時,返回0;

dropMimeData

bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)

當Qt檢測到有Mime Data被釋放到以該模型為model的組件上時,相應model的這個函數被調用。設計者需要重新實現這個函數來處理被釋放的數據,通常是將數據存儲到(插入或追加到)model的數據結構中。如果這個釋放動作和數據被model處理則返回true,否則返回false; 參數中的row, column, parent指明數據釋放的位置。如果row和column為-1,意味著被釋放的數據釋放到了parent上,通常是追加到parent的孩子中。如果row和column大于等于0,則被插入到parent孩子的特定位置。 通常的實現格式為:

if(!data->hasFormats(/* the custom mime types */) return false;if(action == Qt::IgnoreAction) return true;/* 確定插入的位置position */QByteArray encodeData = data->data(/* the custom mime types */);QDataStream stream(&encodeData, Qt::ReadOnly);while(!stream.atEnd()){ stream >> /* 數據1 */ >> /* 數據2 */ >> /* ... */; beginInsertRows(parent, position, position); /* model內部數據結構執行插入操作 */ endInsertRows(); ++position;}return true;

Drop Action

在拖放模型中,用戶既可以拖動信息的拷貝(復制)也可以拖動信息本身(剪切)到一個新地方。但是直到拖放操作完成之后程序才知道用戶是想剪切還是想拷貝。這在拖動不同組件之間的信息時沒有什么影響,但是在同一個組件上拖動時,檢查使用了哪種drop action是很重要的。

Qt::DropAction

Qt::MoveAction 移動數據本身(剪切)Qt::CopyAction 復制數據(復制)Qt::IgnoreAction 忽略數據

在釋放數據的時候,Qt會調用鼠標所在位置上組件的dropEvent()函數,設計者需要在這個函數中告訴拖放操作的數據源drop action以便數據源確定是復制還是剪切。

dropEvent

void QWidget::dropEvent(QDropEvent *event)

通知數據源drop action

event->setDropAction(Qt::MoveAction); /* 通知數據源刪除原數據 */event->accept();

或者

event->setDropAction(Qt::CopyAction); /* 通知數據源保留原數據 */event->accept();

通常拖動操作都是開始于鼠標點擊(mousePRessEvent()函數),而每個拖動操作都是一個QDrag類,所以在鼠標點擊函數中需要定義一個QDrag類,然后執行拖動操作,等待釋放動作的反饋??梢园堰@個函數看成數據源。

mousePressEvent

void QWidget::mousePressEvent(QMouseEvent *event){ /* ... */ /* 取出點擊位置的數據,進行序列化 */ QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction); if(dropAction == Qt::CopyAction || dropAction == IgnoreAction) { /* 不需要刪除原數據 */ } else if(dropAction == Qt::MoveAction) { /* 刪除原數據 */ update(/* event->pos()處的范圍矩形 */) }}

其他一些需要實現的函數

下面這些類處理拖放和必要的mime type的編碼和解碼: QDrag:為以Mime Data為基礎的拖放轉化提供支持。 QDragEnterEvent:這個類型的事件被發送到窗口如果有數據被拖進這個窗口。 QDragLeaveEvent:這個類型的事件被發送到窗口如果有數據被拖離這個窗口。 QDragMoveEvent:當正在拖動時,這個類型的事件會一直被發出。 QDropEvent:當拖放操作完成時,這個類型的時候被發出。

在實現拖放操作時就是圍繞這幾個類來實現特定的函數。

dragEnterEvent

void QWidget::dragEnterEvent(QDragEnterEvent *event);

protected作用域的函數。當鼠標拖進一個窗體的時候,該窗體的這個函數被調用,傳遞的事件作為參數。如果這個事件被忽略了(ignored),那么這個窗體不會接收任何拖動事件。換句話說這個函數就是用于提醒Qt該組件接收的數據類型,判斷是accept()還是ignore()這個事件。通常的實現格式為:

if(event->mimeData()->hasFormats(/* the custom mime types */) event->accept();else event->ignore();

dragLeaveEvent

void QWidget::dragLeaveEvent(QDragLeaveEvent *event);

顧名思義,這個函數就是當拖動超出該組件范圍時調用的。

dragMoveEvent

void QWidget::dragMoveEvent(QDragMoveEvent *event);

當正在拖動時,會一直調用這個函數。可以改變一些變量比如記錄此時的投影矩形,然后在繪制函數中繪制。

paintEvent

void QWidget::paintEvent(QPaintEvent *event);

這個函數就是用于繪制所在類的。它可以被調用由以下理由: 1.repaint()或者update()函數被調用; 2.窗口部件被遮擋并且已經被Qt發現; 3.其他的理由

繪制的時候使用畫刷類QPainter

QPainter painter;painter.begin(this);/* 繪制代碼 */painter.end();
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 平远县| 张家口市| 洛南县| 泽普县| 墨竹工卡县| 丹巴县| 济阳县| 瑞金市| 琼结县| 昌平区| 左云县| 土默特右旗| 湘潭县| 黑水县| 新化县| 金阳县| 桃园县| 临洮县| 新干县| 凉城县| 江油市| 鹰潭市| 蒙山县| 海阳市| 会宁县| 合江县| 招远市| 临洮县| 宁化县| 怀来县| 万载县| 丹江口市| 南开区| 连南| 崇义县| 凯里市| 张掖市| 屯门区| 怀安县| 邢台市| 绥棱县|