<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
做慣了靜態圖,今天來搞一搞動態圖吧,首先來個最基礎的功能:如果讓一個控制元件拖動起來。
展示效果:
按照以往簡單的做法,使用mouseMoveEvent、mousePressEvent、mouseReleaseEvent也是可以實現的。這是最基礎的移動做法。
今天,不使用那種簡單的做法,採用Qt一種特有的拖動方法來實現!
使用QDropEvent實現拖拽事件。
實現控制元件拖拽的流程,如下:
1:建立一個控制元件,這裡使用QLabel控制元件。
2:選中需要拖拽的控制元件
3:重寫拖拽事件。
根據上述操作流程,來實現一個控制元件的拖拽吧!
在Qt中,預設是不響應拖拽訊息的,這跟mouseMoveEvent訊息預設不響應是一樣的,必須明確呼叫,告訴視窗,需要響應此訊息。
this->setAcceptDrops(true);
建立一個初始控制元件,用於初始拖動使用。
QLabel *labIcon = new QLabel(this); labIcon->setText(""); labIcon->setPixmap(QPixmap(":/QDragSingleLabel/image/boat.png")); labIcon->move(10, 10); labIcon->show(); labIcon->setAttribute(Qt::WA_DeleteOnClose);
偷懶起見,對QLabel控制元件設定了視窗關閉銷燬的功能,很是方便。
滑鼠在控制元件上按下,開始做拖動操作;當滑鼠擡起時,不進行拖動操作。
需要知道滑鼠是否點選到控制元件上
這裡需要特殊注意的是:QLabel是一個靜態控制元件,正常情況下是不會響應滑鼠選中效果的。
此時,需要響應QWidget滑鼠按下的事件,將滑鼠點選的點轉換成是否選中QLabel控制元件,側面實現資料點選控制元件效果。
QLabel *child = static_cast<QLabel*>(childAt(event->pos())); if(!child) { //不是QLabel控制元件,不進行處理 return; }
QWidget::childAt(const QPoint& p)const;
說明:返回視窗小部件自身座標系統中p點處的可見子視窗小部件。
查詢到有效QLabel指標後,建立一個可儲存在剪貼簿中的資訊,通過拖放機制進行傳輸的。這裡採用:QMimeData
類實現。
優勢該類可以確保資訊在應用程式之間安全傳輸,並且可以在相同的應用程式內複製。
建立該類並將QLabel中的資料傳入到類中,用於做拖拽使用。
QMimeData *mimeData = new QMimeData; mimeData->setData(qsEnum, itemData);
設定資料。
qsEnum:型別:QString。
在這裡可以設定任意字串,只要保證在拖拽訊息時用的一個字串就可以。為了方便統一,將該字串做了統一設定。
const QString qsEnum = "zhongGuoHaoGongMin";//自定義資料型別
itemData:型別:QByteArray。
對QMimeData傳入的資料,這裡存放了QLabel的圖片以及顯示位置。
QPixmap pixmap = *child->pixmap(); QByteArray itemData; QDataStream dataStream(&itemData, QIODevice::WriteOnly); dataStream << pixmap << QPoint(event->pos() - child->pos());
上述內容準備就緒後,建立拖拽類,用於資料拖拽。
QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); drag->setPixmap(pixmap); drag->setHotSpot(event->pos() - child->pos());
將資料傳遞給拖動物件,設定將在操作期間與遊標一起顯示的畫素圖,並定義一個熱點的位置,該熱點將畫素圖的位置置於遊標之下。
繪製拖動的位置,這裡採用了QPainter繪製機制
QPixmap tempPixmap = pixmap; QPainter painter; painter.begin(&tempPixmap); painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127)); painter.end(); child->setPixmap(tempPixmap);
開始拖動操作,呼叫QDrag::exec()
;
目前只有一個控制元件可以拖動,那麼,當建立多個拖動控制元件時,該如何判斷要拖動哪個呢?
這時候,在建立QMimeData傳入的自定義資料型別就起到作用了。
當資料型別是qsEnum時,進行判斷,如果不是,不進行判斷。
if (event->mimeData()->hasFormat(qsEnum)) { //進行判斷 } else { event->ingnore(); //忽略判斷 }
事件:dragEnterEvent、dragMoveEvent、dropEvent都需要這樣判斷。
當前是匹配的自定義資料型別時,並且是該資源是,接受拖動進入事件,並設定當前為拖動事件。
if (event->source() == this) { event->setDropAction(Qt::MoveAction); event->accept(); }
否則設定執行操作並接收該事件
else { event->acceptProposedAction(); }
結束拖動,響應事件:virtual void dropEvent(QDropEvent *event)override;
除了處理操作3中的事件處理,還需要當滑鼠結束操作時,需要在新的位置上重新建立QLabel控制元件。並將滑鼠按下時建立的QMimeData資料獲取出來,顯示到新建立的QLabel控制元件上。
QByteArray itemData = event->mimeData()->data(qsEnum); QDataStream dataStream(&itemData, QIODevice::ReadOnly); QPixmap pixmap; QPoint offset; dataStream >> pixmap >> offset; QLabel *newIcon = new QLabel(this); newIcon->setPixmap(pixmap); newIcon->move(event->pos() - offset); newIcon->show(); newIcon->setAttribute(Qt::WA_DeleteOnClose);
dropEvent訊息是什麼時候被觸發呢?
當滑鼠左鍵彈起時,說明結束了控制元件拖動事件,需要呼叫dropEvent並重新建立控制元件,顯示新位置。
Qt::DropAction n = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); if (n == Qt::MoveAction) { //結束操作 child->close(); } else { //繼續拖動控制元件,實時顯示新位置 child->show(); child->setPixmap(pixmap); }
到此這篇關於Qt實現拖動單個控制元件移動的範例程式碼的文章就介紹到這了,更多相關Qt拖動控制元件移動內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45