Qt之模型-視圖編程(處理項目視圖的選擇)

簡述

項目視圖類使用選擇模型提供一種對選擇行爲的通用描述。

項目的選擇狀態信息被存儲在QItemSelectionModel類的實例中。

QItemSelectionModel維護着選擇實體(QItemSelection),選擇實體由選擇範圍構成,一個選擇範圍只需要起點(start index)和終點(end index)便可唯一確定。非連續的選擇選擇範圍則需要多個選擇範圍來描述。

提示: 當進行選擇操作時,可以將項目視圖中使用的選擇模型(QItemSelectionModel)看做是項目模型中項目的選擇狀態監控器

當前項目和被選擇的項目

在一個視圖中,總有兩種獨立狀態:當前項目、被選擇的項目。一定要將兩者清楚地區分開。

下面是二者的不同:

當前項目 被選擇的項目
只能有一個當前項目 可以有多個被選擇的項目
當前項目可以通過鍵盤按鍵或者鼠標點擊來改變 當用戶與項目進行交互時,根據幾種預定義模式(例如,單選,多選等)來設置或取消設置項目的選定狀態。
如果按下編輯鍵F2或雙擊該項目,則當前項目將被編輯(前提是啓用了編輯)。 當前項目可與錨點一起使用,以指定應選擇或取消選擇的範圍(或兩者的組合)。
當前項目由焦點矩形指示。 所選項目用選擇矩形表示。

使用選擇模型

標準視圖類爲大多數應用提供了默認的選擇模型。可以通過selectionModel()來獲取視圖的模型,可以通過setSelectionModel()來設置新的選擇模型

通過將一對模型索引傳遞給QItemSelection來創建一個選擇。這對模型索引中,一個表示選擇起點,一個表示選擇終點。爲了將選擇應用到項目上,我們還需要將創建的選擇提交給選擇模型。根據提交時附加的選擇模式,最終會出現特定的選擇效果。使用方法如下:

    //設置選擇起始點
	topLeft = model->index(1, 1, QModelIndex());
    bottomRight = model->index(2, 2, QModelIndex());
	//創建選擇
    QItemSelection selection(topLeft, bottomRight);
	//將選擇提交給選擇模型
    selectionModel->select(selection, QItemSelectionModel::Select);

效果如下:

常見操作

讀取選擇狀態

可以通過selectedIndexes()來讀取選擇模型中的模型索引,如下所示

      QModelIndexList indexes = selectionModel->selectedIndexes();
      QModelIndex index;

      foreach(index, indexes) {
          QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
          model->setData(index, text);
      }

效果

通過遍歷所有選中的項目,對這些項目進行賦值。

當選擇狀態改變的時候,選擇模型會發出信號來指示這種變化,可以編寫相應的槽函數來處理這個信號。下面的代碼展示了這樣一個槽函數。

void Widget::updateSelection(const QItemSelection &selected,
                             const QItemSelection &deselected) {
    QModelIndex index;
    QModelIndexList items = selected.indexes();

    foreach (index, items) {
        QString text = QString("(%1,%2)").arg(index.row()).arg(index.column());
        model->setData(index, text);
    }

    items = deselected.indexes();

    foreach (index, items)
        model->setData(index, "");
}

信號槽綁定:

    connect(selectionModel, &QItemSelectionModel::selectionChanged,this,
            &Widget::updateSelection);

效果

多模式選擇

我們通過如下命令來對特定的區域執行特定的操作:

	  selectionModel->select(selection, QItemSelectionModel::Select);

其中的QItemSelectionModel::Select來自QItemSelectionModel::SelectionFlag,這個枚舉類型定義了像清除、選擇、取消選擇、反選、整行選擇、整列選擇等等,這些枚舉值也可以進行組合使用,下面舉兩個例子來說明:

反選操作

      QItemSelection toggleSelection;

      topLeft = model->index(2, 1, QModelIndex());
      bottomRight = model->index(7, 3, QModelIndex());
      toggleSelection.select(topLeft, bottomRight);

      selectionModel->select(toggleSelection, QItemSelectionModel::Toggle);

整行整列選擇

      QItemSelection columnSelection;

      topLeft = model->index(0, 1, QModelIndex());
      bottomRight = model->index(0, 2, QModelIndex());

      columnSelection.select(topLeft, bottomRight);

      selectionModel->select(columnSelection,
          QItemSelectionModel::Select | QItemSelectionModel::Columns);

      QItemSelection rowSelection;

      topLeft = model->index(0, 0, QModelIndex());
      bottomRight = model->index(1, 0, QModelIndex());

      rowSelection.select(topLeft, bottomRight);

      selectionModel->select(rowSelection,
          QItemSelectionModel::Select | QItemSelectionModel::Rows);

效果

雖然我們只選擇了四個條目,但是這四個條目所在的整行整列都被選取了。

全選操作

全選是一種十分常見的操作,實現方法如下:

      QModelIndex parent = QModelIndex();
      QModelIndex topLeft = model->index(0, 0, parent);
      QModelIndex bottomRight = model->index(model->rowCount(parent)-1,
          model->columnCount(parent)-1, parent);
      QItemSelection selection(topLeft, bottomRight);
      selectionModel->select(selection, QItemSelectionModel::Select);

對於層級結構,hasChildren()函數被用來判斷給定的項目是否是另一些項目的父代。

引用

[1] Qt助手

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章