青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

清源游民 gameogre@gmail.com

創建新的Models

介紹
model/view組件之間功能的分離,允許創建model利用現成的views。這也可以使用標準的功能 圖形用戶接口組件像QListView,QTableView和QTreeView來顯示來自各種數據源的數據為。
QAbstractListModel類提供了非常靈活的接口,允許數據源以層次結構的形式來管理信息,也允許以某種
方式對數據進行插入、刪除、修改和存儲。它也提供了對拖拽操作的支持。
QAbstractListModelQAbstractTableModel為簡單的非層次結構的數據提供了接口,對于比較簡單的list和table models來說,這是不錯的一個開始點。

設計一個Model
當我們為存在的數據結構新建一個model時,首先要考慮的問題是應該選用哪種model來為這些數據提供接口。
假如數據結構可以用數據項的列表或表來表示,那么可以考慮子類化QAbstractListModelQAbstractTableModel
,既然這些類已經合理地對許多功能提供缺省實現。
然而,假如底層的數據結構只能表示成具有層次結構的樹型結構,那么必須得子類化QAbstractItemModel
無論底層的數據結構采取何種形式,在特定的model中實現標準的QAbstractItemModel API總是一個不錯的主意,這使得可以使用更自然的方式對底層的數據結構進行訪問。這也使得用數據構建model 更為容易,其他
的model/view組件也可以使用標準的API與之進行交互。

一個只讀model示例
這個示例實現了一個簡單的,非層次結構的,只讀的數據model,它基于QStringistModel類。它有一個QStringList作為它內部的數據源,只實現了一些必要的接口。為了簡單化,它子類化了QAbstractListModel,這個基類提供了合理的缺省行為,對外提供了比QAbstractItemModel更為簡單的接口。當我們實現一個model時,不要忘了QAbstractItemModel本身不存儲任何數據,它僅僅提供了給views訪問
數據的接口。
class StringListModel : public QAbstractListModel
 {
     Q_OBJECT

 public:
     StringListModel(const QStringList &strings, QObject *parent = 0)
         : QAbstractListModel(parent), stringList(strings) {}

     int rowCount(const QModelIndex &parent = QModelIndex()) const;
     QVariant data(const QModelIndex &index, int role) const;
     QVariant headerData(int section, Qt::Orientation orientation,
                         int role = Qt::DisplayRole) const;

 private:
     QStringList stringList;
 };
除了構造函數,我們僅需要實現兩個函數:rowCount()返回model中的行數,data()返回與特定model index對應的數據項。具有良好行為的model也會實現headerData(),它返回tree和table views需要的,在標題中顯示的數據。
因為這是一個非層次結構的model,我們不必考慮父子關系。假如model具有層次結構,我們也應該實現index()與parent()函數。

Model的尺寸
我們認為model中的行數與string list中的string數目一致:
int StringListModel::rowCount(const QModelIndex &parent) const
 {
     return stringList.count();
 }
在缺省情況下,從QAbstractListModel派生的model只具有一列,因此不需要實現columnCount()。

Model 標題與數據
 QVariant StringListModel::data(const QModelIndex &index, int role) const
 {
     if (!index.isValid())
         return QVariant();

     if (index.row() >= stringList.size())
         return QVariant();

     if (role == Qt::DisplayRole)
         return stringList.at(index.row());
     else
         return QVariant();
 }
QVariant StringListModel::headerData(int section, Qt::Orientation orientation,
                                      int role) const
 {
     if (role != Qt::DisplayRole)
         return QVariant();

     if (orientation == Qt::Horizontal)
         return QString("Column %1").arg(section);
     else
         return QString("Row %1").arg(section);
 }
一個數據項可能有多個角色,根據角色的不同輸出不同的數據。上例中,model中的數據項只有一個角色 ,
DisplayRole,然而我們也可以重用提供給DisplayRole的數據,作為別的角色使用,如我們可以作為ToolTipRole來用。

可編輯的model
上面我們演示了一個只讀的model,它只用于向用戶顯示,對于許多程序來說,可編輯的list model可能更有用。我們只需要給只讀的model提供另外兩個函數flags()與setData()的實現。下列函數聲明被添加到類定義中:
     Qt::ItemFlags flags(const QModelIndex &index) const;
     bool setData(const QModelIndex &index, const QVariant &value,
                  int role = Qt::EditRole);

