Qt QStandardItemModel用法(超級詳細)

QStandardItemModel 是標準的以項數據(item data)爲基礎的標準數據模型類,通常與 QTableView 組合成 Model/View 結構,實現通用的二維數據的管理功能。

本節介紹 QStandardltemModel 的使用,主要用到以下 3 個類:

  1. QStandardItemModel:基於項數據的標準數據模型,可以處理二維數據。維護一個二維的項數據數組,每個項是一個 QStandardltem 類的變量,用於存儲項的數據、字體格式、對齊方式等。
  2. QTableView:二維數據表視圖組件,有多個行和多個列,每個基本顯示單元是一個單元格,通過 setModel() 函數設置一個 QStandardItemModel 類的數據模型之後,一個單元格顯示 QStandardItemModel 數據模型中的一個項。
  3. 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 設計器生成的界面組件的槽函數的聲明):

複製純文本複製

 
  1. #define FixedColumnCount 6 //文件固定 6 列
  2. class MainWindow : public QMainWindow
  3. {
  4. Q_OBJECT private:
  5. QLabel *LabCurFile; //當前文件
  6. QLabel *LabCellPos; //當前單元格行列號
  7. QLabel *LabCellText; //當前單元格內容
  8. QStandardItemModel * theModel; //數據模型
  9. QItemSelectionModel *theSelection; //選擇模型
  10. void iniModelFromStringList (QStringList&) ; //從 StringList 初始化數據模型
  11. public:
  12. explicit MainWindow(QWidget *parent = 0);
  13. private slots:
  14. //當前選擇單元格發生變化
  15. void on_currentChanged(const QModelIndex &current, const QModelIndex &previous);
  16. private:
  17. Ui::MainWindow *ui;
  18. };
#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 &current, const QModelIndex &previous);
private:
    Ui::MainWindow *ui;
};

這裏定義了數據模型變量 theModel,項數據選擇模型變量 theSelection。

定義的私有函數 iniModelFromStringList() 用於在打開文件時,從一個 QStringList 變量的內容創建數據模型。

自定義槽函數 on_currentChanged() 用於在 TableView 上選擇單元格發生變化時,更新狀態欄的信息顯示,這個槽函數將會與項選擇模型 theSelection 的 currentChanged() 信號關聯。

QStandardltemModel的使用

系統初始化

在 MainWindow 的構造函數中進行界面初始化,數據模型和選擇模型的創建,以及與視圖組件的關聯,信號與槽的關聯等設置,代碼如下:

複製純文本複製

 
  1. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui (new Ui::MainWindow)
  2. {
  3. ui->setupUi(this);
  4. setCentralWidget(ui->splitter);
  5. theModel = new QStandardltemModel (2, FixedColumnCount, this) ; //數據模型
  6. theSelection = new QItemSelectionModel (theModel) ;//選擇模型
  7. connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
  8. ui->tableView->setModel (theModel) ; //設置數據模型
  9. ui->tableVi.evi-> setSelectionModel(theSelection) ; //設置選擇模型
  10. ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
  11. ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
  12. //創建狀態欄組件,代碼略
  13. }
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 選擇單元格發生變化時,顯示單元格的行號、列號、內容等信息,槽函數代碼如下:

複製純文本複製

 
  1. void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
  2. { //選擇單元格變化時的響應
  3. if (current.isValid())
  4. {
  5. LabCellPos->setText (QString::asprintf ("當前單元格:%d 行,%d 列", current.row(),current.column()));
  6. QStandardItem* aItem=theModel->itemFromIndex(current);
  7. this->LabCellText->setText ("單元格內容:"+aItem->text());
  8. QFont font=aItem->font();
  9. ui->actFontBold->setChecked(font.bold());
  10. }
  11. }
