PyQt5編程(20):拖放技術

使用拖放技術可實現在不同控件或應用之間的數據交換。使用該技術的典型示例是在Windows資源管理器中移動文件。要將文件移動到另一個目錄,只需用鼠標左鍵單擊文件圖標差按住不放,將文件拖動到目標目錄圖標,然后釋放鼠標按鈕。如果要復制文件,而不是移動文件,則還要按住鍵。
1.拖動
(1) 在mousePressEvent( )中,記錄鼠標按下時的位置;
(2) 在mouseMoveEvent ()中,計算鼠標移動的距離,可用來防止無意的拖動。QApplication的下列靜態方法可用來控制延遲量:

setstartDragDistance (Distance) - 拖動開始的最小移動量;
startDragDistance() - 返回拖動開始的最小移動量;
setstartDragTime (Time) -拖動開始的按壓毫秒數;
startDragTime () - 返回拖動開始的按壓毫秒數;

(3) 鼠標移動超過最小移動值或按壓鼠標超過最小毫秒數,拖動操作開始。此時,創建一個QDrag對象,調用exce()方法進行相關操作。QDrag有以下方法:

exec( ) -  開始拖放操作,返回一個代表放置操作的枚舉值。有兩個格式:
exec(supportedActions = Qt.MoveAction)
exec(supportedActions, defaultDropAction)
詳細用法參見http://doc.qt.io/qt-5/qdrag.html#exec
setMimeData (QMimeData qmd) - 設置拖放中傳輸的數據, 參數為QMimeData類型。傳輸文本的例子:
data = QtCore.QMimeData ()
data.setText ("Drag text")
drag = QtGui.QDrag (self)
drag.setMimeData (data)
mimeData () - 返回拖放過程中傳輸數據的QMimeData 對象;
setPixmap(QPixmap qpix) - 設定拖放過程鼠標顯示的圖像。如:
drag.setPixmap (QtGui.QPixmap ("dd representer.png"))
pixmap() - 返回拖放過程中鼠標顯示圖像的QPixmap對象;
setHotSpot (QPoint pt) - 設置圖像的熱點位置。
drag.setHotSpot (QtCore.QPoint (20, 20))
hotSpot() - 返回熱點位置的QPoint對象;
setDragCursor (QPixmap pix, Qt.DropAction dact) - 設置拖放的鼠標形狀。第一個參數為鼠標形狀的QPixmap對象;第二參數為相關操作的枚舉值,只能是 CopyAction, MoveAction 或LinkAction。drag.setDragCursor (QtGui.QPixmap ("move_cursor.png"), QtCore.Qt.MoveAction)
dragCursor ( Qt.DropAction dact) - 返回dact操作的鼠標形狀的QPixmap對象;
source() - 返回源控件的引用;
target() - 返回目標控件的引用。如果拖放的目標對象為另一應用,返回值為None.
supportedActions () - 返回當前有效操作的組合值。
defaultAction () - 返回缺省的操作。

QDrag有兩個信號:

actionChanged (Qt.DropAction dact) - 當拖放的行為被該變時,發射該信號;
targetchanged (QWidget obj) - 當目標控件被改變時,將會發射該信號;