讓model可編輯
delegate會在創建編輯器之前檢查數據項是否是可編輯的。model必須得讓delegate知道它的數據項是可
編輯的。這可以通過為每一個數據項返回一個正確的標記得到,在本例中,我們假設所有的數據項都是
可編輯可選擇的:
Qt::ItemFlags StringListModel::flags(const QModelIndex &index) const
 {
     if (!index.isValid())
         return Qt::ItemIsEnabled;

     return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
 }
我們不必知道delegate執行怎樣實際的編輯處理過程,我們只需提供給delegate一個方法,delegate會使用它對model中的數據進行設置。這個特殊的函數就是setData():
bool StringListModel::setData(const QModelIndex &index,
                               const QVariant &value, int role)
 {
     if (index.isValid() && role == Qt::EditRole) {

         stringList.replace(index.row(), value.toString());
         emit dataChanged(index, index);
         return true;
     }
     return false;
 }
當數據被設置后,model必須得讓views知道一些數據發生了變化,這可通過發射一個dataChanged() 信號實現。
因為只有一個數據項發生了變化,因此在信號中說明的變化范圍只限于一個model index。
插入,刪除行
在model中改變行數與列數是可能的。當然在本列中,只考慮行的情況,我們只需要重新實現插入、刪除
的函數就可以了,下面應在類定義中聲明:
     bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
     bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
既然model中的每行對應于列表中的一個string,因此,insertRows()函數在string list  中指定位置插入一個空string,
父index通常用于決定model中行列的位置,本例中只有一個單獨的頂級項,困此只需要在list中插入空string。
bool StringListModel::insertRows(int position, int rows, const QModelIndex &parent)
 {
     beginInsertRows(QModelIndex(), position, position+rows-1);

     for (int row = 0; row < rows; ++row) {
         stringList.insert(position, "");
     }

     endInsertRows();
     return true;
 }
beginInsertRows()通知其他組件行數將會改變。endInsertRows()對操作進行確認與通知。
返回true表示成功。
刪除操作與插入操作類似:
bool StringListModel::removeRows(int position, int rows, const QModelIndex &parent)
 {
     beginRemoveRows(QModelIndex(), position, position+rows-1);

     for (int row = 0; row < rows; ++row) {
         stringList.removeAt(position);
     }

     endRemoveRows();
     return true;
 }

posted on 2007-06-18 11:56 清源游民 閱讀(8471) 評論(0)  編輯 收藏 引用 所屬分類: Qt
<2007年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

留言簿(35)

隨筆分類(78)

隨筆檔案(74)