void MainWindow::on_currentChanged(const QModelIndex &current, 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 純文本格式的數據文件


下面是“打開文件”按鈕的槽函數代碼:

複製純文本複製

 
  1. void MainWindow::on_actOpen_triggered()
  2. { //打開文件
  3. //QString str;
  4. QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑
  5. //調用打開文件對話框打開一個文件
  6. QString aFileName=QFileDialog::getOpenFileName(this,"打開一個文件",curPath, "井數據文件(*.txt);;所有文件(*.*)");
  7. if (aFileName.isEmpty())
  8. return; //如果未選擇文件,退出
  9.  
  10. QStringList fFileContent;//文件內容字符串列表
  11. QFile aFile(aFileName); //以文件方式讀出
  12. if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) //以只讀文本方式打開文件
  13. {
  14. QTextStream aStream(&aFile); //用文本流讀取文件
  15. ui->plainTextEdit->clear();//清空
  16. while (!aStream.atEnd())
  17. {
  18. QString str=aStream.readLine();//讀取文件的一行
  19. ui->plainTextEdit->appendPlainText(str); //添加到文本框顯示
  20. fFileContent.append(str); //添加到 StringList
  21. }
  22. aFile.close();//關閉文件
  23.  
  24. this->LabCurFile->setText("當前文件:"+aFileName);//狀態欄顯示
  25. ui->actAppend->setEnabled(true); //更新Actions的enable屬性
  26. ui->actInsert->setEnabled(true);
  27. ui->actDelete->setEnabled(true);
  28. ui->actSave->setEnabled(true);
  29.  
  30. iniModelFromStringList(fFileContent);//從StringList的內容初始化數據模型
  31. }
  32. }
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() 函數的代碼:

複製純文本複製

 
  1. void MainWindow::iniModelFromStringList(QStringList& aFileContent)
  2. { //從一個StringList 獲取數據,初始化數據Model
  3. int rowCnt=aFileContent.count(); //文本行數,第1行是標題
  4. theModel->setRowCount(rowCnt-1); //實際數據行數
  5. //設置表頭
  6. QString header=aFileContent.at(0);//第1行是表頭
  7. //一個或多個空格、TAB等分隔符隔開的字符串, 分解爲一個StringList
  8. QStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);
  9. theModel->setHorizontalHeaderLabels(headerList); //設置表頭文字
  10.  
  11. //設置表格數據
  12. QString aText;
  13. QStringList tmpList;
  14. int j;
  15. QStandardItem *aItem;
  16. for (int i=1;i<rowCnt;i++)
  17. {
  18. QString aLineText=aFileContent.at(i); //獲取數據區的一行
  19. //一個或多個空格、TAB等分隔符隔開的字符串, 分解爲一個StringList
  20. QStringList tmpList=aLineText.split(QRegExp("\\s+"),QString::SkipEmptyParts);
  21. for (j=0;j<FixedColumnCount-1;j++) //tmpList的行數等於FixedColumnCount, 固定的
  22. { //不包含最後一列
  23. aItem=new QStandardItem(tmpList.at(j));//創建item
  24. theModel->setItem(i-1,j,aItem); //爲模型的某個行列位置設置Item
  25. }
  26.  
  27. aItem=new QStandardItem(headerList.at(j));//最後一列是Checkable,需要設置
  28. //aItem=new QStandardItem();//最後一列是Checkable,設置
  29. aItem->setCheckable(true); //設置爲Checkable
  30. //aItem->setTextAlignment(Qt::AlignHCenter);
  31. if (tmpList.at(j)=="0")
  32. aItem->setCheckState(Qt::Unchecked); //根據數據設置check狀態
  33. else
  34. aItem->setCheckState(Qt::Checked);
  35. theModel->setItem(i-1,j,aItem); //爲模型的某個行列位置設置Item
  36. }
  37. }
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 上顯示出來。

添加行

“添加行”操作是在數據表的最後添加一行,其實現代碼如下:

複製純文本複製

 
  1. void MainWindow::on_actAppend_triggered()
  2. { //在表格最後添加行
  3. QList<QStandardItem*> aItemList; //容器類
  4. QStandardItem *aItem;
  5. for(int i=0;i<FixedColumnCount-1;i++) //不包含最後1列
  6. {
  7. aItem=new QStandardItem("0"); //創建Item
  8. aItemList<<aItem; //添加到容器
  9. }
  10. //獲取最後一列的表頭文字
  11. QString str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
  12. aItem=new QStandardItem(str); //創建 "測井取樣"Item
  13. aItem->setCheckable(true);
  14. aItemList<<aItem; //添加到容器
  15.  
  16. theModel->insertRow(theModel->rowCount(),aItemList); //插入一行,需要每個Cell的Item
  17. QModelIndex curIndex=theModel->index(theModel->rowCount()-1,0);//創建最後一行的ModelIndex
  18. theSelection->clearSelection();//清空選擇項
  19. theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//設置剛插入的行爲當前選擇行
  20. }
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) 刪除指定的行。

