在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ C/ QByteArray 和 QVariant
Qt 容器和算法拾遺
自定義 model 之一
反走樣
Hello, world!
Qt 容器類(lèi)之關(guān)聯(lián)存儲(chǔ)容器
QStringListModel
拖放技術(shù)之一
狀態(tài)欄
QTreeWidget
拖放技術(shù)之二
通用算法
event()
Qt 學(xué)習(xí)之路(18): Qt 標(biāo)準(zhǔn)對(duì)話框之 QInputDialog
Qt 容器類(lèi)之遍歷器和隱式數(shù)據(jù)共享
QListWidget
Meta-Object 系統(tǒng)
事件接收與忽略
Qt 學(xué)習(xí)之路(tip): parent 參數(shù)
Qt 標(biāo)準(zhǔn)對(duì)話框之 QColorDialog
QPainter(續(xù))
國(guó)際化(下)
漸變填充
自定義委托
創(chuàng)建 shared library
model-view 架構(gòu)
Graphics View Framework
自定義拖放數(shù)據(jù)對(duì)象
QSortFilterProxyModel
國(guó)際化(上)
組件布局
自定義 Model 之三
事件過(guò)濾器
QDirModel
Hello, world!(續(xù))
Qt 標(biāo)準(zhǔn)對(duì)話框之 QFileDialog
自定義 model 之二
深入了解信號(hào)槽
坐標(biāo)變換
剪貼板操作
QTableWidget
QByteArray 和 QVariant
創(chuàng)建一個(gè)對(duì)話框(下)
Qt 學(xué)習(xí)之路(32): 一個(gè)簡(jiǎn)易畫(huà)板的實(shí)現(xiàn)(Graphics View)
文本文件讀寫(xiě)
自定義事件
編寫(xiě)跨平臺(tái)的程序
MainWindow
初探信號(hào)槽
Qt 學(xué)習(xí)之路(17): Qt 標(biāo)準(zhǔn)對(duì)話框之 QMessageBox
繪圖設(shè)備
菜單和工具條(續(xù))
二進(jìn)制文件讀寫(xiě)
QString
事件(event)
菜單和工具條
QPainter
Qt 容器類(lèi)之順序存儲(chǔ)容器
進(jìn)程間交互
API 文檔的使用
創(chuàng)建一個(gè)對(duì)話框(上)
一個(gè)簡(jiǎn)易畫(huà)板的實(shí)現(xiàn)(QWidget)

QByteArray 和 QVariant

前面我們?cè)诮榻B QString 的最后部分曾經(jīng)提到了 QByteArray 這個(gè)類(lèi)?,F(xiàn)在我們就首先對(duì)這個(gè)類(lèi)進(jìn)行介紹。

QByteArray 具有類(lèi)似與 QString 的 API。它也有相應(yīng)的函數(shù),比如 left(), right(), mid()等。這些函數(shù)不僅名字和 QString 一樣,而且也具有幾乎相同的功能。QByteArray 可以存儲(chǔ)原生的二進(jìn)制數(shù)據(jù)和8位編碼的文本數(shù)據(jù)。這句話怎么理解呢?我們知道,計(jì)算機(jī)內(nèi)部所有的數(shù)據(jù)都是以0和1的形式存儲(chǔ)的。這種形式就是二進(jìn)制。比如一串0、1代碼:1000,計(jì)算機(jī)并不知道它代表的是什么,這需要由上下文決定:它可以是整數(shù)8,也可以是一個(gè) ARGB 的顏色(準(zhǔn)確的說(shuō),整數(shù)8的編碼并不是這么簡(jiǎn)單,但我們姑且這個(gè)理解吧)。對(duì)于文件,即便是一個(gè)文本文件,讀出時(shí)也可以按照二進(jìn)制的形式讀出,這就是二進(jìn)制格式。如果把這些二進(jìn)制的0、1串按照編碼解釋成一個(gè)個(gè)字符,就是文本形式了。因此,QByteArray 實(shí)際上是原生的二進(jìn)制,但是也可以當(dāng)作是文本,因此擁有文本的一些操作。但是,我們還是建議使用 QString 表示文本,重要的原因是,QString 支持 Unicode。

為了方便期間,QByteArray 自動(dòng)的保證“最后一個(gè)字節(jié)之后的那個(gè)位”是'\0'。這就使得 QByteArray可以很容易的轉(zhuǎn)換成 const char *,也就是上一章節(jié)中我們提到的那兩個(gè)函數(shù)。同樣,作為原生二進(jìn)制存儲(chǔ),QByteArray 中間也可以存儲(chǔ)'\0',而不必須是'\0'在最后一位。

