自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

QT核心編程之鼠標(biāo)拖放 (4)

移動開發(fā)
拖放機(jī)制包括拖動、放下、剪貼板、拖放操作、添加新的拖放類型、高級拖放以及和其它應(yīng)用程序之間的操作幾個方面。

QT核心編程之鼠標(biāo)拖放是本節(jié)介紹的內(nèi)容。QT核心編程我們要分幾個部分來介紹,想?yún)⒖几鄡?nèi)容,請看末尾的編輯推薦進(jìn)行詳細(xì)閱讀,先來看本篇內(nèi)容。

拖放提供了一種用戶在應(yīng)用程序之間或之內(nèi)傳遞信息的一種簡單可視機(jī)制。在術(shù)語中,這被稱為"直接操作模型"。拖放在功能上類似剪貼板的剪切和粘貼機(jī)制。拖放機(jī)制包括拖動、放下、剪貼板、拖放操作、添加新的拖放類型、高級拖放以及和其它應(yīng)用程序之間的操作幾個方面。下面從這幾個方面分別進(jìn)行說明:

(1)拖動

開始一個拖動,比如是在鼠標(biāo)移動事件,創(chuàng)建一個適合你的媒體的QDragObject的子類的對象,例如:對于文本使用QTextDrag,對于圖片使用QImageDrag。然后調(diào)用drag()方法。例如,從一個窗口部件中開始拖動一些文本:

  1. void MyWidget::startDrag()  {  
  2.    QDragObject *d = new QTextDrag( myHighlightedText(), this );  
  3.     d->dragCopy(); //拷貝選中文本    // 不要刪除d    

注意在拖動之后,QDragObject沒有被刪除。在拖放明顯完成后,這個QDragObject需要被保存。因?yàn)樗€可能需要與其它進(jìn)程通信。最后 Qt會刪除這個對象。如果擁有拖動對象的窗口部件在刪除拖動對象之前被刪除,那么任何沒有完成的放下操作將會被取消,并且拖動對象會被刪除。因?yàn)檫@個原因,你應(yīng)該小心對待對象引用。

(2)放下

為了能在一個窗口部件中接收被放下的媒體,這個窗口部件調(diào)用setAcceptDrops(TRUE)(如:在它的構(gòu)造函數(shù)中),并且重載事件處理方法dragEnterEvent()和dropEvent()。對于更復(fù)雜的應(yīng)用程序,重載dragMoveEvent()和 dragLeaveEvent()也是必需的。

例如,當(dāng)拖動后放下文本或圖片時,窗口部件接受并處理放下操作的代碼如下:

  1. MyWidget::MyWidget(...) :    QWidget(...)  {  
  2.      ...     setAcceptDrops(TRUE); //接收被放下的媒體  
  3.   }//當(dāng)一個拖動正在進(jìn)行并且鼠標(biāo)進(jìn)入這個窗口部件,這個事件處理函數(shù)被調(diào)用    
  4. void MyWidget::dragEnterEvent(QDragEnterEvent* event)  {   
  5.     event->accept( QTextDrag::canDecode(event) ||         QImageDrag::canDecode(event)  );  
  6.   }//當(dāng)拖動在這個窗口部件上被放下,這個事件處理器被調(diào)用  
  7.   void MyWidget::dropEvent(QDropEvent* event)  {   
  8.     QImage image;  
  9.      QString text;   
  10.      if ( QImageDrag::decode(event, image) ) {//解碼圖片  
  11.         insertImageAt(image, event->pos()); //在窗口部件中插入圖片  
  12.      } else if ( QTextDrag::decode(event, text) ) {   
  13.        insertTextAt(text, event->pos());  
  14.       }  
  15.   } 

(3)剪貼板

QDragObject、QDragEnterEvent、QDragMoveEvent和QDropEvent類都是 QMimeSource(提供類型信息的類)的子類。如果你在QDragObject中基于你的數(shù)據(jù)進(jìn)行傳遞,你不僅可使用拖放,而且還可以使用傳統(tǒng)的剪切和粘貼。QClipboard有兩個函數(shù):

  1. setData(QMimeSource*)  
  2.       QMimeSource* data()const 

