Qt第十二天
阿新 • • 發佈:2018-12-16
QStandardItemModel的使用
實現功能:
開啟一個文字檔案,該檔案為二維資料檔案,通過字串處理獲取表頭和各行各列資料,匯入到QStandardItemModel資料模型
編輯修改資料模型的資料
設定資料模型中某項的不同角色的資料
通過QItemSelectionModel獲取檢視元件上當前單元格
將資料模型中的資料顯示到QPlainTextEdit元件中
將修改後的資料模型另存為一個文字檔案
mainwindow.h檔案
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QLabel> #include <QStandardItemModel> #include <QItemSelectionModel> namespace Ui { class MainWindow; } #define FixedColumCount 6 //固定列數為6 class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; QLabel *LabCurFile;//表示當前檔案 QLabel *LabCellPos;//當前單元格行列號 QLabel *LabCellText;//當前單元格內容 QStandardItemModel *theModel;//加入標頭檔案<QStandardItemModel> //資料模型 QItemSelectionModel *theSelection;//加入標頭檔案<QItemSelectionModel> //選擇資料模型 void iniModelFromStringList(QStringList&);//從StringList初始化資料模型 private slots: //自定義槽函式 void on_currentChanged(const QModelIndex ¤t,const QModelIndex &previous); void on_actOpen_triggered(); void on_actAppend_triggered(); void on_actInsert_triggered(); void on_actDelete_triggered(); void on_actAlignLeft_triggered(); void on_actAlignCenter_triggered(); void on_actAlignRight_triggered(); void on_actFontBold_triggered(); void on_actFontBold_triggered(bool checked); void on_actModelData_triggered(); void on_actSave_triggered(); }; #endif // MAINWINDOW_H
mainwindow.cpp檔案
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QTableView> #include <QFileDialog> #include <QTextStream> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //進行介面初始化,資料模型和選擇模型的建立,訊號與槽的關聯 setCentralWidget(ui->splitter); theModel=new QStandardItemModel(2,FixedColumCount,this);//2*6的資料模型 theSelection=new QItemSelectionModel(theModel);//選擇模型 connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentChanged(QModelIndex,QModelIndex))); //Selection的currentChanged訊號()與on_currentChanged()關聯 ui->tableView->setModel(theModel); ui->tableView->setSelectionModel(theSelection); ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);//允許選中多行 ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);//設定選擇模式為單元格 //狀態列標籤 LabCurFile = new QLabel("當前檔案:",this); LabCurFile->setMinimumWidth(200); LabCellPos = new QLabel("當前單元格:",this); LabCellPos->setMinimumWidth(180); LabCellPos->setAlignment(Qt::AlignHCenter);//設為中心 LabCellText = new QLabel("單元格內容:",this); LabCellText->setMinimumWidth(150); ui->statusBar->addWidget(LabCurFile); ui->statusBar->addWidget(LabCellPos); ui->statusBar->addWidget(LabCellText); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { Q_UNUSED(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; ui->actFontBold->setChecked(font.bold());//更新actFontBold的check狀態 } } void MainWindow::on_actOpen_triggered()//開啟檔案 { 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);//以文字流讀取檔案 //加入標頭檔案<QTextStream> ui->plainTextEdit->clear();//清空 while (!aStream.atEnd()) { QString str=aStream.readLine();//讀取檔案的一行 ui->plainTextEdit->appendPlainText(str); //新增到文字框顯示 fFileContent.append(str); //新增到 StringList } aFile.close();//關閉檔案 this->LabCurFile->setText("當前檔案:"+aFileName);//狀態列顯示 //更新Actions的enable屬性 ui->actAppend->setEnabled(true); ui->actInsert->setEnabled(true); ui->actDelete->setEnabled(true); ui->actSave->setEnabled(true); iniModelFromStringList(fFileContent);//初始化資料模型 } } 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); //設定表頭文字 //設定表格資料 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<FixedColumCount-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->setCheckable(true); //設定為Checkable if (tmpList.at(j)=="0") aItem->setCheckState(Qt::Unchecked); //根據資料設定check狀態 else aItem->setCheckState(Qt::Checked); theModel->setItem(i-1,j,aItem); //為模型的某個行列位置設定Item } } void MainWindow::on_actAppend_triggered()//在最後新增行 { QList<QStandardItem*> aItemList;//列表類 QStandardItem *aItem; for(int i=0;i<FixedColumCount-1;i++)//不包含最後一列 { aItem=new QStandardItem("未知");//建立Item為0 aItemList<<aItem;//新增到列表 } //獲取最後一列的表頭文字 QString str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();//獲取表頭 aItem=new QStandardItem(str); aItem->setCheckable(true); aItemList<<aItem;//新增到列表 theModel->insertRow(theModel->rowCount(),aItemList);//新增一行 QModelIndex curIndex=theModel->index(theModel->rowCount()-1,0);//改變索引值,設為新增行的第一列 theSelection->clearSelection(); theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//改變選中的單元格為新增行的第一個單元格 } void MainWindow::on_actInsert_triggered()//插入行 { QList<QStandardItem*> aItemList;//列表類 QStandardItem *aItem; for(int i=0;i<FixedColumCount-1;i++)//不包含最後一列 { aItem=new QStandardItem("未知1");//建立Item為0 aItemList<<aItem;//新增到列表 } //獲取最後一列的表頭文字 QString str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();//獲取表頭 aItem=new QStandardItem(str); aItem->setCheckable(true); aItemList<<aItem;//新增到列表 QModelIndex curIndex=theSelection->currentIndex();//獲取當前的索引 theModel->insertRow(curIndex.row(),aItemList);//在當前行插入新行 curIndex=theModel->index(curIndex.row(),0); theSelection->clearSelection(); 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);//重新設定選中行 } } void MainWindow::on_actAlignLeft_triggered()//左對齊 { if(!theSelection->hasSelection()) return; //獲取選中的單元格的模型索引列表 QModelIndexList selectedIndex=theSelection->selectedIndexes(); for(int i=0;i<selectedIndex.count();i++) { QModelIndex index=selectedIndex.at(i);//獲取一個模型索引 QStandardItem *aItem=theModel->itemFromIndex(index);//通過索引值獲取物件 aItem->setTextAlignment(Qt::AlignLeft);//設定為左對齊 } } void MainWindow::on_actAlignCenter_triggered()//居中對齊 { if(!theSelection->hasSelection()) return; QModelIndexList selectedIndex=theSelection->selectedIndexes(); for(int i=0;i<selectedIndex.count();i++) { QModelIndex index=selectedIndex.at(i);//獲取一個模型索引 QStandardItem *aItem=theModel->itemFromIndex(index);//通過索引值獲取物件 aItem->setTextAlignment(Qt::AlignHCenter);//設定為左對齊 } } void MainWindow::on_actAlignRight_triggered()//右對齊 { if(!theSelection->hasSelection()) return; QModelIndexList selectedIndex=theSelection->selectedIndexes(); for(int i=0;i<selectedIndex.count();i++) { QModelIndex index=selectedIndex.at(i);//獲取一個模型索引 QStandardItem *aItem=theModel->itemFromIndex(index);//通過索引值獲取物件 aItem->setTextAlignment(Qt::AlignRight);//設定為右對齊 } } void MainWindow::on_actFontBold_triggered() { } void MainWindow::on_actFontBold_triggered(bool checked)//設定為粗體 { if(!theSelection->hasSelection()) { return; } QModelIndexList selectedIndex=theSelection->selectedIndexes(); for(int i=0;i<selectedIndex.count();i++) { QModelIndex index=selectedIndex.at(i);//獲取一個模型索引 QStandardItem *aItem=theModel->itemFromIndex(index);//通過索引值獲取物件 QFont font=aItem->font(); font.setBold(checked);//設定為粗體 aItem->setFont(font); } } void MainWindow::on_actModelData_triggered()//資料模型預覽 { ui->plainTextEdit->clear(); //清空 QStandardItem *aItem; QString str; //獲取表頭文字 int i,j; for (i=0;i<theModel->columnCount();i++) { // aItem=theModel->horizontalHeaderItem(i); //獲取表頭的一個項資料 str=str+aItem->text()+"\t"; //用TAB間隔文字 } 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"); //以 TAB分隔 } aItem=theModel->item(i,j); //最後一行是邏輯型 if (aItem->checkState()==Qt::Checked) str=str+"1"; else str=str+"0"; ui->plainTextEdit->appendPlainText(str); } } 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"; } }