• <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>

            清源游民 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 清源游民 閱讀(8453) 評論(0)  編輯 收藏 引用 所屬分類: Qt
            <2007年3月>
            25262728123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            留言簿(35)

            隨筆分類(78)

            隨筆檔案(74)

            文章檔案(5)

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久婷婷五月综合成人D啪| 久久人人爽人人爽人人片AV高清 | 久久婷婷人人澡人人| 波多野结衣中文字幕久久| 久久婷婷五月综合成人D啪| 久久久久亚洲精品无码网址| 久久精品成人| 狠狠人妻久久久久久综合蜜桃 | 97久久香蕉国产线看观看| 亚洲国产精品18久久久久久| 精品久久久中文字幕人妻| 狠狠色丁香婷婷久久综合| 国内精品久久国产| 午夜不卡久久精品无码免费| 亚洲综合熟女久久久30p| 亚洲精品乱码久久久久久蜜桃图片| 漂亮人妻被中出中文字幕久久| 久久久久亚洲AV无码专区首JN| 亚洲国产精品无码久久SM| 国产A级毛片久久久精品毛片| 久久国产劲爆AV内射—百度| 亚洲精品午夜国产VA久久成人| 亚洲国产精品久久电影欧美| 久久精品人人槡人妻人人玩AV| 国产精品久久久久无码av| 精品久久久久中文字幕一区| 中文字幕精品久久久久人妻| 久久久久人妻一区二区三区vr| 国产69精品久久久久9999| 欧美与黑人午夜性猛交久久久 | 久久久国产打桩机| 久久精品亚洲中文字幕无码麻豆 | 国产精品内射久久久久欢欢| 欧美成a人片免费看久久| 久久精品国产免费观看| AAA级久久久精品无码区| 久久精品国产欧美日韩99热| 国产精品福利一区二区久久| 女同久久| 国产免费福利体检区久久| 久久亚洲中文字幕精品一区|