使用這些函數(shù),你可以把你的拖放初始信息放到剪貼板中:

  1. void MyWidget::copy(){  
  2.     QApplication::clipboard()->setData( new QTextDrag(myHighlightedText()) );  
  3. }  
  4.  void MyWidget::paste(){  
  5.     QString text;   
  6.    if ( QTextDrag::decode(QApplication::clipboard()->data(), text) )  
  7.         insertText( text );  

你甚至能使用QDragObject的子類作為文件I/O部分。例如,如果你的程序有一個QDragObject的子類把CAD設(shè)計編碼成DXF格式,你可以象下面這樣存儲和裝載這個格式的文件:

  1. void MyWidget::save(){  
  2.     QFile out(current_file_name);  
  3.     out.open(IO_WriteOnly);  
  4.     MyCadDrag tmp(current_design); // MyCadDrag是QDragObject的子類  
  5.     out.writeBlock( tmp->encodedData( "image/x-dxf" ) );  
  6. } void MyWidget::load(){   
  7.    QFile in(current_file_name);   
  8.    in.open(IO_ReadOnly);   
  9.    if ( !MyCadDrag::decode(in.readAll(), current_design) ) {  
  10.        QMessageBox::warning( this, "Format error", tr("The file \"%1\" is not in any supported format") .arg(current_file_name) );  
  11.     }  

(4)拖放操作

在一些簡單的情況下,拖放的目標(biāo)接收一個被拖動的數(shù)據(jù)的拷貝,并且由源來決定是否刪除初始的拖動對象。這是QDropEvent中的"Copy"操作。目標(biāo)也可以選擇理解其它操作,特別是"Move"和"Link"操作。如果目標(biāo)理解了"Move"操作,目標(biāo)負(fù)責(zé)拷貝和刪除操作,源不會嘗試刪除數(shù)據(jù)。如果目標(biāo)理解為"Link"操作,它存儲它自己的引用到初始信息中,并且源不會刪除初始信息。最通用的拖放操作是在同一個窗口部件中執(zhí)行一個"Move"操作。

拖動操作的另一個主要用途是當(dāng)使用一個引用類型,比如text/uri-list,實(shí)際上被拖動的數(shù)據(jù)是文件或?qū)ο蟮囊谩?/p>

(5)添加新的拖放類型

拖放不僅僅局限于文本和圖片,任何信息都可以被拖放。為了在應(yīng)用程序之間拖放信息,兩個應(yīng)用程序必須指明彼此都能接受和產(chǎn)生的數(shù)據(jù)格式。這個可以通過使用MIME類型來獲得。拖動的源提供一個它能產(chǎn)生的MIME類型列表(按從最合適的到最少合適的順序排列),并且放下的目標(biāo)選擇一種它能接受的類型。例如,QTextDrag提供了"text/plain"MIME類型(普通的沒有格式的文本),還有"text/utf16"和"text /utf8"的Unicode格式的類型。QImageDrag提供了"image/*"類型,*是QImageIO支持的任何一種圖片格式,并且 QUriDrag子類提供了"text/uri-list"的支持,它是傳輸一個文件名列表(或URL)的標(biāo)準(zhǔn)格式。

為了實(shí)現(xiàn)一些還沒有可用QDragObject子類的信息類型的拖放,首先和最重要的步驟是查找合適的存在格式:IANA(Internet Assigned Numbers Authority)在ISI(Information Sciences Institute)提供了一個MIME媒體類型的分級列表。使用標(biāo)準(zhǔn)的MIME類型將會使你的應(yīng)用程序現(xiàn)在及未來能更好地與其它軟件互相操作。

為了支持另外的媒體類型,從QDragObject或QStoredDrag派生類。當(dāng)你需要提供多種媒體類型的支持時,從QDragObject派生類。當(dāng)一個類型足夠時,就從更簡單的QStoredDrag派生類。

QDragObject的子類將會重載const char* format(int i) const和QByteArray encodedData(const char* mimetype) const成員,并且提供一套方法編碼媒體數(shù)據(jù),提供靜態(tài)成員canDecode()和decode()解碼輸入的數(shù)據(jù),QImageDrag的成員函數(shù) bool canDecode(QMimeSource*) const和QByteArray decode(QMimeSource*) const在子類中需要類似的重載。

QStoredDrag的子類提供了提供一套方法編碼媒體數(shù)據(jù),靜態(tài)成員canDecode()和decode()對進(jìn)入的數(shù)據(jù)進(jìn)行解碼。

(6)高級拖放

在剪貼板模式中,用戶可以剪切或復(fù)制資源信息,然后粘貼它。相似地,在拖放模式中,用戶可以拖動信息的拷貝或者拖動信息本身到一個新的位置(移動它)。拖放模式對于程序員來說都是更多的復(fù)雜性:程序直到放下(粘貼)完成才會知道用戶是想剪切還是復(fù)制。在應(yīng)用程序之間拖動,這個沒有什么區(qū)別,但是在一個應(yīng)用程序之內(nèi)進(jìn)行拖動,應(yīng)用程序必須小心不要將拷貝粘貼到同一個地方。例如,在同上窗口部件中拖動文本,拖動的開始點(diǎn)和放下事件處理函數(shù)應(yīng)象下面這樣重載:

  1. void MyEditor::startDrag(){  
  2.     QDragObject *d = new QTextDrag(myHighlightedText(), this);  
  3.     if ( d->drag() && d->target() != this )  cutMyHighlightedText(); //剪切選中的文本  
  4. }  
  5.  void MyEditor::dropEvent(QDropEvent* event){  
  6.     QString text;   
  7.     if ( QTextDrag::decode(event, text) ) {   
  8.       if ( event->source() == this && event->action() == QDropEvent::Move ) {          // 在同一個窗口部件時,不能使用粘貼拷貝,而應(yīng)是移到到這個位置  
  9.           event->acceptAction();  
  10.           moveMyHighlightedTextTo(event->pos());  
  11.        }  
  12.  else {  
  13.           pasteTextAt(text, event->pos()); //粘貼拷貝  
  14.        }  
  15.     }  

一些窗口部件在數(shù)據(jù)被拖動到它們上面時需要指定"是"或"否"接收。例如,一個CAD程序也許只接收在視圖中的文本對象上放下的文本。在這種情況下,dragMoveEvent()被使用并且給定接受或者忽略拖動的區(qū)域。代碼列出如下:

  1. void MyWidget::dragMoveEvent(QDragMoveEvent* event){   
  2.    if ( QTextDrag::canDecode(event) ) {   
  3.      MyCadItem* item = findMyItemAt(event->pos());  
  4.        if ( item )  
  5.         event->accept();  
  6.     }  

(7)和其它應(yīng)用程序之間的操作

在X11上,拖動使用公有的XDND協(xié)議,而Qt在Windows上使用OLE標(biāo)準(zhǔn),Qt在Mac上使用Carbon拖動管理器。在X11 上,XDND使用MIME,所以不需要轉(zhuǎn)換。Qt的應(yīng)用編程接口與平臺無關(guān)。在Windows上,識別MIME的應(yīng)用程序可以通過使用MIME類型的剪貼板格式名字進(jìn)行通信。一些Windows應(yīng)用程序已經(jīng)對它們的剪貼板格式使用MIME命名規(guī)范了。在內(nèi)部,Qt有能力在專有的剪貼板格式和MIME類型之間轉(zhuǎn)換。在X11上,Qt也支持使用Motif拖放協(xié)議的拖動。

小結(jié):QT核心編程之鼠標(biāo)拖放的內(nèi)容介紹完了,希望本文對你有所幫助,如果需要更多的內(nèi)容,請參考編輯推薦。

【編輯推薦】

QT核心編程之Qt模板庫(1)

QT核心編程之集合類 (2)

QT核心編程之Qt線程 (3)

QT核心編程之鍵盤焦點(diǎn) (5)

QT核心編程之會話管理 (6)

QT核心編程之調(diào)試技術(shù) (7)

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-06-22 10:12:08

Qt 線程

2011-06-22 09:40:32

QT 模板庫 模板

2011-06-22 10:39:56

QT 會話管理

2011-06-22 10:27:32

QT 鍵盤 焦點(diǎn)

2011-06-22 09:58:04

QT 集合類

2011-06-22 10:45:21

QT 調(diào)試

2012-01-17 13:46:55

JavaSwing

2011-06-17 14:54:31

Qt

2010-06-11 09:01:02

.NET 4并行編程

2010-06-24 09:12:27

.NET 4并行編程

2011-09-07 17:04:40

QT平臺模擬鼠標(biāo)

2012-10-29 13:25:54

JavaScriptJSjQuery

2011-08-29 11:25:29

QTWebKit鼠標(biāo)

2015-04-24 09:48:59

TCPsocketsocket編程

2011-06-13 11:07:22

QT 移植

2011-07-21 10:17:53

java

2017-02-07 18:34:16

Linux編程PING

2022-02-14 15:07:48

進(jìn)程FileChanne線程

2014-12-16 09:10:52

IPv4IPv6TCP

2011-06-24 15:30:22

QT 皮膚 QSS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號