Qt之QAbstractItemView視圖項拖拽(二)

一、需求說明???

??? 上一篇文章Qt之QAbstractItemView視圖項拖拽(一)講述了實現QAbstractItemView視圖項拖拽的一種方式,是基于QDrag實現的,這個類是qt自己封裝好了的,所以可定制性也就沒有了那么強,最明顯的是,這個類在執行exec方法后,mouse系列的回調接口就被阻塞了,隨之而來的問題就是拖拽時item項沒有了hover特性,為了解決這個問題,我們就不能使用QDrag類來實現拖拽了,這也是這篇文章我要講述的內容。

二、效果展示 ?

??? 如圖1是demo的效果展示,比較丑,如果加上優秀的qss,那必然能讓人眼前一亮

圖1 ListWidget拖拽


三、實現思路

  1. 繼承QListWidget類,重寫其鼠標多拽時幾個虛方法,分別是mousePressEvent(鼠標按下),mouseMoveEvent(鼠標移動),mouseReleaseEvent(鼠標彈起)等,當然還包括一些輔助的回調方法enterEvent和leaveEvent。
  2. 鼠標按下時,記錄鼠標按下位置和鼠標點擊項
  3. 鼠標移動時移動插入項標示和item項快照位置,并修改鼠標形狀
  4. 最后鼠標釋放時,判斷如果需要更新拖拽項位置,那么把原有項刪除,并構造新的項插入到目標位置

?? ?? 上邊的幾個步驟描述都是在mouse系列的回到接口中發生的,再也沒有QDrag的事兒啦。當然這個mouse方法中需要做一些鼠標狀態維護等。

四、代碼說明

??? 1、重要的類和上一篇文章中的一樣,忘記的小伙伴可以到上一篇文章查看,或者猛戳Qt之QAbstractItemView視圖項拖拽(一)
?? ?2、下面就直接上代碼
?? ?a、記錄鼠標按下時信息

 1 void DragList::mousePressEvent(QMouseEvent * event)
 2 {
 3     if (event->button() == Qt::LeftButton)
 4     {
 5         m_LeftPress = true;
 6         startPos = event->pos();
 7         dragItem = itemAt(event->pos());
 8     }
 9 
10     QListWidget::mousePressEvent(event);
11 }

??? b、鼠標移動時維護鼠標狀態、快照位置和插入表示位置

 1 void DragList::mouseMoveEvent(QMouseEvent * event)
 2 {
 3     QListWidgetItem * item = itemAt(event->pos());
 4     if (dragItem == nullptr)
 5     {
 6         dragItem = itemAt(event->pos());
 7     }
 8 
 9     if (m_ShotPicture == nullptr)
10     {
11         InitShotLabel();
12     }
13     if (m_ShotLine == nullptr)
14     {
15         InitShotLine();
16     }
17 
18     QRect rect = visualItemRect(dragItem);
19     if (ListItem * hoverWidget = ItemWidget(item))
20     {
21         QRect hoverRect = visualItemRect(item);
22         QPoint pos = hoverWidget->mapFromParent(event->pos());
23         if (hoverRect.size().height() / 2 < pos.y())
24         {
25             m_ShotLine->move(mapToGlobal(QPoint(2, hoverRect.y() + hoverRect.height() + 1)));
26         }
27         else
28         {
29             m_ShotLine->move(mapToGlobal(QPoint(2, hoverRect.y() + 1)));
30         }
31         
32         m_ShotLine->setVisible(hoverRect.contains(event->pos()));
33     }
34 
35     if (ListItem * newWidget = ItemWidget(dragItem))
36     {
37         m_ShotPicture->move(mapToGlobal(event->pos() - newWidget->mapFromParent(startPos)));
38         if (rect.contains(event->pos()) || event->pos().isNull())
39         {
40             setCursor(Qt::ForbiddenCursor);
41         }
42         else
43         {
44             setCursor(Qt::ArrowCursor);
45         }
46         if (m_ShotPicture->isHidden())
47         {
48             m_ShotPicture->show();
49         }
50     }
51 
52 
53 //    QListWidget::mouseMoveEvent(event);
54 }