文章檔案(5)

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲免费视频观看| 国产一区二区三区不卡在线观看| 亚洲国语精品自产拍在线观看| 香港久久久电影| 亚洲欧美一区二区在线观看| 亚洲一区二区三区成人在线视频精品| 一区二区三区视频在线观看| 在线一区视频| 久久成人羞羞网站| 麻豆精品91| 亚洲国产va精品久久久不卡综合| 欧美国产一区二区在线观看| 亚洲国产精品传媒在线观看 | 在线观看亚洲精品视频| 激情成人亚洲| 夜夜嗨av一区二区三区中文字幕 | 久久久久久久综合狠狠综合| 久久精品二区三区| 欧美福利视频在线观看| 欧美视频官网| 影音先锋一区| 亚洲一级片在线观看| 香蕉国产精品偷在线观看不卡| 久久精品91久久香蕉加勒比 | 亚洲精品免费一二三区| 亚洲一区二区在线| 美脚丝袜一区二区三区在线观看 | 亚洲欧美国产精品va在线观看 | 亚洲精品美女| 午夜亚洲视频| 欧美激情精品| 黑人极品videos精品欧美裸| 亚洲欧美清纯在线制服| 欧美成年人视频网站| 99视频+国产日韩欧美| 欧美专区日韩专区| 欧美日韩一区二区在线播放| 国语精品中文字幕| 一区二区三区不卡视频在线观看| 久久久国产精品亚洲一区| 亚洲精品在线视频| 久久九九国产精品| 国产精品区一区二区三区| 亚洲理论电影网| 久久躁日日躁aaaaxxxx| 亚洲视频精品在线| 欧美三区美女| 99在线|亚洲一区二区| 免费成人高清| 亚洲一区二区成人| 欧美三级网址| 99精品欧美一区二区蜜桃免费| 欧美a级片网站| 蜜臀99久久精品久久久久久软件| 国产伊人精品| 久久久噜噜噜久久狠狠50岁| 午夜精品福利在线观看| 欧美日韩一本到| 一区二区三区高清不卡| 欧美成人激情视频免费观看| 午夜性色一区二区三区免费视频| 亚洲高清免费在线| 欧美成人69| 一区二区精品在线| 日韩视频免费看| 国产精品老牛| 久久精品国产91精品亚洲| 亚洲一区二区av电影| 国产精品毛片va一区二区三区 | 国产亚洲女人久久久久毛片| 欧美亚洲在线视频| 亚洲欧美制服另类日韩| 国产精品揄拍一区二区| 久久精品视频在线看| 午夜在线成人av| 极品日韩久久| 欧美激情精品久久久久久| 欧美激情精品久久久久久| 在线综合+亚洲+欧美中文字幕| 亚洲毛片在线| 国产精品热久久久久夜色精品三区 | 亚洲一区二区在线免费观看视频| 欧美性做爰猛烈叫床潮| 欧美一区二区三区视频在线观看| 午夜一区二区三视频在线观看 | 日韩视频一区二区在线观看| 欧美精品97| 亚洲图片欧美日产| 亚洲免费视频成人| 在线观看成人网| 亚洲第一区在线观看| 欧美视频观看一区| 久久久99国产精品免费| 一区在线播放视频| 亚洲激情在线| 国产日韩1区| 欧美激情一二区| 国产精品入口| 亚洲二区视频在线| 国产精品一区二区在线| 欧美国产在线视频| 国产美女搞久久| 亚洲精品国产精品国自产观看| 国产精品久久999| 欧美高清在线视频| 国产精品久久久久久久久久三级 | 欧美不卡福利| 欧美性猛片xxxx免费看久爱| 欧美性jizz18性欧美| 免费视频久久| 国产视频综合在线| 一本色道久久综合一区| 在线精品国精品国产尤物884a| 国产精品99久久久久久白浆小说 | 久久久水蜜桃| 久久精品国产免费看久久精品| 欧美成人激情在线| 玖玖视频精品| 国产性做久久久久久| 这里是久久伊人| 夜夜嗨av一区二区三区免费区| 久久久久国产成人精品亚洲午夜| 亚洲深夜福利网站| 欧美激情在线播放| 免费成人黄色| 狠狠色噜噜狠狠色综合久 | 久久国产福利| 久久九九免费视频| 国产亚洲欧洲997久久综合| 在线一区观看| 亚洲午夜激情网站| 欧美日韩成人在线视频| 亚洲国产你懂的| 在线视频国内自拍亚洲视频| 久久国产一二区| 久久欧美肥婆一二区| 国内自拍亚洲| 久久久久久久久久久久久9999| 久久精品国产96久久久香蕉| 国产精品人人做人人爽| 中文精品视频| 香蕉久久夜色精品国产| 日韩午夜三级在线| 99一区二区| 99v久久综合狠狠综合久久| 欧美肥婆在线| 亚洲精品综合精品自拍| 日韩午夜精品| 欧美午夜激情在线| 亚洲淫性视频| 久久久久国产精品一区三寸| 国产欧美一级| 欧美在线视屏| 欧美激情一二区| 一本大道久久a久久综合婷婷| 欧美精品入口| 亚洲丝袜av一区| 久久亚洲一区二区| 亚洲精品免费在线| 欧美色综合网| 欧美亚洲在线| 欧美激情中文不卡| 亚洲一区亚洲二区| 国户精品久久久久久久久久久不卡| 欧美在线亚洲一区| 亚洲国产精品va| 亚洲在线视频一区| 国产一区二区电影在线观看| 久久婷婷蜜乳一本欲蜜臀| 亚洲国产一二三| 亚洲欧美综合一区| 亚洲国产91精品在线观看| 欧美日韩另类综合| 欧美与黑人午夜性猛交久久久| 欧美成人午夜视频| 亚洲一区二区三区视频播放| 狠狠色综合一区二区| 欧美激情视频给我| 亚洲欧美日韩精品| 亚洲福利视频专区| 欧美一区二区国产| 99在线精品视频在线观看| 国产一区二区三区免费观看| 欧美极品色图| 久久精品国产精品亚洲精品| 亚洲裸体俱乐部裸体舞表演av| 久久天堂精品| 久久大综合网| 男人的天堂亚洲在线| 在线一区观看| 亚洲三级电影全部在线观看高清| 久久精品一区二区国产| 亚洲小说欧美另类社区| 亚洲国产精品123| 国产亚洲成精品久久| 欧美偷拍另类| 欧美日韩国产三级| 欧美大胆a视频| 久久综合一区二区三区| 欧美中日韩免费视频|