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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                #(43):QStringListModel 上一章我們已經了解到有關 list、table 和 tree 三個最常用的視圖類的便捷類的使用。前面也提到過,由于這些類僅僅是提供方便,功能、實現自然不如真正的 model/view 強大。從本章起,我們將了解最基本的 model/view 模型的使用。 既然是 model/view,我們也會分為兩部分:model 和 view。本章我們將介紹 Qt 內置的最簡單的一個模型:`QStringListModel`。接下來,我們再介紹另外的一些內置模型,在此基礎上,我們將了解到 Qt 模型的基本架構,以便為最高級的應用——自定義模型——打下堅實的基礎。 `QStringListModel`是最簡單的模型類,具備向視圖提供字符串數據的能力。`QStringListModel`是一個可編輯的模型,可以為組件提供一系列字符串作為數據。我們可以將其看作是封裝了`QStringList`的模型。`QStringList`是一種很常用的數據類型,實際上是一個字符串列表(也就是`QList<QString>`)。既然是列表,它也就是線性的數據結構,因此,`QStringListModel`很多時候都會作為`QListView`或者`QComboBox`這種只有一列的視圖組件的數據模型。 下面我們通過一個例子來看看`QStringListModel`的使用。首先是我們的構造函數: ~~~ MyListView::MyListView() { QStringList data; data << "Letter A" << "Letter B" << "Letter C"; model = new QStringListModel(this); model->setStringList(data); listView = new QListView(this); listView->setModel(model); QHBoxLayout *btnLayout = new QHBoxLayout; QPushButton *insertBtn = new QPushButton(tr("insert"), this); connect(insertBtn, SIGNAL(clicked()), this, SLOT(insertData())); QPushButton *delBtn = new QPushButton(tr("Delete"), this); connect(delBtn, SIGNAL(clicked()), this, SLOT(deleteData())); QPushButton *showBtn = new QPushButton(tr("Show"), this); connect(showBtn, SIGNAL(clicked()), this, SLOT(showData())); btnLayout->addWidget(insertBtn); btnLayout->addWidget(delBtn); btnLayout->addWidget(showBtn); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(listView); mainLayout->addLayout(btnLayout); setLayout(mainLayout); } ~~~ 我們不貼出完整的頭文件了,只看源代碼文件。首先,我們創建了一個`QStringList`對象,向其中插入了幾個數據;然后將其作為`QStringListModel`的底層數據。這樣,我們可以理解為,`QStringListModel`將`QStringList`包裝了起來。剩下來的只是簡單的界面代碼,這里不再贅述。試運行一下,程序應該是這樣的: [![](https://box.kancloud.cn/2015-12-29_568232605479b.png)](http://files.devbean.net/images/2013/02/qstringlistmodel-demo.png) 接下來我們來看幾個按鈕的響應槽函數。 ~~~ void MyListView::insertData() { bool isOK; QString text = QInputDialog::getText(this, "Insert", "Please input new data:", QLineEdit::Normal, "You are inserting new data.", &isOK); if (isOK) { int row = listView->currentIndex().row(); model->insertRows(row, 1); QModelIndex index = model->index(row); model->setData(index, text); listView->setCurrentIndex(index); listView->edit(index); } } ~~~ 首先是`insertData()`函數。我們使用`QInputDialog::getText()`函數要求用戶輸入數據。這是 Qt 的標準對話框,用于獲取用戶輸入的字符串。這部分在前面的章節中已經講解過。當用戶點擊了 OK 按鈕,我們使用`listView->currentIndex()`函數,獲取`QListView`當前行。這個函數的返回值是一個`QModelIndex`類型。我們會在后面的章節詳細講解這個類,現在只要知道這個類保存了三個重要的數據:行索引、列索引以及該數據屬于哪一個模型。我們調用其`row()`函數獲得行索引,該返回值是一個 int,也就是當前是第幾行。然后我們向模型插入新的一行。`insertRows()`函數簽名如下: ~~~ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); ~~~ 該函數會將 count 行插入到模型給定的 row 的位置,新行的數據將會作為 parent 的子元素。如果 row 為 0,新行將被插入到 parent 的所有數據之前,否則將在指定位置的數據之前。如果 parent 沒有子元素,則會新插入一個單列數據。函數插入成功返回 true,否則返回 false。我們在這段代碼中調用的是`insertRows(row, 1)`。這是`QStringListModel`的一個重載。參數 1 說明要插入 1 條數據。記得之前我們已經把 row 設置為當前行,因此,這行語句實際上是在當前的 row 位置插入 count 行,這里的 count 為 1。由于我們沒有添加任何數據,實際效果是,我們在 row 位置插入了 1 個空行。然后我們使用 model 的`index()`函數獲取當前行的`QModelIndex`對象,利用`setData()`函數把我們用`QInputDialog`接受的數據設置為當前行數據。接下來,我們使用`setCurrentIndex()`函數,把當前行設為新插入的一行,并調用`edit()`函數,使這一行可以被編輯。 以上是我們提供的一種插入數據的方法:首先插入空行,然后選中新插入的空行,設置新的數據。這其實是一種冗余操作,因為`currentIndex()`已經獲取到當前行。在此,我們僅僅是為了介紹這些函數的使用。因此,除去這些冗余,我們可以使用一種更簡潔的寫法: ~~~ void MyListView::insertData() { bool isOK; QString text = QInputDialog::getText(this, "Insert", "Please input new data:", QLineEdit::Normal, "You are inserting new data.", &isOK); if (isOK) { QModelIndex currIndex = listView->currentIndex(); model->insertRows(currIndex.row(), 1); model->setData(currIndex, text); listView->edit(currIndex); } } ~~~ 接下來是刪除數據: ~~~ void MyListView::deleteData() { if (model->rowCount() > 1) { model->removeRows(listView->currentIndex().row(), 1); } } ~~~ 使用模型的`removeRows()`函數可以輕松完成這個操作。這個函數同前面所說的`insertRows()`很類似,這里不再贅述。需要注意的是,我們用`rowCount()`函數判斷了一下,要求最終始終保留 1 行。這是因為我們寫的簡單地插入操作所限制,如果把數據全部刪除,就不能再插入數據了。所以,前面所說的插入操作實際上還需要再詳細考慮才可以解決這一問題。 最后是簡單地將所有數據都顯示出來: ~~~ void MyListView::showData() { QStringList data = model->stringList(); QString str; foreach(QString s, data) { str += s + "\n"; } QMessageBox::information(this, "Data", str); } ~~~ 這段代碼沒什么好說的。 關于`QStringListModel`我們簡單介紹這些。從這些示例中可以看到,幾乎所有操作都是針對模型的,也就是說,我們直接對數據進行操作,當模型檢測到數據發生了變化,會立刻通知視圖進行刷新。這樣,我們就可以把精力集中到對數據的操作上,而不用擔心視圖的同步顯示問題。這正是 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>

                              哎呀哎呀视频在线观看