<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                #(45):模型 在前面兩章的基礎之上,我們將開始介紹 model 的通用概念。 在 model/view 架構中,model 提供一種標準接口,供視圖和委托訪問數據。在 Qt 中,這個接口由`QAbstractItemModel`類進行定義。不管底層數據是如何存儲的,只要是`QAbstractItemModel`的子類,都提供一種表格形式的層次結構。視圖利用統一的轉換來訪問模型中的數據。但是,需要提供的是,盡管模型內部是這樣組織數據的,但是并不要求也得這樣子向用戶展示數據。 下面是各種 model 的組織示意圖。我們利用此圖來理解什么叫“一種表格形式的層次結構”。 [![](https://box.kancloud.cn/2015-12-29_5682326191087.png)](http://files.devbean.net/images/2013/02/model-intro.png) 如上圖所示,List Model 雖然是線性的列表,也有一個 Root Item(根節點),之下才是呈線性的一個個數據,而這些數據實際可以看作是一個只有一列的表格,但是它是有層次的,因為有一個根節點。Table Model 就比較容易理解,只是也存在一個根節點。Tree Model 主要面向層次數據,而每一層次都可以都很多列,因此也是一個帶有層次的表格。 為了能夠使得數據的顯示同存儲分離,我們引入模型索引(model index)的概念。通過索引,我們可以訪問模型的特定元素的特定部分。視圖和委托使用索引來請求所需要的數據。由此可以看出,只有模型自己需要知道如何獲得數據,模型所管理的數據類型可以使用通用的方式進行定義。索引保存有創建的它的那個模型的指針,這使得同時操作多個模型成為可能。 ~~~ QAbstractItemModel *model = index.model(); ~~~ 模型索引提供了所需要的信息的**臨時索引**,可以用于通過模型取回或者修改數據。由于模型隨時可能重新組織其內部的結構,因此模型索引很可能變成不可用的,此時,就不應該保存這些數據。如果你需要長期有效的數據片段,必須創建**持久索引**。持久索引保證其引用的數據及時更新。臨時索引(也就是通常使用的索引)由`QModelIndex`類提供,持久索引則是`QPersistentModelIndex`類。 為了定位模型中的數據,我們需要三個屬性:行號、列號以及父索引。下面我們對其一一進行解釋。 我們前面介紹過模型的基本形式:數據以二維表的形式進行存儲。此時,一個數據可以由行號和列號進行定位。注意,我們僅僅是使用“二維表”這個名詞,并不意味著模型內部真的是以二維數組的形式進行存儲;所謂“行號”“列號”,也僅僅是為方便描述這種對應關系,并不真的是有行列之分。通過指定行號和列號,我們可以定位一個元素項,取出其信息。此時,我們獲得的是一個索引對象(回憶一下,通過索引我們可以獲取具體信息): ~~~ QModelIndex index = model->index(row, column, ...); ~~~ 模型提供了一個簡單的接口,用于列表以及表格這種非層次視圖的數據獲取。不過,正如上面的代碼暗示的那樣,實際接口并不是那么簡單。我們可以通過文檔查看這個函數的原型: ~~~ QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent=QModelIndex()) const ~~~ 這里,我們僅僅使用了前兩個參數。通過下圖來理解一下: [![](https://box.kancloud.cn/2015-12-29_56823261abbbc.png)](http://files.devbean.net/images/2013/02/table-model-index-intro.png) 在一個簡單的表格中,每一個項都可以由行號和列號確定。因此,我們只需提供兩個參數即可獲取到表格中的某一個數據項: ~~~ QModelIndex indexA = model->index(0, 0, QModelIndex()); QModelIndex indexB = model->index(1, 1, QModelIndex()); QModelIndex indexC = model->index(2, 1, QModelIndex()); ~~~ 函數的最后一個參數始終是 QModelIndex(),接下來我們就要討論這個參數的含義。 在類似表格的視圖中,比如列表和表格,行號和列號足以定位一個數據項。但是,對于樹型結構,僅有兩個參數就不足夠了。這是因為樹型結構是一個層次結構,而層次結構中每一個節點都有可能是另外一個表格。所以,每一個項需要指明其父節點。前面說過,在模型外部只能用過索引訪問內部數據,因此,`index()`函數還需要一個 parent 參數: ~~~ QModelIndex index = model->index(row, column, parent); ~~~ 類似的,我們來看看下面的示意圖: [![](https://box.kancloud.cn/2015-12-29_56823261bda30.png)](http://files.devbean.net/images/2013/02/tree-model-index-intro.png) 圖中,A 和 C 都是模型中的頂級項: ~~~ QModelIndex indexA = model->index(0, 0, QModelIndex()); QModelIndex indexC = model->index(2, 1, QModelIndex()); ~~~ A 還有自己的子項。那么,我們就應該使用下面的代碼獲取 B 的索引: ~~~ QModelIndex indexB = model->index(1, 0, indexA); ~~~ 由此我們看到,如果只有行號和列號兩個參數,B 的行號是 1,列號是 0,這同與 A 同級的行號是 1,列號是 0 的項相同,所以我們通過 parent 屬性區別開來。 以上我們討論了有關索引的定位。現在我們來看看模型的另外一個部分:數據角色。模型可以針對不同的組件(或者組件的不同部分,比如按鈕的提示以及顯示的文本等)提供不同的數據。例如,`Qt::DisplayRole`用于視圖的文本顯示。通常來說,數據項包含一系列不同的數據角色,這些角色定義在`Qt::ItemDataRole`枚舉中。 我們可以通過指定索引以及角色來獲得模型所提供的數據: ~~~ QVariant value = model->data(index, role); ~~~ 通過為每一個角色提供恰當的數據,模型可以告訴視圖和委托如何向用戶顯示內容。不同類型的視圖可以選擇忽略自己不需要的數據。當然,我們也可以添加我們所需要的額外數據。 總結一下: * 模型使用索引來提供給視圖和委托有關數據項的位置的信息,這樣做的好處是,模型之外的對象無需知道底層的數據存儲方式; * 數據項通過行號、列號以及父項三個坐標進行定位; * 模型索引由模型在其它組件(視圖和委托)請求時才會被創建; * 如果使用`index()`函數請求獲得一個父項的可用索引,該索引會指向模型中這個父項下面的數據項。這個索引指向該項的一個子項;如果使用`index()`函數請求獲得一個父項的不可用索引,該索引指向模型的最頂級項; * 角色用于區分數據項的不同類型的數據。 下面回到前面我們曾經見過的模型`QFileSystemModel`,看看如何從模型獲取數據。 ~~~ QFileSystemModel *model = new QFileSystemModel; QModelIndex parentIndex = model->index(QDir::currentPath()); int numRows = model->rowCount(parentIndex); ~~~ 在這個例子中,我們創建了`QFileSystemModel`的實例,使用`QFileSystemModel`重載的`index()`獲取索引,然后使用`rowCount()`函數計算當前目錄下有多少數據項(也就是行數)。前面一章中迷迷糊糊的代碼,現在已經相當清楚了。 為簡單起見,下面我們只關心模型第一列。我們遍歷所有數據,取得第一列索引: ~~~ for (int row = 0; row < numRows; ++row) { QModelIndex index = model->index(row, 0, parentIndex); ~~~ 我們使用`index()`函數,第一個參數是每一行行號,第二個參數是 0,也就是第一列,第三個參數是 parentIndex,也就是當前目錄作為父項。我們可以使用模型的`data()`函數獲取每一項的數據。注意,該函數返回值是`QVariant`,實際是一個字符串,因此我們直接轉換成`QString`: ~~~ QString text = model->data(index, Qt::DisplayRole).toString(); // 使用 text 數據 } ~~~ 上面的代碼片段顯示了從模型獲取數據的一些有用的函數: * 模型的數目信息可以通過`rowCount()`和`columnCount()`獲得。這些函數需要制定父項; * 索引用于訪問模型中的數據。我們需要利用行號、列號以及父項三個參數來獲得該索引; * 當我們使用`QModelIndex()`創建一個空索引使用時,我們獲得的就是模型中最頂級項; * 數據項包含了不同角色的數據。為獲取特定角色的數據,必須指定這個角色。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看