??? c、鼠標釋放時處理拖拽結果

 1 void DragList::mouseReleaseEvent(QMouseEvent * event)
 2 {
 3     if (event->button() == Qt::LeftButton)
 4     {
 5         m_LeftPress = false;
 6         if (m_ShotPicture)
 7         {
 8             m_ShotPicture->close();
 9             m_ShotPicture->deleteLater();
10             m_ShotPicture = nullptr;
11         }
12         if (m_ShotLine)
13         {
14             m_ShotLine->close();
15             m_ShotLine->deleteLater();
16             m_ShotLine = nullptr;
17         }
18         MouseRelease(event);
19     }
20 
21     setCursor(Qt::ArrowCursor);
22 
23     QListWidget::mouseReleaseEvent(event);
24 }

??? d、初始化跟隨鼠標移動的快照,并把當前拖拽的窗口截圖設置給快照

 1 void DragList::InitShotLabel()
 2 {
 3     m_ShotPicture = new QLabel;
 4     m_ShotPicture->setWindowOpacity(0.95);
 5     m_ShotPicture->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
 6     m_ShotPicture->setAttribute(Qt::WA_TransparentForMouseEvents, true);
 7 
 8     if (ListItem * oldWidget = ItemWidget(dragItem))
 9     {
10         m_ShotPicture->setPixmap(oldWidget->grab());
11         m_ShotPicture->resize(visualItemRect(dragItem).size());
12     }
13     m_ShotPicture->show();
14 }

??? e、初始化鼠標插入位置標示

 1 void DragList::InitShotLine()
 2 {
 3     m_ShotLine = new QLabel;
 4     m_ShotLine->setObjectName(QStringLiteral("ShotLine"));
 5     m_ShotLine->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
 6     m_ShotLine->setAttribute(Qt::WA_TransparentForMouseEvents, true);
 7     m_ShotLine->setStyleSheet("QLabel#ShotLine{background:green;}");//用圖片代替
 8     
 9     if (ListItem * oldWidget = ItemWidget(dragItem))
10     {
11     //    m_ShotLine->setPixmap(oldWidget->grab());
12         m_ShotLine->resize(visualItemRect(dragItem).size().width(), 2);
13     }
14     m_ShotLine->show();
15 }

??? f、鼠標彈起具體處理函數

 1 void DragList::MouseRelease(QMouseEvent * event)
 2 {
 3     QListWidgetItem * item = itemAt(event->pos()); 
 4     if (item == nullptr || item == dragItem)
 5     {
 6         return;
 7     }
 8 
 9     int insertPos = row(item);
10     if (ListItem * oldWidget = ItemWidget(item))
11     {
12         QPoint pos = oldWidget->mapFromParent(event->pos());
13         if (oldWidget->size().height() / 2 < pos.y())
14         {
15             insertPos += 1;
16         }
17     }
18 
19     if (dragItem)
20     {
21         if (ListItem * oldWidget = ItemWidget(dragItem))
22         {
23             QListWidgetItem * newItem = new QListWidgetItem;
24             ListItem * itemWidget = new ListItem;
25             itemWidget->SetData(oldWidget->GetData());
26 
27             insertItem(insertPos, newItem);
28             setItemWidget(newItem, itemWidget);
29 
30             setCurrentItem(newItem);
31 
32             oldWidget->deleteLater();
33         }
34 
35         dragItem = takeItem(row(dragItem));
36         if (dragItem)
37         {
38             delete dragItem;
39             dragItem = nullptr;
40         }
41     }
42 }

五、下載鏈接 

 ?? Qt之QAbstractItemView視圖項拖拽2?

六、相關文章

  自定義拖放數據:這篇文章是講述怎么自定義QMimeData數據的,我使用的是其中第二個方法。

  Qt之QAbstractItemView視圖項拖拽(一)

  Qt之QAbstractItemView選擇無焦點

轉載于:https://www.cnblogs.com/swarmbees/p/6055280.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/news/260169.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260169.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260169.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

電腦控制蘋果手機_必備神器,電腦控制手機