複製純文本複製

 
  1. void MainWindow::on_actDelete_triggered()
  2. { //刪除行
  3. QModelIndex curIndex=theSelection->currentIndex () ;//獲取模型索引
  4. if (curIndex. row () ==theModel->rowCount () -1) //最後一行
  5. theModel->removeRow (curIndex.row () ) ; //刪除最後一行
  6. else {
  7. theModel->removeRow (curIndex.row () );//刪除一行,並重新設置當前選擇行
  8. theSelection->setCurrentIndex (curIndex, QItemSelectionModel::Select);
  9. }
  10. }
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 中選擇多個單元格時,可以同時設置多個單元格的格式。例如,“居左”按鈕的代碼如下:

複製純文本複製

 
  1. void MainWindow::on_actAlignLeft_triggered()
  2. { //設置文字居左對齊
  3. if (!theSelection->hasSelection())
  4. return;
  5. //獲取選擇的單元格的模型索引列表,可以是多選
  6. QModelIndexList selectedIndex=theSelection->selectedIndexes();
  7. for (int i=0;i<selectedIndex.count();i++)
  8. {
  9. QModelIndex aIndex=selectedIndex.at (i) ; //獲取一個模型索引
  10. QStandardItem* aItem=theModel->itemFromIndex(aIndex);
  11. aItem->setTextAlignment (Qt::AlignLeft) ;//設置文字對齊方式
  12. }
  13. }
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) 的槽函數代碼如下,與設置對齊方式的代碼操作方式類似:

複製純文本複製

 
  1. void MainWindow::on_actFontBold_triggered(bool checked)
  2. {//設置字體粗體
  3. if (!theSelection->hasSelection())
  4. return;
  5. //獲取選擇單元格的模型索引列表
  6. QModelIndexList selectedIndex=theSelection->selectedIndexes();
  7. for (int i=0;i<selectedIndex.count();i++)
  8. {
  9. QModelIndex aIndex=selectedIndex.at(i); //獲取一個模型索引
  10. QStandardItem* aItem=theModel->itemFromIndex(aIndex);//獲取項數據
  11. QFont font=aItem->font(); //獲取字體
  12. font.setBold(checked); //設置字體是否粗體
  13. aItem->setFont(font); //重新設置字體
  14. }
  15. }
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 裏,其實現代碼如下:

複製純文本複製

 
  1. void MainWindow::on_actSave_triggered()
  2. { //保存爲文件
  3. QString curPath=QCoreApplication::applicationDirPath(); //獲取應用程序的路徑
  4. //調用打開文件對話框選擇一個文件
  5. QString aFileName=QFileDialog::getSaveFileName(this,tr("選擇一個文件"),curPath,
  6. "井斜數據文件(*.txt);;所有文件(*.*)");
  7.  
  8. if (aFileName.isEmpty()) //未選擇文件,退出
  9. return;
  10.  
  11. QFile aFile(aFileName);
  12. if (!(aFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)))
  13. return; //以讀寫、覆蓋原有內容方式打開文件
  14.  
  15. QTextStream aStream(&aFile); //用文本流讀取文件
  16.  
  17. QStandardItem *aItem;
  18. int i,j;
  19. QString str;
  20.  
  21. ui->plainTextEdit->clear();
  22.  
  23. //獲取表頭文字
  24. for (i=0;i<theModel->columnCount();i++)
  25. {
  26. aItem=theModel->horizontalHeaderItem(i); //獲取表頭的項數據
  27. str=str+aItem->text()+"\t\t"; //以TAB見隔開
  28. }
  29. aStream<<str<<"\n"; //文件裏需要加入換行符 \n
  30. ui->plainTextEdit->appendPlainText(str);
  31.  
  32. //獲取數據區文字
  33. for ( i=0;i<theModel->rowCount();i++)
  34. {
  35. str="";
  36. for( j=0;j<theModel->columnCount()-1;j++)
  37. {
  38. aItem=theModel->item(i,j);
  39. str=str+aItem->text()+QString::asprintf("\t\t");
  40. }
  41.  
  42. aItem=theModel->item(i,j); //最後一列是邏輯型
  43. if (aItem->checkState()==Qt::Checked)
  44. str=str+"1";
  45. else
  46. str=str+"0";
  47.  
  48. ui->plainTextEdit->appendPlainText(str);
  49. aStream<<str<<"\n";
  50. }
  51. }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章