前面的例子都是使用的系統提供的拖放物件 qmimedata 進行拖放資料的儲存,比如使用 qmimedata::settext() 建立文字,使用 qmimedata::urls() 建立 url 物件。但是,如果你希望使用一些自定義的物件作為拖放資料,比如自定義類等等,單純使用 qmimedata 可能就沒有那麼容易了。為了實現這種操作,我們可以從下面三種實現方式中選擇乙個:
將自定義資料作為 qbytearray 物件,使用 qmimedata::setdata() 函式作為二進位制資料儲存到 qmimedata 中,然後使用 qmimedata::data() 讀取;
繼承 qmimedata,重寫其中的 formats() 和 retrievedata() 函式操作自定義資料;
如果拖放操作僅僅發生在同乙個應用程式,可以直接繼承 qmimedata,然後使用任意合適的資料結構進行儲存。
第一種方法不需要繼承任何類,但是有一些侷限:即是拖放不會發生,我們也必須將自定義的資料物件轉換成 qbytearray 物件;如果你希望支援很多種拖放的資料,那麼每種型別的資料都必須使用乙個 qmimedata 類,這可能會導致類**;如果資料很大的話,這種方式可能會降低系統的可維護性。然而,後兩種實現方式就不會有這些問題,或者說是能夠減小這種問題,並且能夠讓我們有完全控制權。
我們先來看乙個應用,使用 qtablewidget 來進行拖放操作,拖放的型別包括 plain/text,plain/html 和 plain/csv。如果使用第一種實現方法,我們的**將會如下所示:
void mytablewidget::mousemoveevent(qmouseevent *event)對於這段**,我們應該已經很容易的理解:在 performdrag() 函式中,我們呼叫 qmimedata 的 settext() 和 sethtml() 函式儲存 plain/text 和 plain/html 資料,使用 setdata() 將 text/csv 型別的資料作為二進位制 qbytearray 型別儲存。qtablewidget::mousemoveevent(event);
} void mytablewidget::performdrag()
qstring mytablewidget::tocsv(const qstring &plaintext)tocsv() 和 tohtml() 函式將資料取出並轉換成我們需要的 csv 和 html型別的資料。例如,下面的資料qstring mytablewidget::tohtml(const qstring &plaintext)
red green blue轉換成 csv 格式為:cyan yellow magenta
"red", "green", "blue"轉換成 html 格式為:"cyan", "yellow", "magenta"
redgreenblue
cyanyellowmagenta
在放置的函式中我們像以前一樣使用:
void mytablewidget::dropevent(qdropevent *event)雖然我們接受三種資料型別,但是在這個函式中我們只接受兩種型別。至於 html 型別,我們希望如果使用者將 qtablewidget 的資料拖到乙個 html 編輯器,那麼它就會自動轉換成 html **,但是我們不計畫支援將外部的 html **拖放到 qtablewidget 上。為了讓這段**能夠工作,我們需要在建構函式中設定 setacceptdrops(true) 和 setselectionmode(contiguousselection)。else
if (event->mimedata()->hasformat("text/plain"))
}
好了,上面就是我們所說的第一種方式的實現。這裡並沒有給出完整的實現**,大家可以根據需要自己實現一下試試。下面我們將按照第二種方法重新實現這個需求。
class tablemimedata : public qmimedata為了避免儲存具體的資料,我們儲存 table 和選擇區域的座標的指標。qtablewidgetselectionrange range() const
qstringlist formats() const;
protected:
qvariant retrievedata(const qstring &format,
qvariant::type preferredtype) const;
private:
static qstring tohtml(const qstring &plaintext);
static qstring tocsv(const qstring &plaintext);
qstring text(int row, int column) const;
qstring rangeasplaintext() const;
const qtablewidget *mytablewidget;
qtablewidgetselectionrange myrange;
qstringlist myformats;
};
tablemimedata::tablemimedata(const qtablewidget *tablewidget,建構函式中,我們對私有變數進行初始化。formats() 函式返回的是被 mime 資料物件支援的資料型別列表。這個列表是沒有先後順序的,但是最佳實踐是將「最適合」的型別放在第一位。對於支援多種型別的應用程式而言,有時候會直接選用第乙個符合的型別儲存。const qtablewidgetselectionrange &range)
qstringlist tablemimedata::formats() const
qvariant tablemimedata::retrievedata(const qstring &format,qvariant::type preferredtype) const
else
if (format == "text/csv") else
if (format == "text/html") else
}
函式 retrievedata() 將給出的 mime 型別作為 qvariant 返回。引數 format 的值通常是 formats() 函式返回值之一,但是我們並不能假定一定是這個值之一,因為並不是所有的應用程式都會通過 formats() 函式檢查 mime 型別。一些返回函式,比如 text(), html(), urls(), imagedata(), colordata() 和 data() 實際上都是在 qmimedata 的 retrievedata() 函式中實現的。第二個引數 preferredtype 給出我們應該在 qvariant 中儲存哪種型別的資料。在這裡,我們簡單的將其忽略了,並且在 else 語句中,我們假定 qmimedata 會自動將其轉換成所需要的型別。
void mytablewidget::dropevent(qdropevent *event)在放置的函式中,我們需要按照我們自己定義的資料型別進行選擇。我們使用 qobject_cast 巨集進行型別轉換。如果成功,說明資料來自同一應用程式,因此我們直接設定 qtablewidget 相關 資料,如果轉換失敗,我們則使用一般的處理方式。else
if (event->mimedata()->hasformat("text/csv")) else
if (event->mimedata()->hasformat("text/plain"))
qtablewidget::mousemoveevent(event);
}
Qt學習之路之自定義訊息框
qt自己也有很多的訊息框,這時,如果這些訊息框都不能滿足開發的需求,qt還允許自定義訊息框。包括訊息框的圖示,按鈕和訊息框顯示的內容都可以根據需求設定。不廢話了,下面給出個簡單的例子 custmsg widget.h ifndef custmsgwidget h define custmsgwidg...
QT學習之自定義訊號
我們先建立乙個msignal工程專案,並在ui介面拖入乙個按鈕 然後轉到槽函式選擇clicked 如圖 在類中定義乙個訊號 signals void msignal 在類中定義乙個print的槽函式,並實現 void msignal print connect this,msignal msigna...
Qt自定義資料型別
qt框架下開發時,建立乙個自定義型別,需要確保建立的這個自定義型別符合qmetatype規定的所有要求,即它必須滿足以下幾個條件 下面的message類的定義滿足這些條件,可以定義成乙個新的資料型別 class message q declare metatype message 這個類還提供了乙個...