序一款電腦端的神器&#xff0c;它可以任意的操縱你的手機。****QtScrcpy可以通過USB(或通過TCP/IP)連接Android設備&#xff0c;并進行顯示和控制。不需要root權限。單個應用程序最多支持16個安卓設備同時連接。同時支持GNU/Linux&#xff0c;Windows和MacOS三大主流桌面平臺。…

php未定義要怎樣做,php-Behat-未定義的功能步驟

我設置了一個簡單的測試場景來學習behat,但是我遇到了一些問題.我正在關注THIS教程.這是我的專題節目&#xff1a;Feature: showThis is a behat feature to test the article pages.##TODOScenario: I want to view a detailed article pageGiven I am logged inAnd Im on &qu…

CentOS 命令大全 (轉)

1、查看系統使用端口并釋放端口 [rootmy_nn_01 WEB-INF]# lsof -w -n -i tcp:80 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME java 24065 root 34u IPv6 269149 TCP *:http (LISTEN) [rootmy_nn_01 WEB-INF]# kill -9 24065 2、以KB/MB形式顯示文件列表…

微信接口改良

之前公司微信開發的時候 寫了個微信的接口改良版,當然好多想改進的都沒改。。大概是太懶了 &#xff08;囧 /*** Created by DFH on 13-12-16.*//*--htmlvar shareData {//分享展示圖片地址 **必須"imgUrl": "a.jpg",//分享至朋友圈鏈接 **必須&q…

生活大爆炸版石頭剪刀布

題目描述 Description石頭剪刀布是常見的猜拳游戲&#xff1a;石頭勝剪刀&#xff0c;剪刀勝布&#xff0c;布勝石頭。如果兩個人出拳一樣&#xff0c;則不分勝負。在《生活大爆炸》第二季第8集中出現了一種石頭剪刀布的升級版游戲。升級版游戲在傳統的石頭剪刀布游戲的基礎上&…

oracle18c卸載方法,在debian 10上安裝和卸載oracle數據庫快捷版18c第4版

安裝oracle-xe-18c的步驟此安裝向導依賴軟件包alien。由于oracle并未提供oracle-xe-18c的deb包&#xff0c;故需要通過alien命令將oracle-xe-18c的rpm格式的安裝包導出新的deb格式的安裝包&#xff1a;sudo alien --scripts -d oracle-database-xe-18c-1.0-1.x86_64.rpm相應rpm…

解決:缺少aclocal、autoconf、automake

下載三個包&#xff1a;autoconf-2.68.tar.bz2、automake-1.11.1.tar.bz2、m4-1.4.14.tar.bz2 1、su - root 2、tar xjf XXXXX.tar.bz2 3、cd m4/ 4、./configure make make install 5、cd autoconf/ 6、./configure make make install 7、cd automake/ 8、./configure…

jquery事件 on(),live(),delegate(),blind()

jQuery推出on()的目的有2個&#xff0c;一是為了統一接口&#xff0c;二是為了提高性能&#xff0c; 所以從現在開始用on()替換bind(), live(), delegate吧。 尤其是不要再用live()了&#xff0c;因為它已經處于不推薦使用列表了[1.7已經被刪除]。 如果只綁定一次事件&#xff…

Swift 開發的工具類,主要是提供正則表達式及其它,Github會長期維護

直接訪問 GitHub 看代碼 YYGRegular 我是&#xff1a; 語歌復制代碼It is a regular expression used on iOS, which implement by Swift 這是一個基于swift快捷開發的擴展類&#xff0c;目前的涵蓋內容包括詳細打印&#xff0c;正則表達式&#xff0c;會經常維護 介于是增加更…

用python慶祝生日_生日到底該過陰歷還是陽歷好呢?不是迷信,都怪我們大意!...

過生日到底該過陰歷還是陽歷&#xff1f;答案說出來你可能都不信在我們國家&#xff0c;過生日有兩種不同的方式&#xff0c;因為有兩種不同的日子的計算方式&#xff0c;分為陰歷和陽歷。一般來說&#xff0c;在農村和一些比較落后的地方&#xff0c;人們習慣于用陰歷來計算生…