2.QMineData類
拖放過過程中的MIME類型的數據傳遞通過將QMineData對象作為參數調用QDrag的setMimeData()函數實現。
創建QMimeData方法:
data=QtCore.QMimeData()
QMimeData類支持以下方法(詳見http://doc.qt.io/qt-5/qmimedata.html):

setText(text) - 設置文本數據(MIME型文本/文本格式):
data.setText("拖動文本")
text( ) - 返回文本數據;
hasText( ) - 如果對象包含文本數據,則返回True,否則返回False。
setHtml(HTML-text) - 以HTML格式設置文本數據(MIME型文本 / html格式):
data.setHtml("拖動HTML文本</ b>")
html( ) - 返回HTML格式的文本數據;
hasHtml( ) - 如果對象包含HTML格式的文本數據,則返回True,否則為False.
setUrls( QList  url) - 設置地址列表,參數為QUrl類的列表;
data.setUrls ([QtCore.QUrl ("http://www.google.com/")])
urls () - 返回地址列表:
url = e.mimeData (). urls () [0] .toString ()
hasUrls () - 如果對象包Url地址,則返回True,否則為False.
setlmageData(QVarinat  img) - 設置圖像數據,可以是QImage或QPixmap實例:
data.setlmageData (QtGui.Qlmage("pixmap.png"))
data.setlmageData (QtGui.QPixmap("pixmap.png"))
imageData( ) - 返回圖像對象;
haslmage( ) - 如果對象包含圖像數據,則返回True,否則為False.
setData(QString mimetype, QCore.QByteData data) 設置任意類型的MIME類型數據;參數1為QString類型,指定MIME類型;參數2為QByteData類實例。該方法可以用MIME不同類型,多次調用:
data.setData("text/plain",QtCore.QByteArray (bytes ("Data", "utf-8")))
data(QString mimetype) -  返回mimetype類型的QByteData數據對象;
hasFormat(QString mimetype) -  如果對象包含mimetype類型數據,則返回True,否則為False.
formats ( ) - 返回包括的mimetype類型列表;
removeFormat (QString mimetype) - 刪除mimetype類型的數據;
clear ( ) - 刪除所有數據。

如果要實現特殊類型數據的拖放,需要創建一個QMimeData子類,并重載retrieveData( ) 和 formats ( )方法。詳細內容,請參考Qt文檔。
3. 放置操作
在處理拖放對象之前,必須告訴系統該組件可以處理這些事件。 為此,要在組件的構造函數中,調用繼承自QWidget類的setAcceptDrops方法,參數值為True:

self.setAcceptDrops(True)
拖放對象的過程執行如下:

在控件的dragEnterEvent()方法中,檢查拖動的MIME類型數據。如果該控件能處理此類型數據,則調用事件對象的acceptProposedAction( )方法。如果要變更操作,則將新事件傳遞給事件對象的setDropAction( )方法,然后調用accept( )方法,而不是調用acceptProposedAction( )方法。
如果要限制控件的特定區域才能放置操作,必須在dragMoveEvent( )方法中處理。即當拖放進入到特定的區域,調用accept( QRect rect)方法,參數rect為特定區域的QRect對象。
在控件的dropEvent()方法中,完成相關操作。

QWidget類的下列方法可以處理在拖放過程中發生的事件:

    dragEnterEvent (self,event) - 當拖動進入到控件區域時調用。通過event參數, 可取得QDragEnterEvent實例;
    dragLeaveEvent(self,event) - 當拖動離開控件區域時調用。通過event參數, 可取得QDragLeaveEvent實例;
    dragMoveEvent (self, event) -當拖動在控件區域移動時調用。通過event參數, 可取得QDragMoveEvent實例;
    dropEvent (self, event) - 當拖動在控件區域放開時調用。通過event參數, 可取得QDropEvent實例;

QDragLeaveEvent類繼承自QEvent類,不附帶任何其他信息。因為在該類中只要知道拖動的對象已經離開組件區域就夠了。
相關類的繼承順序為:
QEvent - QDropEvent - QDragMoveEvent - QDragEnterEvent
QDragEnterEvent類中沒有增加新方法。
QDropEvent類有下列方法:

mimeData( ) - 返回含有所傳輸數據和MIME類型信息的QMimeData類的實例;
pos( ) - 返回QPoint類的實例,為拖放對象放置的整數坐標;
posF( ) - 返回QPointF類的實例,為拖放對象放置的浮點坐標;
possibleAction( ) - 返回拖放可能的操作組合,如:
if e.possibleActions () & QtCore.Qt.MoveAction:
    print ("MoveAction")
if e.possibleActions () & QtCore.Qt.CopyAction:
    print ("CopyAction")
proposedAction( ) - 返回默認的放置操作;
acceptProposedAction( ) - 表示已準備好接受傳輸的數據和由proposalAction( )返回的默認操作。該方法(或者accept()方法)必須在dragEnterEvent()中調用,否則,dropEvent()不會被調用。
setDropAction (action) - 允許在放置時指定為action. 作了此設置后,必須調用accept( )方法, 而不是acceptProposedAction( )方法;
dropAction( ) - 返回放置時進行的操作。如果用setDropAction( )進行了更改,可能與proposedAction ()的返回值不一致。
keyboardModifiers( ) - 用于判斷按下了哪些修飾鍵 (, , , 等.) ,可參考“PyQt5編程(18):鍵盤事件”中的對應函數。
mouseButtons () - 用于判斷在拖放過程中按下的鼠標鍵;
source( ) - 如果拖放是從另一個應用程來的,返回為None;否則,返回對拖放源控件的引用。

QDragMoveEvent類的方法有:

accept (QRect rect) - 表明允許后續的移動操作。 rect用來指定可接受拖放操作的區域;
ignore (QRect rect) - 表明不允許后續的移動操作。 rect用來指定不接受拖放操作的區域;;
answerRect () - 返回可接受拖放操作區域的QRect對象。

PyQt中的有些控件,如單行文本控件,已有拖放功能。因此,在自己實現拖放功能之前,請仔細閱讀相關控件的文檔。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • 禪與 Objective-C 編程藝術 (Zen and the Art of the Objective-C C...
    GrayLand閱讀 1,643評論 1 10
  • 當你懷孕以后,到孕中期,肚皮上會出現一條妊娠中線,不同的孕媽咪深淺不一。其實,當你沒有懷孕時,它早已存在,而且不分...
    金灶沐_馬維閱讀 524評論 0 0
  • 迪卡爾曾經說過:閱讀好書,就像跟過去最優秀的人物對話。讀書的目的是要讓我們的人生減少各種不必要的困擾。 在此,我弱...
    迷你花書評閱讀 434評論 2 2
  • 在朋友的推薦下開通了簡書,開始了我手寫我心的嘗試。中斷了好幾年寫點什么的習慣,終于又被撿起來,簡書讓我想起了最...
    Yumi玉米粒閱讀 409評論 3 3