若該文為原創文章,轉載請注明原文出處
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/116292217
紅胖子(紅模仿)的博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬結合等等)持續更新中…(點擊傳送門)
Qt開發專欄:開發技術(點擊傳送門)
上一篇:沒有了
下一篇:敬請期待…
前話
??Qt中的拽拖操作詳細介紹,
Demo
圖片拽拖
??
控制元件拽拖
??
視窗拽拖
??
拽托框架(高級開發)
??
??
拖放(Drag and Drop)
??拖放提供了一種簡單的可視機制,用戶可以使用它在應用程式之間和內部傳輸資訊,拖放的功能類似于剪貼板的剪切和粘貼機制,
??本檔案描述了基本的拖放機制,并概述了在自定義控制元件中啟用該機制的方法,許多qt的控制元件也支持拖放操作,例如專案視圖和圖形視圖框架,以及為qt小部件和qt quick編輯控制元件,有關專案視圖和圖形視圖的詳細資訊,請參見使用專案視圖和圖形視圖框架的拖放,
拖放類
??這些類處理拖放和必要的mime型別編碼和解碼,
??
配置
??QStyleHints物件提供了一些與拖放操作相關的屬性:
- QStyleHints::startDragTime():描述在開始拖動之前,用戶必須在物件上按住滑鼠按鈕的時間量(毫秒),
- QStyleHints::StartDragDistance():表示在移動被解釋為拖動之前,按住滑鼠按鈕時用戶必須移動滑鼠的距離,
- QStyleHints::StartDragVelocity():表示用戶移動滑鼠開始拖動的速度(以像素/秒為單位),值為0表示沒有這樣的限制,
??如果在控制元件中提供拖放支持,這些數量將提供與基礎視窗系統兼容的合理默認值,供您使用,
在Qt Quick種的拖放
??檔案的其余部分主要關注如何在C++中實作拖放,要在Qt快速場景中使用拖放,請閱讀Qt Quick拖放、DragEvent和DropArea項的檔案,以及Qt快速拖放示例,
拖曳(Dragging)
??要開始拖動,請創建一個QDrag物件,并呼叫其exec()函式,在大多數應用程式中,只有在按下滑鼠按鈕并移動游標一定距離后,才能開始拖放操作,但是,啟用小部件拖動最簡單方法是重新實作小部件的mousePressEvent(),并啟動拖放操作:
??
??盡管用戶可能需要一些時間來完成拖動操作,但就應用程式而言,exec()函式是一個帶有多個值之一的阻塞函式,這些說明操作是如何結束的,下面將詳細介紹,
??注意,exec()函式不會阻塞主事件回圈,
??對于需要區分滑鼠單擊和拖動的小部件,重新實作小部件的mousePressEvent()函式以記錄拖動的開始位置是很有用的:
??
??稍后,在mouseMoveEvent()中,我們可以確定是否應該開始拖動,并構造一個拖動物件來處理該操作:
??
??這種特殊的方法使用QPoint::manhattanlength()函式粗略估計滑鼠單擊位置和當前游標位置之間的距離,此函式以精度換取速度,通常適用于此目的,
放下(Dropping)
??要能夠接收小部件上丟棄的媒體,請為小部件呼叫setAcceptDrops(true),并重新實作dragEnterEvent()和dropEvent()事件處理程式函式,
例如,以下代碼啟用了QWidget子類的建構式中的Drop事件,從而可以有效地實作Drop事件處理程式:
??dragEnterEvent()通常用于通知qt小部件接受的資料型別,如果要在DragMoveEvent()和dropEvent()的重新實作中接收QDragMoveEvent或QDropEvent,則必須重新實作此函式,
報錯
??下面的代碼顯示如何重新實作DragEnterEvent(),以告訴拖放系統我們只能處理純文本:
?? 
??dropEvent()用于解包丟棄的資料,并以適合您的應用程式的方式對其進行處理,
??在以下代碼中,事件中提供的文本將傳遞給QTextBrowser,QComboBox將填充用于描述資料的mime型別串列:
??
??在這種情況下,我們接受建議的操作,而不檢查它是什么,在實際應用程式中,可能需要從dropEvent()函式回傳,而不接受建議的操作,或者在操作不相關的情況下處理資料,例如,如果我們不支持到應用程式中外部源的鏈接,我們可以選擇忽略Qt::LinkAction操作,
覆寫提議的行動
??也可以忽略提議的操作,并對資料執行其他操作,為此,我們將在呼叫accept()之前使用Qt::dropAction中的首選操作呼叫事件物件的setDropAction(),這樣可以確保使用替換洗掉操作而不是建議的操作,
對于更復雜的應用程式,重新實作dragMoveEvent()和dragLeaveEvent()將使小部件的某些部分對放置事件敏感,并使您能夠更好地控制應用程式中的拖放,
復雜小部件的子類化
??某些標準Qt小部件為拖放提供了自己的支持,在對這些小部件進行子類化時,除了DragCenterEvent()和DropEvent()之外,可能還需要重新實作DragMoveEvent(),以防止基類提供默認的拖放處理,并處理您感興趣的任何特殊情況,
拖放操作
??在最簡單的情況下,拖放操作的目標將接收正在拖動的資料的副本,源將決定是否洗掉原始資料,這由CopyAction操作描述,目標還可以選擇處理其他操作,特別是MoveAction和LinkAction操作,如果源呼叫QDrag::exec(),并回傳MoveAction,則如果源選擇洗掉任何原始資料,則該源將負責洗掉,不應洗掉源小部件創建的QMimeData和QDrag物件-它們將被Qt銷毀, 目標負責獲取在拖放操作中發送的資料的所有權;這通常通過保留對資料的參考來實作,
??如果目標理解LinkAction操作,它應該存盤自己對原始資訊的參考;源不需要對資料執行任何進一步的處理,拖放操作的最常見用法是在同一個小部件中執行移動;有關此功能的詳細資訊,請參閱有關拖放操作的部分,
??拖動操作的另一個主要用途是在使用參考型別(如text/uri-list)時,其中拖動的資料實際上是對檔案或物件的參考,
添加新的拖放型別
??拖放不限于文本和影像,任何型別的資訊都可以在拖放操作中傳輸,要在應用程式之間拖動資訊, 應用程式必須能夠相互指示可以接受哪些資料格式以及可以生成哪些資料格式,這是通過使用mime型別實作的, 由源構造的QDrag物件包含一個用于表示資料的mime型別串列(從最合適的到最不合適的順序排列),drop目標使用其中一個來訪問資料,對于常見的資料型別,便利函式處理透明使用的mime型別,但是對于自定義資料型別,必須顯式地宣告它們,
??要對QDrag便利功能未涵蓋的資訊型別執行拖放操作,第一步也是最重要的一步是查找適當的現有格式:Internet分配號碼管理局(IANA)在資訊科學研究所(ISI)提供了MIME媒體型別的分層串列,使用標準的mime型別可以最大限度地提高應用程式與其他軟體現在和將來的互操作性,
要支持其他媒體型別,只需使用setData()函式設定QMimeData物件中的資料,提供完整的mime型別和以適當格式包含資料的QByteArray,以下代碼從標簽中獲取QPixmap,并將其存盤為QMimeData物件中的可移植網路圖形(PNG)檔案:
??
??對于這種情況,我們可以簡單地使用setImageData()來提供各種格式的影像資料:
??
??在這種情況下,QByteArray方法仍然很有用,因為它可以更好地控制QMimeData物件中存盤的資料量,
請注意,在項視圖中使用的自定義資料型別必須宣告為元物件,并且必須實作它們的流運算子,
放下動作
??在剪貼板模型中,用戶可以剪切或復制源資訊,然后粘貼它,同樣,在拖放模型中,用戶可以拖動資訊的副本,也可以將資訊本身拖動到新位置(移動資訊),拖放模型對于程式員來說還有一個額外的復雜之處:在操作完成之前,程式不知道用戶是否想要剪切或復制資訊,在應用程式之間拖動資訊時,這通常沒有什么區別,但在應用程式中,檢查使用了哪個放置操作是很重要的,
??可以為一個小部件重新實作mouseMoveEvent(),并通過可能的拖放操作組合啟動拖放操作,例如,可能希望確保拖動始終移動小部件中的物件:
??
??如果資訊被放到另一個應用程式中,exec()函式回傳的操作可能默認為copyAction,但是如果資訊被放到同一個應用程式中的另一個小部件中,我們可能會獲得不同的drop操作,
可以在小部件的dragMoveEvent()函式中篩選建議的放置操作,但是,可以接受DragEnterEvent()中所有建議的操作,并讓用戶稍后決定要接受哪個操作:
??
??當小部件中發生放置時,將呼叫DropEvent()處理程式函式,我們可以依次處理每個可能的操作,首先,我們在同一個小部件中處理拖放操作:
??
??在這種情況下,拒絕處理移動操作,接受的每種型別的跌落動作都會進行相應的檢查和處理:
??
??注意,在上面的代碼中檢查了單獨的放置操作,如上所述,在覆寫建議的操作部分,有時需要覆寫建議的洗掉操作,并從可能的洗掉操作中選擇不同的操作,為此,需要檢查事件的possibleActions()提供的值中是否存在每個操作,使用setDropAction()設定Drop操作,并呼叫accept(),
矩形下落
??小部件的dragMoveEvent()可用于通過僅在游標位于這些區域內時接受建議的放置操作來限制小部件的某些部分的放置,例如,當游標位于子小部件(DropFrame)上時,以下代碼接受任何建議的放置操作:
??
??如果您需要在拖放操作期間提供視覺反饋、滾動視窗或任何適當的操作,也可以使用DragMoveEvent(),
剪切板
??應用程式還可以通過將資料放在剪貼板上進行通信,要訪問這個,您需要從QApplication物件獲取一個QClipboard物件,
??QMimedata類用于表示在剪貼板中傳輸的資料,要將資料放在剪貼板上,可以使用setText()、setImage()和setPixmap()方便函式來處理常見的資料型別,這些函式與在QMimedata類中找到的函式類似,只是它們還帶有一個控制資料存盤位置的附加引數:如果指定了剪貼板,則資料將放置在剪貼板上;如果指定了選擇,則資料將放置在滑鼠選擇中(僅在x11上),默認情況下,資料放在剪貼板上,
例如,我們可以使用以下代碼將QLineEdit的內容復制到剪貼板:
??具有不同mime型別的資料也可以放在剪貼板上,構造一個qmimedata物件,并使用setData()函式按照前面部分描述的方式設定資料;然后可以使用setmimedata()函式將該物件放到剪貼板上,
QClipboard類可以通過其dataChanged()信號通知應用程式它所包含的資料的更改,例如,我們可以通過將此信號連接到小部件中的插槽來監視剪貼板:
??
??連接到此信號的插槽可以使用可用于表示該信號的MIME型別之一讀取剪貼板上的資料:
??
??selectionChanged()信號可用于x11以監視滑鼠選擇,
與其他應用程式互操作
??在x11上,使用公共XDND協議,而在Windows Qt上使用OLE標準,而Qt for MacOS使用Cocoa拖動管理器,在x11, XDND使用MIME,因此不需要翻譯,無論平臺如何,QT API都是相同的,在Windows上,支持MIME的應用程式可以使用MIME型別的剪貼板格式名稱進行通信,一些Windows應用程式已經為其剪貼板格式使用了MIME命名約定,
??用于轉換專用剪貼板格式的自定義類可以通過在Windows上重新實作QwinMime或在MacOS上重新實作QMacPasteboardMime來注冊,
上一篇:沒有了
下一篇:敬請期待…
若該文為原創文章,轉載請注明原文出處
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/116292217
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/282145.html
標籤:其他
上一篇:Linux_多執行緒與鎖
