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

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Qt學(xué)習(xí)筆記-----拖放

2019-11-10 21:40:52
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

拖放,拖動(dòng)和釋放(Drag and Drop),允許用戶利用鼠標(biāo)在不同組件之間或一個(gè)組件上進(jìn)行數(shù)據(jù)的拖動(dòng)。如果哪個(gè)組件支持拖放操作,就在該組件的設(shè)計(jì)上實(shí)現(xiàn)某些必要的函數(shù)。比如說(shuō),我們可能需要在MainWindow這個(gè)主窗口上實(shí)現(xiàn)拖放,那就在這個(gè)類中實(shí)現(xiàn)一些函數(shù)。如果我們自定義了一個(gè)組件,比如說(shuō)定義了一個(gè)類MyDnDWidget繼承自QWidget,我們就在MyDndWidget類中實(shí)現(xiàn)特定的函數(shù)來(lái)支持拖放。

Drag and Drop Types

QMimeData類是Qt內(nèi)部的一個(gè)容器,它記錄著大量擁有Mime Type(元類型)的數(shù)據(jù)。可以把它當(dāng)成是一個(gè)map,每一個(gè)元素都是”Mime Type, Mime Data”這樣的鍵值對(duì),但是使用的時(shí)候不要像map一樣使用,只是用于理解。

拖放操作不只局限在文本和圖像上,任何類型的信息在拖放操作中都能被轉(zhuǎn)換。為了在應(yīng)用之間拖動(dòng)信息,這些應(yīng)用彼此都應(yīng)該知道他們?cè)试S接收哪種數(shù)據(jù)格式,同時(shí)也應(yīng)該知道他們可以產(chǎn)生哪種數(shù)據(jù)格式。這個(gè)是由MIME Types實(shí)現(xiàn)的。

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

mimeTypes

QStringList QAbstractItemModel::mimeTypes() const

這個(gè)函數(shù)返回允許的Mime Types列表。默認(rèn)情況下,內(nèi)置的models和views使用內(nèi)部的Mime Type,比如text/uri-list。 當(dāng)重新實(shí)現(xiàn)一個(gè)支持拖放操作的model時(shí),如果設(shè)計(jì)者想要返回的數(shù)據(jù)格式不同于內(nèi)部的Mime Type,那就需要重新實(shí)現(xiàn)這個(gè)函數(shù)來(lái)返回自定義的Mime Types列表。通常的實(shí)現(xiàn)形式為:

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

如果在自定義model中重新實(shí)現(xiàn)了這個(gè)函數(shù),那么同時(shí)也需要重新實(shí)現(xiàn)mimeData()和dropMimeData()函數(shù):

mimeData

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

這個(gè)函數(shù)返回一個(gè)QMimeData *類型的對(duì)象,這個(gè)對(duì)象包含序列化的數(shù)據(jù)元素,而那些數(shù)據(jù)元素存儲(chǔ)在形參indexes中。換句話說(shuō),就是將模型索引列表indexes中的數(shù)據(jù)序列化,然后存儲(chǔ)在一個(gè)QMimeData中,最后返回這個(gè)QMimeData指針。序列化的方法是使用QByteArray和QDataStream兩個(gè)類。通常的實(shí)現(xiàn)格式為:

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

需要注意的是,當(dāng)模型索引列表indexes為空時(shí),返回0;

dropMimeData

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

當(dāng)Qt檢測(cè)到有Mime Data被釋放到以該模型為model的組件上時(shí),相應(yīng)model的這個(gè)函數(shù)被調(diào)用。設(shè)計(jì)者需要重新實(shí)現(xiàn)這個(gè)函數(shù)來(lái)處理被釋放的數(shù)據(jù),通常是將數(shù)據(jù)存儲(chǔ)到(插入或追加到)model的數(shù)據(jù)結(jié)構(gòu)中。如果這個(gè)釋放動(dòng)作和數(shù)據(jù)被model處理則返回true,否則返回false; 參數(shù)中的row, column, parent指明數(shù)據(jù)釋放的位置。如果row和column為-1,意味著被釋放的數(shù)據(jù)釋放到了parent上,通常是追加到parent的孩子中。如果row和column大于等于0,則被插入到parent孩子的特定位置。 通常的實(shí)現(xiàn)格式為:

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 >> /* 數(shù)據(jù)1 */ >> /* 數(shù)據(jù)2 */ >> /* ... */; beginInsertRows(parent, position, position); /* model內(nèi)部數(shù)據(jù)結(jié)構(gòu)執(zhí)行插入操作 */ endInsertRows(); ++position;}return true;

Drop Action

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

Qt::DropAction

