QStandardItemModel 是標準的以項數據(item data)爲基礎的標準數據模型類,通常與 QTableView 組合成 Model/View 結構,實現通用的二維數據的管理功能。
本節介紹 QStandardltemModel 的使用,主要用到以下 3 個類:
- QStandardItemModel:基於項數據的標準數據模型,可以處理二維數據。維護一個二維的項數據數組,每個項是一個 QStandardltem 類的變量,用於存儲項的數據、字體格式、對齊方式等。
- QTableView:二維數據表視圖組件,有多個行和多個列,每個基本顯示單元是一個單元格,通過 setModel() 函數設置一個 QStandardItemModel 類的數據模型之後,一個單元格顯示 QStandardItemModel 數據模型中的一個項。
- QItemSelectionModel:一個用於跟蹤視圖組件的單元格選擇狀態的類,當在 QTableView 選擇某個單元格,或多個單元格時,通過 QItemSelectionModel 可以獲得選中的單元格的模型索引,爲單元格的選擇操作提供方便。
這幾個類之間的關係是:QTableView 是界面視圖組件,其關聯的數據模型是 QStandardItem Model,關聯的項選擇模型是 QItemSelectionModel,QStandardItemModel 的數據管理的基本單元是 QStandardItem。
實例 samp5_3 演示 QStandardItemModel 的使用,其運行時界面如圖 1 所示。
圖 1 實例 samp5_3 的運行時界面
該實例具有如下功能:
- 打開一個純文本文件,該文件是規則的二維數據文件,通過字符串處理獲取表頭和各行各列的數據,導入到一個 QStandardItemModel 數據模型。
- 編輯修改數據模型的數據,可以插入行、添加行、刪除行,還可以在 QTableView 視圖組件中直接修改單元格的數據內容。
- 可以設置數據模型中某個項的不同角色的數據,包括文字對齊方式、字體是否粗體等。
- 通過 QItemSelectionModel 獲取視圖組件上的當前單元格,以及選擇單元格的範圍,對選擇的單元格進行操作。
- 將數據模型的數據內容顯示到 QPlainTextEdit 組件裏,顯示數據模型的內容,檢驗視圖組件上做的修改是否與數據模型同步。
- 將修改後的模型數據另存爲一個文本文件。
界面設計與主窗口類定義
本實例的主窗口從 QMainWindow 繼承而來,中間的 TableView 和 PlainTextEdit 組件採用水平分割條佈局。在 Action 編輯器中創建如圖 2 所示的一些 Action,並由 Action 創建主工具欄上的按鈕,下方的狀態欄設置了幾個 QLabel 組件,顯示當前文件名稱、當前單元格行號、列號,以及相應內容。
圖 2 實例中創建的 Action
主窗口類 MainWindow 裏新增的定義如下(省略了 UI 設計器生成的界面組件的槽函數的聲明):
複製純文本複製
- #define FixedColumnCount 6 //文件固定 6 列
- class MainWindow : public QMainWindow
- {
- Q_OBJECT private:
- QLabel *LabCurFile; //當前文件
- QLabel *LabCellPos; //當前單元格行列號
- QLabel *LabCellText; //當前單元格內容
- QStandardItemModel * theModel; //數據模型
- QItemSelectionModel *theSelection; //選擇模型
- void iniModelFromStringList (QStringList&) ; //從 StringList 初始化數據模型
- public:
- explicit MainWindow(QWidget *parent = 0);
- private slots:
- //當前選擇單元格發生變化
- void on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
- private:
- Ui::MainWindow *ui;
- };
#define FixedColumnCount 6 //文件固定 6 列 class MainWindow : public QMainWindow { Q_OBJECT private: QLabel *LabCurFile; //當前文件 QLabel *LabCellPos; //當前單元格行列號 QLabel *LabCellText; //當前單元格內容 QStandardItemModel * theModel; //數據模型 QItemSelectionModel *theSelection; //選擇模型 void iniModelFromStringList (QStringList&) ; //從 StringList 初始化數據模型 public: explicit MainWindow(QWidget *parent = 0); private slots: //當前選擇單元格發生變化 void on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous); private: Ui::MainWindow *ui; };
這裏定義了數據模型變量 theModel,項數據選擇模型變量 theSelection。
定義的私有函數 iniModelFromStringList() 用於在打開文件時,從一個 QStringList 變量的內容創建數據模型。
自定義槽函數 on_currentChanged() 用於在 TableView 上選擇單元格發生變化時,更新狀態欄的信息顯示,這個槽函數將會與項選擇模型 theSelection 的 currentChanged() 信號關聯。
QStandardltemModel的使用
系統初始化
在 MainWindow 的構造函數中進行界面初始化,數據模型和選擇模型的創建,以及與視圖組件的關聯,信號與槽的關聯等設置,代碼如下:
複製純文本複製
- MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui (new Ui::MainWindow)
- {
- ui->setupUi(this);
- setCentralWidget(ui->splitter);
- theModel = new QStandardltemModel (2, FixedColumnCount, this) ; //數據模型
- theSelection = new QItemSelectionModel (theModel) ;//選擇模型
- connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
- ui->tableView->setModel (theModel) ; //設置數據模型
- ui->tableVi.evi-> setSelectionModel(theSelection) ; //設置選擇模型
- ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
- ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
- //創建狀態欄組件,代碼略
- }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui (new Ui::MainWindow) { ui->setupUi(this); setCentralWidget(ui->splitter); theModel = new QStandardltemModel (2, FixedColumnCount, this) ; //數據模型 theSelection = new QItemSelectionModel (theModel) ;//選擇模型 connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this,SLOT(on_currentChanged(QModelIndex,QModelIndex))); ui->tableView->setModel (theModel) ; //設置數據模型 ui->tableVi.evi-> setSelectionModel(theSelection) ; //設置選擇模型 ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems); //創建狀態欄組件,代碼略 }
在構造函數裏首先創建數據模型 theModel,創建數據選擇模型時需要傳遞一個數據模型變量作爲其參數。這樣,數據選擇模型 theSelection 就與數據模型 theModel 關聯,用於表示 theModel 的項數據選擇操作。
創建數據模型和選擇模型後,爲 TableView 組件設置數據模型和選擇模型:
ui->tableView->setModel (theModel) ; //設置數據模型
ui->tableView->setSelectionModel (theSelection) ; //設置選擇模型
構造函數裏還將自定義的槽函數 on_currentChanged() 與 theSelection 的 currentChanged() 信號關聯,用於界面上 tableView 選擇單元格發生變化時,顯示單元格的行號、列號、內容等信息,槽函數代碼如下:
複製純文本複製
- void MainWindow::on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous)
- { //選擇單元格變化時的響應
- if (current.isValid())
- {
- LabCellPos->setText (QString::asprintf ("當前單元格:%d 行,%d 列", current.row(),current.column()));
- QStandardItem* aItem=theModel->itemFromIndex(current);
- this->LabCellText->setText ("單元格內容:"+aItem->text());
- QFont font=aItem->font();
- ui->actFontBold->setChecked(font.bold());
- }
- }
void MainWindow::on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { //選擇單元格變化時的響應 if (current.isValid()) { LabCellPos->setText (QString::asprintf ("當前單元格:%d 行,%d 列", current.row(),current.column())); QStandardItem* aItem=theModel->itemFromIndex(current); this->LabCellText->setText ("單元格內容:"+aItem->text()); QFont font=aItem->font(); ui->actFontBold->setChecked(font.bold()); } }
從文本文件導入數據
QStandardItemModel 是標準的基於項數據的數據模型,以類似於二維數組的形式管理內部數據,適合於處理表格型數據,其顯示一般採用 QTableView。
QStandardItemModel 的數據可以是程序生成的內存中的數據,也可以來源於文件。例如,在實際數據處理中,有些數據經常是以純文本格式保存的,它們有固定的列數,每一列是一項數據,實際構成一個二維數據表。圖 3 是本實例程序要打開的一個純文本文件的內容,文件的第 1 行是數據列的文字標題,相當於數據表的表頭,然後以行存儲數據,以 TAB 鍵間隔每列數據。
當單擊工具欄上的“打開文件”按鈕時,需要選擇一個這樣的文件導入到數據模型,並在 tableView 上進行顯示和編輯。圖 3 的數據有 6 列,第 1 列是整數,第 2 至 4 列是浮點數,第 5 列是文字,第 6 列是邏輯型變量,“1”表示 true。
圖 3 純文本格式的數據文件
下面是“打開文件”按鈕的槽函數代碼:
複製純文本複製
- void MainWindow::on_actOpen_triggered()
- { //打開文件
- //QString str;
- QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑
- //調用打開文件對話框打開一個文件
- QString aFileName=QFileDialog::getOpenFileName(this,"打開一個文件",curPath, "井數據文件(*.txt);;所有文件(*.*)");
- if (aFileName.isEmpty())
- return; //如果未選擇文件,退出
- QStringList fFileContent;//文件內容字符串列表
- QFile aFile(aFileName); //以文件方式讀出
- if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) //以只讀文本方式打開文件
- {
- QTextStream aStream(&aFile); //用文本流讀取文件
- ui->plainTextEdit->clear();//清空
- while (!aStream.atEnd())
- {
- QString str=aStream.readLine();//讀取文件的一行
- ui->plainTextEdit->appendPlainText(str); //添加到文本框顯示
- fFileContent.append(str); //添加到 StringList
- }
- aFile.close();//關閉文件
- this->LabCurFile->setText("當前文件:"+aFileName);//狀態欄顯示
- ui->actAppend->setEnabled(true); //更新Actions的enable屬性
- ui->actInsert->setEnabled(true);
- ui->actDelete->setEnabled(true);
- ui->actSave->setEnabled(true);
- iniModelFromStringList(fFileContent);//從StringList的內容初始化數據模型
- }
- }
void MainWindow::on_actOpen_triggered() { //打開文件 //QString str; QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑 //調用打開文件對話框打開一個文件 QString aFileName=QFileDialog::getOpenFileName(this,"打開一個文件",curPath, "井數據文件(*.txt);;所有文件(*.*)"); if (aFileName.isEmpty()) return; //如果未選擇文件,退出 QStringList fFileContent;//文件內容字符串列表 QFile aFile(aFileName); //以文件方式讀出 if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) //以只讀文本方式打開文件 { QTextStream aStream(&aFile); //用文本流讀取文件 ui->plainTextEdit->clear();//清空 while (!aStream.atEnd()) { QString str=aStream.readLine();//讀取文件的一行 ui->plainTextEdit->appendPlainText(str); //添加到文本框顯示 fFileContent.append(str); //添加到 StringList } aFile.close();//關閉文件 this->LabCurFile->setText("當前文件:"+aFileName);//狀態欄顯示 ui->actAppend->setEnabled(true); //更新Actions的enable屬性 ui->actInsert->setEnabled(true); ui->actDelete->setEnabled(true); ui->actSave->setEnabled(true); iniModelFromStringList(fFileContent);//從StringList的內容初始化數據模型 } }
這段代碼讓用戶選擇所需要打開的數據文本文件,然後用只讀和文本格式打開文件,逐行讀取其內容,將每行字符串顯示到界面上的 plainTextEdit 裏,並且添加到一個臨時的 QStringList 類型的變量 fFileContent 裏。
然後調用自定義函數 iniModelFromStringList(),用 fFileContent 的內容初始化數據模型。下面是 iniModelFromStringList() 函數的代碼:
複製純文本複製
- void MainWindow::iniModelFromStringList(QStringList& aFileContent)
- { //從一個StringList 獲取數據,初始化數據Model
- int rowCnt=aFileContent.count(); //文本行數,第1行是標題
- theModel->setRowCount(rowCnt-1); //實際數據行數
- //設置表頭
- QString header=aFileContent.at(0);//第1行是表頭
- //一個或多個空格、TAB等分隔符隔開的字符串, 分解爲一個StringList
- QStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);
- theModel->setHorizontalHeaderLabels(headerList); //設置表頭文字
- //設置表格數據
- QString aText;
- QStringList tmpList;
- int j;
- QStandardItem *aItem;
- for (int i=1;i<rowCnt;i++)
- {
- QString aLineText=aFileContent.at(i); //獲取數據區的一行
- //一個或多個空格、TAB等分隔符隔開的字符串, 分解爲一個StringList
- QStringList tmpList=aLineText.split(QRegExp("\\s+"),QString::SkipEmptyParts);
- for (j=0;j<FixedColumnCount-1;j++) //tmpList的行數等於FixedColumnCount, 固定的
- { //不包含最後一列
- aItem=new QStandardItem(tmpList.at(j));//創建item
- theModel->setItem(i-1,j,aItem); //爲模型的某個行列位置設置Item
- }
- aItem=new QStandardItem(headerList.at(j));//最後一列是Checkable,需要設置
- //aItem=new QStandardItem();//最後一列是Checkable,設置
- aItem->setCheckable(true); //設置爲Checkable
- //aItem->setTextAlignment(Qt::AlignHCenter);
- if (tmpList.at(j)=="0")
- aItem->setCheckState(Qt::Unchecked); //根據數據設置check狀態
- else
- aItem->setCheckState(Qt::Checked);
- theModel->setItem(i-1,j,aItem); //爲模型的某個行列位置設置Item
- }
- }
void MainWindow::iniModelFromStringList(QStringList& aFileContent) { //從一個StringList 獲取數據,初始化數據Model int rowCnt=aFileContent.count(); //文本行數,第1行是標題 theModel->setRowCount(rowCnt-1); //實際數據行數 //設置表頭 QString header=aFileContent.at(0);//第1行是表頭 //一個或多個空格、TAB等分隔符隔開的字符串, 分解爲一個StringList QStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts); theModel->setHorizontalHeaderLabels(headerList); //設置表頭文字 //設置表格數據 QString aText; QStringList tmpList; int j; QStandardItem *aItem; for (int i=1;i<rowCnt;i++) { QString aLineText=aFileContent.at(i); //獲取數據區的一行 //一個或多個空格、TAB等分隔符隔開的字符串, 分解爲一個StringList QStringList tmpList=aLineText.split(QRegExp("\\s+"),QString::SkipEmptyParts); for (j=0;j<FixedColumnCount-1;j++) //tmpList的行數等於FixedColumnCount, 固定的 { //不包含最後一列 aItem=new QStandardItem(tmpList.at(j));//創建item theModel->setItem(i-1,j,aItem); //爲模型的某個行列位置設置Item } aItem=new QStandardItem(headerList.at(j));//最後一列是Checkable,需要設置 //aItem=new QStandardItem();//最後一列是Checkable,設置 aItem->setCheckable(true); //設置爲Checkable //aItem->setTextAlignment(Qt::AlignHCenter); if (tmpList.at(j)=="0") aItem->setCheckState(Qt::Unchecked); //根據數據設置check狀態 else aItem->setCheckState(Qt::Checked); theModel->setItem(i-1,j,aItem); //爲模型的某個行列位置設置Item } }
傳遞來的參數 aFileContent 是文本文件所有行構成的 StringList,文件的每一行是 aFileContent 的一行字符串,第 1 行是表頭文字,數據從第 2 行開始。
程序首先獲取字符串列表的行數,然後設置數據模型的行數,因爲數據模型的列數在初始化時己經設置了。
然後獲取字符串列表的第 1 行,即表頭文字,用 QString::split() 函數分割成一個 QStringList,設置爲數據模型的表頭標題。
QString::split() 函數根據某個特定的符號將字符串進行分割。例如,header 是數據列的標題, 每個標題之間通過一個或多個 TAB 鍵分隔,其內容是:
測深(m) 垂深(m) 方位(°) 總位移(m) 固井質量 測井取樣
那麼通過上面的 split() 函數操作,得到一個字符串列表 headerList,其內容是:
測深(m)
垂深(m)
方位(°)
總位移(m)
固井質量
測井取樣
也就是分解爲一個 6 行的 StringList。然後使用此字符串列表作爲數據模型,設置表頭標題的函數 setHorizontalHeaderLabels() 的參數,就可以爲數據模型設置表頭了。
同樣,在逐行獲取字符串後,也採用 split() 函數進行分解,爲每個數據創建一個 QStandardltem 類型的項數據 altem,並賦給數據模型作爲某行某列的項數據。
QStandardItemModel 以二維表格的形式保存項數據,每個項數據對應着 QTableView 的一個單元格。項數據不僅可以存儲顯示的文字,還可以存儲其他角色的數據。
數據文件的最後一列是一個邏輯型數據,在 tableView 上顯示時爲其提供一個 CheckBox 組件,此功能通過調用 QStandardItem 的 setCheckable() 函數實現。
數據修改
當 TableView 設置爲可編輯時,雙擊一個單元格可以修改其內容,對於使用 CheckBox 的列,改變 CheckBox 的勾選狀態,就可以修改單元格關聯項的選擇狀態。
在實例主窗口工具欄上有“添加行”、“插入行”、“刪除行”按鈕,它們實現相應的編輯操作,這些操作都是直接針對數據模型的,數據模型被修改後,會直接在 TableView 上顯示出來。
添加行
“添加行”操作是在數據表的最後添加一行,其實現代碼如下:
複製純文本複製
- void MainWindow::on_actAppend_triggered()
- { //在表格最後添加行
- QList<QStandardItem*> aItemList; //容器類
- QStandardItem *aItem;
- for(int i=0;i<FixedColumnCount-1;i++) //不包含最後1列
- {
- aItem=new QStandardItem("0"); //創建Item
- aItemList<<aItem; //添加到容器
- }
- //獲取最後一列的表頭文字
- QString str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
- aItem=new QStandardItem(str); //創建 "測井取樣"Item
- aItem->setCheckable(true);
- aItemList<<aItem; //添加到容器
- theModel->insertRow(theModel->rowCount(),aItemList); //插入一行,需要每個Cell的Item
- QModelIndex curIndex=theModel->index(theModel->rowCount()-1,0);//創建最後一行的ModelIndex
- theSelection->clearSelection();//清空選擇項
- theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//設置剛插入的行爲當前選擇行
- }
void MainWindow::on_actAppend_triggered() { //在表格最後添加行 QList<QStandardItem*> aItemList; //容器類 QStandardItem *aItem; for(int i=0;i<FixedColumnCount-1;i++) //不包含最後1列 { aItem=new QStandardItem("0"); //創建Item aItemList<<aItem; //添加到容器 } //獲取最後一列的表頭文字 QString str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString(); aItem=new QStandardItem(str); //創建 "測井取樣"Item aItem->setCheckable(true); aItemList<<aItem; //添加到容器 theModel->insertRow(theModel->rowCount(),aItemList); //插入一行,需要每個Cell的Item QModelIndex curIndex=theModel->index(theModel->rowCount()-1,0);//創建最後一行的ModelIndex theSelection->clearSelection();//清空選擇項 theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//設置剛插入的行爲當前選擇行 }
使用 QStandardltemModel::insertRow() 函數插入一行,其函數原型是:
void insertRow(int row, const QList<QStandardltem *> fiitems)
其中,row 是一個行號,表示在此行號之前插入一行,若 row 等於或大於總行數,則在最後添加一行。QList<QStandardItem *>&items 是一個 QStandardltem 類型的列表類,需要爲插入的一行的每個項數據創建一個 QStandardltem 類型的項,然後傳遞給 insertRow() 函數。
在這段程序中,爲前 5 列創建 QStandardItem 對象時,都使用文字“0”,最後一列使用表頭的標題,並設置爲 Checkable。創建完每個項數據對象後,使用 insertRow() 函數在最後添加一行。
插入行
“插入行”按鈕的功能是在當前行的前面插入一行,實現代碼與“添加行”類似。
刪除行
“刪除行”按鈕的功能是刪除當前行,首先從選擇模型中獲取當前單元格的模型索引,然後從模型索引中獲取行號,調用 removeRow(int row) 刪除指定的行。
複製純文本複製
- void MainWindow::on_actDelete_triggered()
- { //刪除行
- QModelIndex curIndex=theSelection->currentIndex () ;//獲取模型索引
- if (curIndex. row () ==theModel->rowCount () -1) //最後一行
- theModel->removeRow (curIndex.row () ) ; //刪除最後一行
- else {
- theModel->removeRow (curIndex.row () );//刪除一行,並重新設置當前選擇行
- theSelection->setCurrentIndex (curIndex, QItemSelectionModel::Select);
- }
- }
void MainWindow::on_actDelete_triggered() { //刪除行 QModelIndex curIndex=theSelection->currentIndex () ;//獲取模型索引 if (curIndex. row () ==theModel->rowCount () -1) //最後一行 theModel->removeRow (curIndex.row () ) ; //刪除最後一行 else { theModel->removeRow (curIndex.row () );//刪除一行,並重新設置當前選擇行 theSelection->setCurrentIndex (curIndex, QItemSelectionModel::Select); } }
單元格格式設置
工具欄上有 3 個設置單元格文字對齊方式的按鈕,還有一個設置字體粗體的按鈕。當在 TableView 中選擇多個單元格時,可以同時設置多個單元格的格式。例如,“居左”按鈕的代碼如下:
複製純文本複製
- void MainWindow::on_actAlignLeft_triggered()
- { //設置文字居左對齊
- if (!theSelection->hasSelection())
- return;
- //獲取選擇的單元格的模型索引列表,可以是多選
- QModelIndexList selectedIndex=theSelection->selectedIndexes();
- for (int i=0;i<selectedIndex.count();i++)
- {
- QModelIndex aIndex=selectedIndex.at (i) ; //獲取一個模型索引
- QStandardItem* aItem=theModel->itemFromIndex(aIndex);
- aItem->setTextAlignment (Qt::AlignLeft) ;//設置文字對齊方式
- }
- }
void MainWindow::on_actAlignLeft_triggered() { //設置文字居左對齊 if (!theSelection->hasSelection()) return; //獲取選擇的單元格的模型索引列表,可以是多選 QModelIndexList selectedIndex=theSelection->selectedIndexes(); for (int i=0;i<selectedIndex.count();i++) { QModelIndex aIndex=selectedIndex.at (i) ; //獲取一個模型索引 QStandardItem* aItem=theModel->itemFromIndex(aIndex); aItem->setTextAlignment (Qt::AlignLeft) ;//設置文字對齊方式 } }
QItemSelectionModel::selectedIndexes() 函數返回選擇單元格的模型索引列表,然後通過此列表獲取每個選擇的單元格的模型索引,再通過模型索引獲取其項數據,然後調用 QStandardItem::setTextAlignment() 設置一個項的對齊方式即可。
“居中”和“居右”按鈕的代碼與此類似。
“粗體”按鈕設置單元格的字體是否爲粗體,在選擇單元格時,actFontBold 的 check 狀態根據當前單元格的字體是否爲粗體自動更新。actFontBold 的 triggered(bool) 的槽函數代碼如下,與設置對齊方式的代碼操作方式類似:
複製純文本複製
- void MainWindow::on_actFontBold_triggered(bool checked)
- {//設置字體粗體
- if (!theSelection->hasSelection())
- return;
- //獲取選擇單元格的模型索引列表
- QModelIndexList selectedIndex=theSelection->selectedIndexes();
- for (int i=0;i<selectedIndex.count();i++)
- {
- QModelIndex aIndex=selectedIndex.at(i); //獲取一個模型索引
- QStandardItem* aItem=theModel->itemFromIndex(aIndex);//獲取項數據
- QFont font=aItem->font(); //獲取字體
- font.setBold(checked); //設置字體是否粗體
- aItem->setFont(font); //重新設置字體
- }
- }
void MainWindow::on_actFontBold_triggered(bool checked) {//設置字體粗體 if (!theSelection->hasSelection()) return; //獲取選擇單元格的模型索引列表 QModelIndexList selectedIndex=theSelection->selectedIndexes(); for (int i=0;i<selectedIndex.count();i++) { QModelIndex aIndex=selectedIndex.at(i); //獲取一個模型索引 QStandardItem* aItem=theModel->itemFromIndex(aIndex);//獲取項數據 QFont font=aItem->font(); //獲取字體 font.setBold(checked); //設置字體是否粗體 aItem->setFont(font); //重新設置字體 } }
數據另存爲文件
在視圖組件上對數據的修改都會自動更新到數據模型裏,單擊工具欄上的“模型數據預覽” 按鈕,可以將數據模型的數據內容顯示到 PlainTextEdit 裏。
數據模型裏的數據是在內存中的,工具欄上的“另存文件”按鈕可以將數據模型的數據另存 爲一個數據文本文件,同時也顯示在 PlainTextEdit 裏,其實現代碼如下:
複製純文本複製
- void MainWindow::on_actSave_triggered()
- { //保存爲文件
- QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑
- //調用打開文件對話框選擇一個文件
- QString aFileName=QFileDialog::getSaveFileName(this,tr("選擇一個文件"),curPath,
- "井斜數據文件(*.txt);;所有文件(*.*)");
- if (aFileName.isEmpty()) //未選擇文件,退出
- return;
- QFile aFile(aFileName);
- if (!(aFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)))
- return; //以讀寫、覆蓋原有內容方式打開文件
- QTextStream aStream(&aFile); //用文本流讀取文件
- QStandardItem *aItem;
- int i,j;
- QString str;
- ui->plainTextEdit->clear();
- //獲取表頭文字
- for (i=0;i<theModel->columnCount();i++)
- {
- aItem=theModel->horizontalHeaderItem(i); //獲取表頭的項數據
- str=str+aItem->text()+"\t\t"; //以TAB見隔開
- }
- aStream<<str<<"\n"; //文件裏需要加入換行符 \n
- ui->plainTextEdit->appendPlainText(str);
- //獲取數據區文字
- for ( i=0;i<theModel->rowCount();i++)
- {
- str="";
- for( j=0;j<theModel->columnCount()-1;j++)
- {
- aItem=theModel->item(i,j);
- str=str+aItem->text()+QString::asprintf("\t\t");
- }
- aItem=theModel->item(i,j); //最後一列是邏輯型
- if (aItem->checkState()==Qt::Checked)
- str=str+"1";
- else
- str=str+"0";
- ui->plainTextEdit->appendPlainText(str);
- aStream<<str<<"\n";
- }
- }