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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                #(50):自定義可編輯模型 上一章我們了解了如何自定義只讀模型。顧名思義,只讀模型只能夠用于展示只讀數據,用戶不能對其進行修改。如果允許用戶修改數據,則應該提供可編輯的模型。可編輯模型與只讀模型非常相似,至少在展示數據方面幾乎是完全一樣的,所不同的是可編輯模型需要提供用戶編輯數據后,應當如何將數據保存到實際存儲值中。 我們還是利用上一章的`CurrencyModel`,在此基礎上進行修改。相同的代碼這里不再贅述,我們只列出增加以及修改的代碼。相比只讀模型,可編輯模型需要增加以下兩個函數的實現: ~~~ Qt::ItemFlags flags(const QModelIndex &index) const; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); ~~~ 還記得之前我們曾經介紹過,在 Qt 的 model/view 模型中,我們使用委托 delegate 來實現數據的編輯。在實際創建編輯器之前,委托需要檢測這個數據項是不是允許編輯。模型必須讓委托知道這一點,這是通過返回模型中每個數據項的標記 flag 來實現的,也就是這個 flags() 函數。這本例中,只有行和列的索引不一致的時候,我們才允許修改(因為對角線上面的值恒為 1.0000,不應該對其進行修改): ~~~ Qt::ItemFlags CurrencyModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (index.row() != index.column()) { flags |= Qt::ItemIsEditable; } return flags; } ~~~ 注意,我們并不是在判斷了`index.row() != index.column()`之后直接返回`Qt::ItemIsEditable`,而是返回`QAbstractItemModel::flags(index) | Qt::ItemIsEditable`。這是因為我們不希望丟棄原來已經存在的那些標記。 我們不需要知道在實際編輯的過程中,委托究竟做了什么,只需要提供一種方式,告訴 Qt 如何將委托獲得的用戶輸入的新的數據保存到模型中。這一步驟是通過`setData()`函數實現的: ~~~ bool CurrencyModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && index.row() != index.column() && role == Qt::EditRole) { QString columnCurrency = headerData(index.column(), Qt::Horizontal, Qt::DisplayRole) .toString(); QString rowCurrency = headerData(index.row(), Qt::Vertical, Qt::DisplayRole) .toString(); currencyMap.insert(columnCurrency, value.toDouble() * currencyMap.value(rowCurrency)); emit dataChanged(index, index); return true; } return false; } ~~~ 回憶一下我們的業務邏輯:我們的底層數據結構中保存的是各個幣種相對美元的匯率,顯示的時候,我們使用列與行的比值獲取兩兩之間的匯率。例如,當我們修改`currencyMap["CNY"]/currencyMap["HKD"]`的值時,我們認為人民幣相對美元的匯率發生了變化,而港幣相對美元的匯率保持不變,因此新的數值應當是用戶新輸入的值與原來`currencyMap["HKD"]`的乘積。這正是上面的代碼所實現的邏輯。另外注意,在實際修改之前,我們需要檢查 index 是否有效,以及從業務來說,行列是否不等,最后還要檢查角色是不是`Qt::EditRole`。這里為方便起見,我們使用了`Qt::EditRole`,也就是編輯時的角色。但是,對于布爾類型,我們也可以選擇使用設置`Qt::ItemIsUserCheckable`標記的`Qt::CheckStateRole`,此時,Qt 會顯示一個選擇框而不是輸入框。注意這里的底層數據都是一樣的,只不過顯示方式的區別。當數據重新設置是,模型必須通知視圖,數據發生了變化。這要求我們必須發出`dataChanged()`信號。由于我們只有一個數據發生了改變,因此這個信號的兩個參數是一致的(`dataChanged()`的兩個參數是發生改變的數據區域的左上角和右下角的索引值,由于我們只改變了一個單元格,所以二者是相同的)。最后,如果數據修改成功就返回 true,否則返回 false。 當我們完成以上工作時,還需要修改一下`data()`函數: ~~~ QVariant CurrencyModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } if (role == Qt::TextAlignmentRole) { return int(Qt::AlignRight | Qt::AlignVCenter); } else if (role == Qt::DisplayRole || role == Qt::EditRole) { QString rowCurrency = currencyAt(index.row()); QString columnCurrency = currencyAt(index.column()); if (currencyMap.value(rowCurrency) == 0.0) { return "####"; } double amount = currencyMap.value(columnCurrency) / currencyMap.value(rowCurrency); return QString("%1").arg(amount, 0, 'f', 4); } return QVariant(); } ~~~ 我們的修改很簡單:僅僅是增加了`role == Qt::EditRole`這么一行判斷。這意味著,當是`EditRole`時,Qt 會提供一個默認值。我們可以試著刪除這個判斷來看看其產生的效果。 最后運行一下程序,修改一下數據就會發現,當我們修改過一個單元格后,Qt?會自動刷新所有受影響的數據的值。這也正是?model / view 模型的強大之處:對數據模型的修改會直接反映到視圖上。
                  <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>

                              哎呀哎呀视频在线观看