在有些情況下,我們希望把數(shù)據(jù)存儲(chǔ)在一個(gè)變量中。例如,我有一個(gè)數(shù)組,既希望存整數(shù),又希望存浮點(diǎn)數(shù),還希望存 string。對(duì)于 Java 來(lái)說(shuō),很簡(jiǎn)單,只要把這個(gè)數(shù)組聲明成 Object[]類(lèi)型的。這是什么意思呢?實(shí)際上,這里用到的是繼承。在 Java 中,int 和 float 雖然是原生數(shù)據(jù)類(lèi)型,但是它們都有分別對(duì)應(yīng)一個(gè)包裝類(lèi) Integer 和 Float。所有這些 Integer、Float 和 String 都是繼承于Object,也就是說(shuō),Integer、Float 和 String 都是一個(gè)(也就是 is-a 的關(guān)系)Object,這樣,Object 的數(shù)組就可以存儲(chǔ)不同的類(lèi)型。但是,C++中沒(méi)有這樣一個(gè) Object 類(lèi),原因在于,Java 是單根的,而 C++不是。在 Java 中,所有類(lèi)都可以上溯到 Object 類(lèi),但是 C++中沒(méi)有這么一個(gè)根。那么,怎么實(shí)現(xiàn)這么的操作呢?一種辦法是,我們都存成 string 類(lèi),比如 int i=10,我就存"10"字符串。簡(jiǎn)單的數(shù)據(jù)類(lèi)型固然可以,可復(fù)雜一些的呢?比如一個(gè)顏色?難道要把 ARGB 所有的值都轉(zhuǎn)化成string?這種做法很復(fù)雜,而且失去了 C++的類(lèi)型檢查等好處。于是我們想另外的辦法:創(chuàng)建一個(gè)Object 類(lèi),這是一個(gè)“很大很大的”類(lèi),里面存儲(chǔ)了幾乎所有的數(shù)據(jù)類(lèi)型,比如下面的代碼:


class Object  
{  
public:  
    int intValue;  
    float floatValue;  
    string stringValue;  
}; 

這個(gè)類(lèi)怎么樣?它就足以存儲(chǔ) int、float 和 string 了。嗯,這就是我們的思路,也是 Qt 的思路。在 Qt 中,這樣的類(lèi)就是 QVariant。

QVariant 可以保存很多 Qt 的數(shù)據(jù)類(lèi)型,包括 QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、QPalette、QPen、QPixmap、QPoint、QRect、QRegion、QSize 和 QString,并且還有 C++基本類(lèi)型,如 int、float 等。QVariant 還能保存很多集合類(lèi)型,如 QMap<QString, QVariant>, QStringList 和 QList。item view classes,數(shù)據(jù)庫(kù)模塊和 QSettings 都大量使用了 QVariant 類(lèi),,以方便我們讀寫(xiě)數(shù)據(jù)。 QVariant 也可以進(jìn)行嵌套存儲(chǔ),例如


QMap<QString, QVariant> pearMap;  
pearMap["Standard"] = 1.95;  
pearMap["Organic"] = 2.25;  

QMap<QString, QVariant> fruitMap;  
fruitMap["Orange"] = 2.10;  
fruitMap["Pineapple"] = 3.85;  
fruitMap["Pear"] = pearMap;

QVariant 被用于構(gòu)建 Qt Meta-Object,因此是 QtCore 的一部分。當(dāng)然,我們也可以在 GUI 模塊中使用,例如


QIcon icon("open.png");  
QVariant variant = icon;  
// other function  
QIcon icon = variant.value<QIcon>(); 

我們使用了 value()模版函數(shù),獲取存儲(chǔ)在 QVariant 中的數(shù)據(jù)。這種函數(shù)在非 GUI 數(shù)據(jù)中同樣適用,但是,在非 GUI 模塊中,我們通常使用 toInt()這樣的一系列 to...()函數(shù),如 toString()等。

如果你覺(jué)得 QVariant 提供的存儲(chǔ)數(shù)據(jù)類(lèi)型太少,也可以自定義 QVariant 的存儲(chǔ)類(lèi)型。被 QVariant 存儲(chǔ)的數(shù)據(jù)類(lèi)型需要有一個(gè)默認(rèn)的構(gòu)造函數(shù)和一個(gè)拷貝構(gòu)造函數(shù)。為了實(shí)現(xiàn)這個(gè)功能,首先必須使用 Q_DECLARE_METATYPE()宏。通常會(huì)將這個(gè)宏放在類(lèi)的聲明所在頭文件的下面:


Q_DECLARE_METATYPE(BusinessCard) 

然后我們就可以使用:


BusinessCard businessCard;  
QVariant variant = QVariant::fromValue(businessCard);  
// ...  
if (variant.canConvert<BusinessCard>()) {  
    BusinessCard card = variant.value<BusinessCard>();  
    // ...  
}

由于 VC 6的編譯器限制,這些模板函數(shù)不能使用,如果你使用這個(gè)編譯器,需要使用qVariantFromValue(), qVariantValue()和 qVariantCanConvert()這三個(gè)宏。 如果自定義數(shù)據(jù)類(lèi)型重寫(xiě)了<<和>>運(yùn)算符,那么就可以直接在 QDataStream 中使用。不過(guò)首先需要使用 qRegisterMetaTypeStreamOperators().宏進(jìn)行注冊(cè)。這就能夠讓 QSettings 使用操作符對(duì)數(shù)據(jù)進(jìn)行操作,例如


qRegisterMetaTypeStreamOperators<BusinessCard>("BusinessCard"); 

本文出自 “豆子空間” 博客,請(qǐng)務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/193918