Qt::MoveAction 移動(dòng)數(shù)據(jù)本身(剪切)Qt::CopyAction 復(fù)制數(shù)據(jù)(復(fù)制)Qt::IgnoreAction 忽略數(shù)據(jù)

在釋放數(shù)據(jù)的時(shí)候,Qt會(huì)調(diào)用鼠標(biāo)所在位置上組件的dropEvent()函數(shù),設(shè)計(jì)者需要在這個(gè)函數(shù)中告訴拖放操作的數(shù)據(jù)源drop action以便數(shù)據(jù)源確定是復(fù)制還是剪切。

dropEvent

void QWidget::dropEvent(QDropEvent *event)

通知數(shù)據(jù)源drop action

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

或者

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

通常拖動(dòng)操作都是開始于鼠標(biāo)點(diǎn)擊(mousePRessEvent()函數(shù)),而每個(gè)拖動(dòng)操作都是一個(gè)QDrag類,所以在鼠標(biāo)點(diǎn)擊函數(shù)中需要定義一個(gè)QDrag類,然后執(zhí)行拖動(dòng)操作,等待釋放動(dòng)作的反饋。可以把這個(gè)函數(shù)看成數(shù)據(jù)源。

mousePressEvent

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

其他一些需要實(shí)現(xiàn)的函數(shù)

下面這些類處理拖放和必要的mime type的編碼和解碼: QDrag:為以Mime Data為基礎(chǔ)的拖放轉(zhuǎn)化提供支持。 QDragEnterEvent:這個(gè)類型的事件被發(fā)送到窗口如果有數(shù)據(jù)被拖進(jìn)這個(gè)窗口。 QDragLeaveEvent:這個(gè)類型的事件被發(fā)送到窗口如果有數(shù)據(jù)被拖離這個(gè)窗口。 QDragMoveEvent:當(dāng)正在拖動(dòng)時(shí),這個(gè)類型的事件會(huì)一直被發(fā)出。 QDropEvent:當(dāng)拖放操作完成時(shí),這個(gè)類型的時(shí)候被發(fā)出。

在實(shí)現(xiàn)拖放操作時(shí)就是圍繞這幾個(gè)類來(lái)實(shí)現(xiàn)特定的函數(shù)。

dragEnterEvent

void QWidget::dragEnterEvent(QDragEnterEvent *event);

protected作用域的函數(shù)。當(dāng)鼠標(biāo)拖進(jìn)一個(gè)窗體的時(shí)候,該窗體的這個(gè)函數(shù)被調(diào)用,傳遞的事件作為參數(shù)。如果這個(gè)事件被忽略了(ignored),那么這個(gè)窗體不會(huì)接收任何拖動(dòng)事件。換句話說(shuō)這個(gè)函數(shù)就是用于提醒Qt該組件接收的數(shù)據(jù)類型,判斷是accept()還是ignore()這個(gè)事件。通常的實(shí)現(xiàn)格式為:

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

dragLeaveEvent

void QWidget::dragLeaveEvent(QDragLeaveEvent *event);

顧名思義,這個(gè)函數(shù)就是當(dāng)拖動(dòng)超出該組件范圍時(shí)調(diào)用的。

dragMoveEvent

void QWidget::dragMoveEvent(QDragMoveEvent *event);

當(dāng)正在拖動(dòng)時(shí),會(huì)一直調(diào)用這個(gè)函數(shù)??梢愿淖円恍┳兞勘热缬涗洿藭r(shí)的投影矩形,然后在繪制函數(shù)中繪制。

paintEvent

void QWidget::paintEvent(QPaintEvent *event);

這個(gè)函數(shù)就是用于繪制所在類的。它可以被調(diào)用由以下理由: 1.repaint()或者update()函數(shù)被調(diào)用; 2.窗口部件被遮擋并且已經(jīng)被Qt發(fā)現(xiàn); 3.其他的理由

繪制的時(shí)候使用畫刷類QPainter

QPainter painter;painter.begin(this);/* 繪制代碼 */painter.end();
上一篇:codeforces#395

下一篇:第一個(gè)Win32程序

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 都匀市| 两当县| 剑河县| 龙井市| 凤翔县| 胶州市| 西丰县| 兴和县| 蓬莱市| 宁远县| 余干县| 于田县| 盐边县| 班戈县| 澳门| 郎溪县| 镇宁| 北安市| 南漳县| 海阳市| 天峻县| 阿巴嘎旗| 镇远县| 固镇县| 扬中市| 阜城县| 长汀县| 浦城县| 平湖市| 定安县| 浏阳市| 石棉县| 云阳县| 平乡县| 清水河县| 闽侯县| 松原市| 福泉市| 西平县| 孝感市| 舟山市|