websphere jndi oracle,websphere7.0獲得JNDI連接報invalid username/password

Exception in thread "P497968:O0:CT" java.sql.SQLException: ORA-01017: invalid username/password; logon deniedDSRA0010E: SQL 狀態&#xff1a;72000&#xff0c;錯誤碼&#xff1a;1,017at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapp…

WSS3.0自帶數據庫可以使用SQL 2005 Server Management Studio來管理

默認情況下&#xff0c;安裝完WSS3.0后&#xff0c;會自動安裝一個自帶的SQL Server 2005 Embedded Edition數據庫&#xff0c;但是此數據庫卻沒有管理工具,不像安裝SQL 2005其它版本會有管理工具。如果你要管理數據庫&#xff0c;這時怎么辦呢。經過俺試了一上午了&#xff0c…

CPU的高速緩存存儲器知識整理

基于緩存的存儲器層次結構 基于緩存的存儲器層次結構行之有效&#xff0c;是因為較慢的存儲設備比較快的存儲設備更便宜&#xff0c;還因為程序往往展示局部性&#xff1a; 時間局部性&#xff1a;被引用過一次的存儲器的位置很可能在不遠的將來被再次引用。 空間局部性&#x…

uniapp光標自動定義到文本框_word技巧自動生成畢業論文目錄

一篇word文檔&#xff0c;內容有大的章&#xff0c;小的節。如何把章節抽出來生成目錄&#xff1f;WORD →點擊需要插入的地方 → 插入菜單 → 索引和目錄 → 目錄 → 確定。1 創建標題目錄Word 一般是利用標題或者大綱級別來創建目錄的。因此&#xff0c;在創建目錄之前&#…

JSTL

2019獨角獸企業重金招聘Python工程師標準>>> 說明 JSTL 是 JAVA 中的一個定制標記庫集。實現了JSP頁面中代碼的復用&#xff0c;增加了JSP頁面的可讀性&#xff0c;方便查看和參與開發 使用 1.下載地址 http://archive.apache.org/dist/jakarta/taglibs/standard/bi…

[jQuery] event.stopPropagation()報錯

使用jQuery給一個事件加處理方法時&#xff0c;為了阻止一個事件向上冒泡&#xff0c;使用了event.stopPropagation()&#xff0c;但在IE下卻報對象不支持此屬性或方法的錯誤&#xff08;IE下是event. cancelBubbletrue&#xff09;&#xff0c;jQuery不是兼容各瀏覽器嗎&#…

中科燕園arcgis外包----排水管網地理信息系統

項目背景 紹興縣是浙江省第一個“數字城管”試點城市&#xff0c;也是全國第一個“數字城管”縣級城市。隨著經濟的飛速發展、城市化步伐的加快&#xff0c;以及城市規模的擴大和現代化程度的不斷提高&#xff0c;作為城市重要基礎設施的城市地下管線也越來越龐大、密集&#x…

自然語言0_nltk中文使用和學習資料匯總

sklearn實戰-乳腺癌細胞數據挖掘&#xff08;博主親自錄制視頻教程&#xff09; https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare http://blog.csdn.net/huyoo/article/…

python實現深度優先搜索_python中的深度優先搜索算法

假設我有一個函數&#xff0c;它接受一個輸入($x iui$)&#xff0c;然后經過一個循環并生成一系列輸出($x{I&#xff0c;j}$)。然后&#xff0c;每個輸出可以再次作為同一函數的輸入&#xff0c;從而產生更多的輸出($x{i&#xff0c;j&#xff0c;k}$)。我試圖通過這個函數找到…

mysql函數移植到oracle,oracle到mysql的遷移,函數部分

to_date(?, YYYY-MM-DD HH24:MI:SS)"STR_TO_DATE(2003-15-10 00:00:00,%Y-%m-%d %H:%i:%s); //格式不對&#xff0c;會返回NULLto_char(create_time,yyyy-MM-dd)DATE_FORMAT(create_time,%Y-%m-%d)sysdatenow()或者CURRENT_TIMESTAMP //1997-12-15 23:50:26,建表的時…