18、Model/View的使用

1、QFileSystemModel

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1-1、mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>900</width>
    <height>559</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>文件系统Model/View</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout_5">
    <property name="spacing">
     <number>3</number>
    </property>
    <property name="leftMargin">
     <number>3</number>
    </property>
    <property name="topMargin">
     <number>3</number>
    </property>
    <property name="rightMargin">
     <number>3</number>
    </property>
    <property name="bottomMargin">
     <number>3</number>
    </property>
    <item>
     <widget class="QSplitter" name="splitterMain">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <widget class="QGroupBox" name="groupBox_3">
       <property name="title">
        <string>TreeView</string>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_3">
        <property name="spacing">
         <number>4</number>
        </property>
        <property name="leftMargin">
         <number>4</number>
        </property>
        <property name="topMargin">
         <number>4</number>
        </property>
        <property name="rightMargin">
         <number>4</number>
        </property>
        <property name="bottomMargin">
         <number>4</number>
        </property>
        <item>
         <widget class="QTreeView" name="treeView"/>
        </item>
       </layout>
      </widget>
      <widget class="QSplitter" name="splitter">
       <property name="orientation">
        <enum>Qt::Vertical</enum>
       </property>
       <widget class="QGroupBox" name="groupBox">
        <property name="title">
         <string>ListView</string>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout">
         <property name="spacing">
          <number>4</number>
         </property>
         <property name="leftMargin">
          <number>4</number>
         </property>
         <property name="topMargin">
          <number>4</number>
         </property>
         <property name="rightMargin">
          <number>4</number>
         </property>
         <property name="bottomMargin">
          <number>4</number>
         </property>
         <item>
          <widget class="QListView" name="listView"/>
         </item>
        </layout>
       </widget>
       <widget class="QGroupBox" name="groupBox_2">
        <property name="title">
         <string>TableView</string>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout_2">
         <property name="spacing">
          <number>3</number>
         </property>
         <property name="leftMargin">
          <number>4</number>
         </property>
         <property name="topMargin">
          <number>4</number>
         </property>
         <property name="rightMargin">
          <number>4</number>
         </property>
         <property name="bottomMargin">
          <number>4</number>
         </property>
         <item>
          <widget class="QTableView" name="tableView"/>
         </item>
        </layout>
       </widget>
      </widget>
     </widget>
    </item>
    <item>
     <widget class="QGroupBox" name="groupBox_4">
      <property name="maximumSize">
       <size>
        <width>16777215</width>
        <height>100</height>
       </size>
      </property>
      <property name="title">
       <string/>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_4">
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
          <widget class="QLabel" name="LabFileName">
           <property name="text">
            <string>文件名:</string>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QLabel" name="LabFileSize">
           <property name="text">
            <string>文件大小:</string>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QLabel" name="LabType">
           <property name="text">
            <string>节点类型:</string>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QCheckBox" name="chkIsDir">
           <property name="text">
            <string>节点是目录</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
       <item>
        <widget class="QLabel" name="LabPath">
         <property name="text">
          <string>路径名:</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>900</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

1-2、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include    <QFileSystemModel>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QFileSystemModel    *model; //定义数据模型变量

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_treeView_clicked(const QModelIndex &index);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

1-3、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model=new QFileSystemModel(this); //QFileSystemModel提供单独线程,推荐使用
    model->setRootPath(QDir::currentPath()); //设置根目录

    ui->treeView->setModel(model); //设置数据模型
    ui->listView->setModel(model); //设置数据模型
    ui->tableView->setModel(model); //设置数据模型

//信号与槽关联,treeView单击时,其目录设置为listView和tableView的根节点
    connect(ui->treeView,SIGNAL(clicked(QModelIndex)),
            ui->listView,SLOT(setRootIndex(QModelIndex)));

    connect(ui->treeView,SIGNAL(clicked(QModelIndex)),
            ui->tableView,SLOT(setRootIndex(QModelIndex)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_treeView_clicked(const QModelIndex &index)
{
    ui->chkIsDir->setChecked(model->isDir(index));
    ui->LabPath->setText(model->filePath(index));
    ui->LabType->setText(model->type(index));

    ui->LabFileName->setText(model->fileName(index));

    int sz=model->size(index)/1024;
    if (sz<1024)
        ui->LabFileSize->setText(QString("%1 KB").arg(sz));
    else
        ui->LabFileSize->setText(QString::asprintf("%.1f MB",sz/1024.0));
}

2、QStringListModel

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2-1、widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>549</width>
    <height>348</height>
   </rect>
  </property>
  <property name="font">
   <font>
    <pointsize>10</pointsize>
   </font>
  </property>
  <property name="windowTitle">
   <string>QListView的使用</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_4">
   <property name="spacing">
    <number>3</number>
   </property>
   <property name="leftMargin">
    <number>4</number>
   </property>
   <property name="topMargin">
    <number>4</number>
   </property>
   <property name="rightMargin">
    <number>4</number>
   </property>
   <property name="bottomMargin">
    <number>4</number>
   </property>
   <item>
    <widget class="QSplitter" name="splitter">
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
       <string>QListView</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_3">
       <property name="spacing">
        <number>3</number>
       </property>
       <property name="leftMargin">
        <number>4</number>
       </property>
       <property name="topMargin">
        <number>4</number>
       </property>
       <property name="rightMargin">
        <number>4</number>
       </property>
       <property name="bottomMargin">
        <number>4</number>
       </property>
       <item>
        <layout class="QGridLayout" name="gridLayout">
         <item row="0" column="0">
          <widget class="QPushButton" name="btnIniList">
           <property name="text">
            <string>恢复列表</string>
           </property>
          </widget>
         </item>
         <item row="1" column="0">
          <widget class="QPushButton" name="btnListAppend">
           <property name="text">
            <string>添加项</string>
           </property>
          </widget>
         </item>
         <item row="1" column="1">
          <widget class="QPushButton" name="btnListInsert">
           <property name="text">
            <string>插入项</string>
           </property>
          </widget>
         </item>
         <item row="2" column="0">
          <widget class="QPushButton" name="btnListDelete">
           <property name="text">
            <string>删除当前项</string>
           </property>
          </widget>
         </item>
         <item row="2" column="1">
          <widget class="QPushButton" name="btnListClear">
           <property name="text">
            <string>清除列表</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
       <item>
        <widget class="QListView" name="listView"/>
       </item>
      </layout>
     </widget>
     <widget class="QGroupBox" name="groupBox_2">
      <property name="title">
       <string>QPlainTextEdit</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_2">
       <property name="spacing">
        <number>3</number>
       </property>
       <property name="leftMargin">
        <number>4</number>
       </property>
       <property name="topMargin">
        <number>4</number>
       </property>
       <property name="rightMargin">
        <number>4</number>
       </property>
       <property name="bottomMargin">
        <number>4</number>
       </property>
       <item>
        <layout class="QVBoxLayout" name="verticalLayout">
         <item>
          <widget class="QPushButton" name="btnTextClear">
           <property name="text">
            <string>清空文本</string>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QPushButton" name="btnTextImport">
           <property name="text">
            <string>显示数据模型的StringList</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
       <item>
        <widget class="QPlainTextEdit" name="plainTextEdit"/>
       </item>
      </layout>
     </widget>
    </widget>
   </item>
   <item>
    <widget class="QGroupBox" name="groupBox_3">
     <property name="maximumSize">
      <size>
       <width>16777215</width>
       <height>40</height>
      </size>
     </property>
     <property name="title">
      <string/>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QLabel" name="LabInfo">
        <property name="text">
         <string>当前项的ModelIndex</string>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </item>
  </layout>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

2-2、widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include    <QWidget>
#include    <QStringListModel>


namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

private:
    QStringListModel   *theModel; //数据模型

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_listView_clicked(const QModelIndex &index); //单击事件,显示QModelIndex的内容

    void on_btnIniList_clicked(); //初始化列表

    void on_btnTextClear_clicked();//清除 PlainText 的内容

    void on_btnTextImport_clicked();//ListView 的内容导入到PlainText显示

    void on_btnListClear_clicked(); //清除 ListView

    void on_btnListAppend_clicked(); //添加一行

    void on_btnListInsert_clicked(); //插入一行

    void on_btnListDelete_clicked(); //删除当前行

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

2-3、widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QStringList         theStrList; //保存初始 StringList
    theStrList<<"北京"<<"上海"<<"天津"<<"河北"<<"山东"<<"四川"<<"重庆"<<"广东"<<"河南"; //初始化 StringList

    theModel=new QStringListModel(this); //创建数据模型
    theModel->setStringList(theStrList); //为模型设置StringList,会导入StringList的内容
    ui->listView->setModel(theModel); //为listView设置数据模型

    ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked    | QAbstractItemView::SelectedClicked);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_listView_clicked(const QModelIndex &index)
{ //显示QModelIndex的行、列号
    ui->LabInfo->setText(QString::asprintf("当前项:row=%d, column=%d",
                        index.row(),index.column()));
}

void Widget::on_btnIniList_clicked()
{ //重新载入theStrList的内容,初始化theModel的内容
    QStringList         theStrList; //保存初始 StringList
    theStrList<<"北京"<<"上海"<<"天津"<<"河北"<<"山东"<<"四川"<<"重庆"<<"广东"<<"河南"; //初始化 StringList
    theModel->setStringList(theStrList);
}

void Widget::on_btnTextClear_clicked()
{ //清除plainTextEdit的文本
    ui->plainTextEdit->clear();
}

void Widget::on_btnTextImport_clicked()
{// 显示数据模型的StringList
    QStringList tmpList;
    tmpList=theModel->stringList();//获取数据模型的StringList

    ui->plainTextEdit->clear(); //文本框清空
    for (int i=0; i<tmpList.count();i++)
        ui->plainTextEdit->appendPlainText(tmpList.at(i)); //显示数据模型的StringList()返回的内容
}

void Widget::on_btnListClear_clicked()
{//清除ListView的所有项
    theModel->removeRows(0,theModel->rowCount());
}

void Widget::on_btnListAppend_clicked()
{ //添加一行
    theModel->insertRow(theModel->rowCount()); //在尾部插入一空行
    QModelIndex index=theModel->index(theModel->rowCount()-1,0);//获取最后一行
    theModel->setData(index,"new item",Qt::DisplayRole);//设置显示文字
    ui->listView->setCurrentIndex(index); //设置当前选中的行
}

void Widget::on_btnListInsert_clicked()
{//插入一行
    QModelIndex  index;
    index=ui->listView->currentIndex(); //当前 modelIndex
    theModel->insertRow(index.row()); //在当前行的前面插入一行
    theModel->setData(index,"inserted item",Qt::DisplayRole); //设置显示文字
    theModel->setData(index,Qt::AlignRight,Qt::TextAlignmentRole); //设置对齐方式,不起作用
    ui->listView->setCurrentIndex(index); //设置当前选中的行
}

void Widget::on_btnListDelete_clicked()
{//删除当前行
    QModelIndex  index;
    index=ui->listView->currentIndex(); //获取当前 modelIndex
    theModel->removeRow(index.row()); //删除当前行
}

3、QStandardItemModel

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3-1、mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>753</width>
    <height>403</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>QTableView与QStandardItemModel</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QSplitter" name="splitter">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>40</y>
      <width>532</width>
      <height>261</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
    <widget class="QGroupBox" name="groupBox">
     <property name="title">
      <string>TableView</string>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout">
      <property name="leftMargin">
       <number>4</number>
      </property>
      <property name="topMargin">
       <number>4</number>
      </property>
      <property name="rightMargin">
       <number>4</number>
      </property>
      <property name="bottomMargin">
       <number>4</number>
      </property>
      <item>
       <widget class="QTableView" name="tableView">
        <property name="editTriggers">
         <set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
        </property>
        <property name="alternatingRowColors">
         <bool>true</bool>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
    <widget class="QGroupBox" name="groupBox_2">
     <property name="title">
      <string>PlainTextEdit</string>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout_2">
      <property name="leftMargin">
       <number>4</number>
      </property>
      <property name="topMargin">
       <number>4</number>
      </property>
      <property name="rightMargin">
       <number>4</number>
      </property>
      <property name="bottomMargin">
       <number>4</number>
      </property>
      <item>
       <widget class="QPlainTextEdit" name="plainTextEdit">
        <property name="lineWrapMode">
         <enum>QPlainTextEdit::NoWrap</enum>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>753</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <property name="toolButtonStyle">
    <enum>Qt::ToolButtonTextUnderIcon</enum>
   </property>
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
   <addaction name="actOpen"/>
   <addaction name="actSave"/>
   <addaction name="actModelData"/>
   <addaction name="separator"/>
   <addaction name="actAppend"/>
   <addaction name="actInsert"/>
   <addaction name="actDelete"/>
   <addaction name="separator"/>
   <addaction name="actAlignLeft"/>
   <addaction name="actAlignCenter"/>
   <addaction name="actAlignRight"/>
   <addaction name="actFontBold"/>
   <addaction name="separator"/>
   <addaction name="actExit"/>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actOpen">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/open.bmp</normaloff>:/images/icons/open.bmp</iconset>
   </property>
   <property name="text">
    <string>打开文件</string>
   </property>
   <property name="toolTip">
    <string>打开文件</string>
   </property>
  </action>
  <action name="actSave">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/save.bmp</normaloff>:/images/icons/save.bmp</iconset>
   </property>
   <property name="text">
    <string>另存文件</string>
   </property>
   <property name="toolTip">
    <string>表格内容另存为文件</string>
   </property>
  </action>
  <action name="actAppend">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/append.bmp</normaloff>:/images/icons/append.bmp</iconset>
   </property>
   <property name="text">
    <string>添加行</string>
   </property>
   <property name="toolTip">
    <string>添加一行</string>
   </property>
  </action>
  <action name="actInsert">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/306.bmp</normaloff>:/images/icons/306.bmp</iconset>
   </property>
   <property name="text">
    <string>插入行</string>
   </property>
   <property name="toolTip">
    <string>插入一行</string>
   </property>
  </action>
  <action name="actDelete">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/delete.bmp</normaloff>:/images/icons/delete.bmp</iconset>
   </property>
   <property name="text">
    <string>删除行</string>
   </property>
   <property name="toolTip">
    <string>删除当前行</string>
   </property>
  </action>
  <action name="actExit">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/exit.bmp</normaloff>:/images/icons/exit.bmp</iconset>
   </property>
   <property name="text">
    <string>退出</string>
   </property>
   <property name="toolTip">
    <string>退出</string>
   </property>
  </action>
  <action name="actModelData">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/import1.bmp</normaloff>:/images/icons/import1.bmp</iconset>
   </property>
   <property name="text">
    <string>模型数据预览</string>
   </property>
   <property name="toolTip">
    <string>模型数据显示到文本框里</string>
   </property>
  </action>
  <action name="actAlignLeft">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/508.bmp</normaloff>:/images/icons/508.bmp</iconset>
   </property>
   <property name="text">
    <string>居左</string>
   </property>
   <property name="toolTip">
    <string>文字左对齐</string>
   </property>
  </action>
  <action name="actAlignCenter">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/510.bmp</normaloff>:/images/icons/510.bmp</iconset>
   </property>
   <property name="text">
    <string>居中</string>
   </property>
   <property name="toolTip">
    <string>文字居中</string>
   </property>
  </action>
  <action name="actAlignRight">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/512.bmp</normaloff>:/images/icons/512.bmp</iconset>
   </property>
   <property name="text">
    <string>居右</string>
   </property>
   <property name="toolTip">
    <string>文字右对齐</string>
   </property>
  </action>
  <action name="actFontBold">
   <property name="checkable">
    <bool>true</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/500.bmp</normaloff>:/images/icons/500.bmp</iconset>
   </property>
   <property name="text">
    <string>粗体</string>
   </property>
   <property name="toolTip">
    <string>粗体字体</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources>
  <include location="res.qrc"/>
 </resources>
 <connections>
  <connection>
   <sender>actExit</sender>
   <signal>triggered()</signal>
   <receiver>MainWindow</receiver>
   <slot>close()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>-1</x>
     <y>-1</y>
    </hint>
    <hint type="destinationlabel">
     <x>433</x>
     <y>266</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

3-2、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include    <QMainWindow>
#include    <QLabel>
#include    <QStandardItemModel>
#include    <QItemSelectionModel>

#define     FixedColumnCount    6       //文件固定6列

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:

//用于状态栏的信息显示
    QLabel  *LabCurFile;  //当前文件
    QLabel  *LabCellPos;    //当前单元格行列号
    QLabel  *LabCellText;   //当前单元格内容

    QStandardItemModel  *theModel;//数据模型
    QItemSelectionModel *theSelection;//Item选择模型

    void    iniModelFromStringList(QStringList&);//从StringList初始化数据模型

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
 //当前选择单元格发生变化
    void on_currentChanged(const QModelIndex &current, const QModelIndex &previous);


    void on_actOpen_triggered(); //打开文件

    void on_actAppend_triggered(); //添加行

    void on_actInsert_triggered();//插入行

    void on_actDelete_triggered();//删除行

    void on_actModelData_triggered();  //到处模型数据

    void on_actSave_triggered();//保存文件

    void on_actAlignCenter_triggered();//居中对齐

    void on_actFontBold_triggered(bool checked);//粗体字体

    void on_actAlignLeft_triggered(); //居左对齐

    void on_actAlignRight_triggered();//居右对齐

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

3-3、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include    <QFileDialog>
#include    <QTextStream>


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


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    theModel = new QStandardItemModel(2,FixedColumnCount,this); //数据模型
    theSelection = new QItemSelectionModel(theModel);//Item选择模型

//选择当前单元格变化时的信号与槽
    connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));

    //为tableView设置数据模型
    ui->tableView->setModel(theModel); //设置数据模型
    ui->tableView->setSelectionModel(theSelection);//设置选择模型
    ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);//
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);

    setCentralWidget(ui->splitter); //

//创建状态栏组件
    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 &current, const QModelIndex &previous)
{ //选择单元格变化时的响应
   Q_UNUSED(previous);

    if (current.isValid()) //当前模型索引有效
    {
        LabCellPos->setText(QString::asprintf("当前单元格:%d行,%d列",
                                  current.row(),current.column())); //显示模型索引的行和列号
        QStandardItem   *aItem;
        aItem=theModel->itemFromIndex(current); //从模型索引获得Item
        this->LabCellText->setText("单元格内容:"+aItem->text()); //显示item的文字内容

        QFont   font=aItem->font(); //获取item的字体
        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); //用文本流读取文件
        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_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_actInsert_triggered()
{//插入行
    QList<QStandardItem*>    aItemList;  //QStandardItem的列表类
    QStandardItem   *aItem;
    for(int i=0;i<FixedColumnCount-1;i++)
    {
        aItem=new QStandardItem("0"); //新建一个QStandardItem
        aItemList<<aItem;//添加到列表类
    }
//    aItem=new QStandardItem("优"); //新建一个QStandardItem
//    aItemList<<aItem;//添加到列表类

    QString str;    //获取表头文字
    str=theModel->headerData(theModel->columnCount()-1,
                             Qt::Horizontal,Qt::DisplayRole).toString();
    aItem=new QStandardItem(str); //创建Item
    aItem->setCheckable(true);//设置为可使用CheckBox
    aItemList<<aItem;//添加到列表类


    QModelIndex curIndex=theSelection->currentIndex(); //获取当前选中项的模型索引
    theModel->insertRow(curIndex.row(),aItemList);  //在当前行的前面插入一行
    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_actModelData_triggered()
{//模型数据导出到PlainTextEdit显示
    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";
    }
}

void MainWindow::on_actAlignCenter_triggered()
{//文字居中对齐
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndex=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndex.count();i++)
    {
        aIndex=selectedIndex.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignHCenter);
    }
}

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_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_actAlignRight_triggered()
{//设置文字居右对齐
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndex=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndex.count();i++)
    {
        aIndex=selectedIndex.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignRight);
    }
}


4、自定义代理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4-1、mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>687</width>
    <height>393</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>QTableView与QStandardItemModel</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QSplitter" name="splitter">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>40</y>
      <width>532</width>
      <height>214</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
    <widget class="QGroupBox" name="groupBox">
     <property name="title">
      <string>TableView</string>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout">
      <property name="leftMargin">
       <number>4</number>
      </property>
      <property name="topMargin">
       <number>4</number>
      </property>
      <property name="rightMargin">
       <number>4</number>
      </property>
      <property name="bottomMargin">
       <number>4</number>
      </property>
      <item>
       <widget class="QTableView" name="tableView">
        <property name="editTriggers">
         <set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
        </property>
        <property name="alternatingRowColors">
         <bool>true</bool>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
    <widget class="QGroupBox" name="groupBox_2">
     <property name="title">
      <string>PlainTextEdit</string>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout_2">
      <property name="leftMargin">
       <number>4</number>
      </property>
      <property name="topMargin">
       <number>4</number>
      </property>
      <property name="rightMargin">
       <number>4</number>
      </property>
      <property name="bottomMargin">
       <number>4</number>
      </property>
      <item>
       <widget class="QPlainTextEdit" name="plainTextEdit">
        <property name="lineWrapMode">
         <enum>QPlainTextEdit::NoWrap</enum>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>687</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <property name="toolButtonStyle">
    <enum>Qt::ToolButtonTextUnderIcon</enum>
   </property>
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
   <addaction name="actOpen"/>
   <addaction name="actSave"/>
   <addaction name="actModelData"/>
   <addaction name="separator"/>
   <addaction name="actAppend"/>
   <addaction name="actInsert"/>
   <addaction name="actDelete"/>
   <addaction name="separator"/>
   <addaction name="actAlignLeft"/>
   <addaction name="actAlignCenter"/>
   <addaction name="actAlignRight"/>
   <addaction name="actFontBold"/>
   <addaction name="separator"/>
   <addaction name="actExit"/>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actOpen">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/open.bmp</normaloff>:/images/icons/open.bmp</iconset>
   </property>
   <property name="text">
    <string>打开文件</string>
   </property>
   <property name="toolTip">
    <string>打开文件</string>
   </property>
  </action>
  <action name="actSave">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/save.bmp</normaloff>:/images/icons/save.bmp</iconset>
   </property>
   <property name="text">
    <string>另存文件</string>
   </property>
   <property name="toolTip">
    <string>表格内容另存为文件</string>
   </property>
  </action>
  <action name="actAppend">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/append.bmp</normaloff>:/images/icons/append.bmp</iconset>
   </property>
   <property name="text">
    <string>添加行</string>
   </property>
   <property name="toolTip">
    <string>添加一行</string>
   </property>
  </action>
  <action name="actInsert">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/306.bmp</normaloff>:/images/icons/306.bmp</iconset>
   </property>
   <property name="text">
    <string>插入行</string>
   </property>
   <property name="toolTip">
    <string>插入一行</string>
   </property>
  </action>
  <action name="actDelete">
   <property name="enabled">
    <bool>false</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/delete.bmp</normaloff>:/images/icons/delete.bmp</iconset>
   </property>
   <property name="text">
    <string>删除行</string>
   </property>
   <property name="toolTip">
    <string>删除当前行</string>
   </property>
  </action>
  <action name="actExit">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/exit.bmp</normaloff>:/images/icons/exit.bmp</iconset>
   </property>
   <property name="text">
    <string>退出</string>
   </property>
   <property name="toolTip">
    <string>退出</string>
   </property>
  </action>
  <action name="actModelData">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/import1.bmp</normaloff>:/images/icons/import1.bmp</iconset>
   </property>
   <property name="text">
    <string>模型数据预览</string>
   </property>
   <property name="toolTip">
    <string>模型数据显示到文本框里</string>
   </property>
  </action>
  <action name="actAlignLeft">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/508.bmp</normaloff>:/images/icons/508.bmp</iconset>
   </property>
   <property name="text">
    <string>居左</string>
   </property>
   <property name="toolTip">
    <string>文字左对齐</string>
   </property>
  </action>
  <action name="actAlignCenter">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/510.bmp</normaloff>:/images/icons/510.bmp</iconset>
   </property>
   <property name="text">
    <string>居中</string>
   </property>
   <property name="toolTip">
    <string>文字居中</string>
   </property>
  </action>
  <action name="actAlignRight">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/512.bmp</normaloff>:/images/icons/512.bmp</iconset>
   </property>
   <property name="text">
    <string>居右</string>
   </property>
   <property name="toolTip">
    <string>文字右对齐</string>
   </property>
  </action>
  <action name="actFontBold">
   <property name="checkable">
    <bool>true</bool>
   </property>
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/icons/500.bmp</normaloff>:/images/icons/500.bmp</iconset>
   </property>
   <property name="text">
    <string>粗体</string>
   </property>
   <property name="toolTip">
    <string>粗体字体</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources>
  <include location="res.qrc"/>
 </resources>
 <connections>
  <connection>
   <sender>actExit</sender>
   <signal>triggered()</signal>
   <receiver>MainWindow</receiver>
   <slot>close()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>-1</x>
     <y>-1</y>
    </hint>
    <hint type="destinationlabel">
     <x>433</x>
     <y>266</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

4-2、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include    <QLabel>
#include    <QStandardItemModel>
#include    <QItemSelectionModel>

#include    "qwintspindelegate.h"
#include    "qwfloatspindelegate.h"

#include    "qwcomboboxdelegate.h"


#define     FixedColumnCount    6       //文件固定6行

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
private:

//用于状态栏的信息显示
    QLabel  *LabCurFile;  //当前文件
    QLabel  *LabCellPos;    //当前单元格行列号
    QLabel  *LabCellText;   //当前单元格内容

    QWIntSpinDelegate    intSpinDelegate; //整型数
    QWFloatSpinDelegate  floatSpinDelegate; //浮点数
    QWComboBoxDelegate   comboBoxDelegate; //列表选择

    QString fCurFile;//当前文件名

    QStandardItemModel  *theModel;//数据模型
    QItemSelectionModel *theSelection;//Item选择模型

    void    iniModelFromStringList(QStringList&);//从StringList初始化数据模型

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_currentChanged(const QModelIndex &current, const QModelIndex &previous);

    void on_actOpen_triggered(); //打开文件

    void on_actAppend_triggered(); //添加行

    void on_actInsert_triggered();//插入行

    void on_actDelete_triggered();//删除行

    void on_actModelData_triggered();  //到处模型数据

    void on_actSave_triggered();//保存文件

    void on_actAlignCenter_triggered();

    void on_actFontBold_triggered(bool checked);

    void on_actAlignLeft_triggered();

    void on_actAlignRight_triggered();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

4-3、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include    <QFileDialog>
#include    <QTextStream>


void MainWindow::iniModelFromStringList(QStringList& aFileContent)
{ //从一个StringList 获取数据,初始化Model
    int rowCnt=aFileContent.count(); // 第1行是标题头,
    theModel->setRowCount(rowCnt-1); //数据行数

    QString header,aLineText;
    QStandardItem   *aItem;
    QStringList     headerList,tmpList;

//设置表头
    header=aFileContent.at(0);//第1行是表头
    headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);//一个或多个空格、TAB等分隔符隔开的字符串
    theModel->setHorizontalHeaderLabels(headerList); //设置表头文字

//设置表格数据
    int i,j;
    for (i=1;i<rowCnt;i++)
    {
        aLineText=aFileContent.at(i); //获取stringList的一行
        tmpList=aLineText.split(QRegExp("\\s+"),QString::SkipEmptyParts);//一个或多个空格、TAB等分隔符隔开的字符串分解为多个字符串
        for (j=0;j<FixedColumnCount-1;j++)
        {
            aItem=new QStandardItem(tmpList.at(j));//创建item
            theModel->setItem(i-1,j,aItem); //为模型的某个行列位置设置Item
        }
        aItem=new QStandardItem(headerList.at(j));//最后一列是Checkable,设置
        aItem->setCheckable(true);
        if (tmpList.at(j)=="0")
            aItem->setCheckState(Qt::Unchecked);
        else
            aItem->setCheckState(Qt::Checked);
        theModel->setItem(i-1,j,aItem); //为模型的某个行列位置设置Item
    }
}


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    theModel = new QStandardItemModel(2,FixedColumnCount,this); //创建数据模型
    theSelection = new QItemSelectionModel(theModel);//Item选择模型
    connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));

    //为tableView设置数据模型
    ui->tableView->setModel(theModel); //设置数据模型
    ui->tableView->setSelectionModel(theSelection);//设置选择模型

//为各列设置自定义代理组件
    ui->tableView->setItemDelegateForColumn(0,&intSpinDelegate);  //测深,整数
    ui->tableView->setItemDelegateForColumn(1,&floatSpinDelegate);  //浮点数
    ui->tableView->setItemDelegateForColumn(2,&floatSpinDelegate); //浮点数
    ui->tableView->setItemDelegateForColumn(3,&floatSpinDelegate); //浮点数
    ui->tableView->setItemDelegateForColumn(4,&comboBoxDelegate); //Combbox选择型

    setCentralWidget(ui->splitter); //

//创建状态栏组件
    LabCurFile = new QLabel("当前文件:",this);
    LabCurFile->setMinimumWidth(300);

    LabCellPos = new QLabel("当前单元格:",this);
    LabCellPos->setMinimumWidth(180);
    LabCellPos->setAlignment(Qt::AlignHCenter);

    LabCellText = new QLabel("单元格内容:",this);
    LabCellText->setMinimumWidth(200);

    ui->statusBar->addWidget(LabCurFile);
    ui->statusBar->addWidget(LabCellPos);
    ui->statusBar->addWidget(LabCellText);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
    Q_UNUSED(previous);
    if (current.isValid())
    {
        LabCellPos->setText(QString::asprintf("当前单元格:%d行,%d列",
                                  current.row(),current.column()));
        QStandardItem   *aItem;
        aItem=theModel->itemFromIndex(current); //从模型索引获得Item
        this->LabCellText->setText("单元格内容:"+aItem->text());

        QFont   font=aItem->font();
        ui->actFontBold->setChecked(font.bold());
    }
}

void MainWindow::on_actOpen_triggered()
{
    QString curPath,aFileName,str;
    curPath=QCoreApplication::applicationDirPath(); //获取应用程序的路径
//调用打开文件对话框打开一个文件
    aFileName=QFileDialog::getOpenFileName(this,tr("打开一个文件"),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())
        {
            str=aStream.readLine();//读取文件的一行
            ui->plainTextEdit->appendPlainText(str); //添加到文本框显示
            fFileContent.append(str); //添加到StringList
        }
        aFile.close();

        this->LabCurFile->setText("当前文件:"+aFileName);
        ui->actAppend->setEnabled(true);
        ui->actInsert->setEnabled(true);
        ui->actDelete->setEnabled(true);
        ui->actSave->setEnabled(true);

        iniModelFromStringList(fFileContent);//初始化数据模型
    }
}

void MainWindow::on_actAppend_triggered()
{ //添加行
    QList<QStandardItem*>    aItemList; //容器类
    QStandardItem   *aItem;
    QString str;
    for(int i=0;i<FixedColumnCount-2;i++)
    {
        aItem=new QStandardItem("0"); //创建Item
        aItemList<<aItem;   //添加到容器
    }
    aItem=new QStandardItem("优"); //创建Item
    aItemList<<aItem;   //添加到容器

    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_actInsert_triggered()
{//插入行
    QList<QStandardItem*>    aItemList;  //QStandardItem的容器类
    QStandardItem   *aItem;
    QString str;
    for(int i=0;i<FixedColumnCount-2;i++)
    {
        aItem=new QStandardItem("0"); //新建一个QStandardItem
        aItemList<<aItem;//添加到容器类
    }
    aItem=new QStandardItem("优"); //新建一个QStandardItem
    aItemList<<aItem;//添加到容器类

    str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    aItem=new QStandardItem(str); //创建Item
    aItem->setCheckable(true);
    aItemList<<aItem;//添加到容器类
    QModelIndex curIndex=theSelection->currentIndex();
    theModel->insertRow(curIndex.row(),aItemList);
    theSelection->clearSelection();
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}

void MainWindow::on_actDelete_triggered()
{ //删除行
    QModelIndex curIndex=theSelection->currentIndex();
    if (curIndex.row()==theModel->rowCount()-1)//(curIndex.isValid())
        theModel->removeRow(curIndex.row());
    else
    {
        theModel->removeRow(curIndex.row());
        theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
    }
}

void MainWindow::on_actModelData_triggered()
{//模型数据导出到PlainTextEdit显示
    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";
    }
    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,aFileName;
    curPath=QCoreApplication::applicationDirPath(); //获取应用程序的路径
//调用打开文件对话框选择一个文件
    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";
    }
    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";
    }
}

void MainWindow::on_actAlignCenter_triggered()
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignHCenter);
    }
}

void MainWindow::on_actFontBold_triggered(bool checked)
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;
    QFont   font;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        font=aItem->font();
        font.setBold(checked);
        aItem->setFont(font);
    }

}

void MainWindow::on_actAlignLeft_triggered()
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignLeft);
    }
}

void MainWindow::on_actAlignRight_triggered()
{
    if (!theSelection->hasSelection())
        return;

    QModelIndexList selectedIndix=theSelection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem   *aItem;

    for (int i=0;i<selectedIndix.count();i++)
    {
        aIndex=selectedIndix.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignRight);
    }
}

4-4、qwcomboboxdelegate.h

#ifndef QWCOMBOBOXDELEGATE_H
#define QWCOMBOBOXDELEGATE_H

#include    <QItemDelegate>

class QWComboBoxDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    QWComboBoxDelegate(QObject *parent=0);

//自定义代理组件必须继承以下4个函数
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const Q_DECL_OVERRIDE;

    void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const Q_DECL_OVERRIDE;
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const Q_DECL_OVERRIDE;
};

#endif // QWCOMBOBOXDELEGATE_H

4-5、qwcomboboxdelegate.cpp

#include "qwcomboboxdelegate.h"

#include    <QComboBox>

QWComboBoxDelegate::QWComboBoxDelegate(QObject *parent):QItemDelegate(parent)
{

}

QWidget *QWComboBoxDelegate::createEditor(QWidget *parent,
       const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QComboBox *editor = new QComboBox(parent);

    editor->addItem("优");
    editor->addItem("良");
    editor->addItem("一般");
    editor->addItem("不合格");

    return editor;
}

void QWComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QString str = index.model()->data(index, Qt::EditRole).toString();

    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    comboBox->setCurrentText(str);
}

void QWComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QComboBox *comboBox = static_cast<QComboBox*>(editor);

    QString str = comboBox->currentText();

    model->setData(index, str, Qt::EditRole);
}

void QWComboBoxDelegate::updateEditorGeometry(QWidget *editor,
                const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

4-6、qwfloatspindelegate.h

#ifndef QWFLOATSPINDELEGATE_H
#define QWFLOATSPINDELEGATE_H

#include    <QObject>
#include    <QWidget>
#include    <QStyledItemDelegate>

class QWFloatSpinDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    QWFloatSpinDelegate(QObject *parent=0);

//自定义代理组件必须继承以下4个函数
//创建编辑组件
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const Q_DECL_OVERRIDE;

    void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const Q_DECL_OVERRIDE;
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const Q_DECL_OVERRIDE;
};

#endif // QWFLOATSPINDELEGATE_H

4-7、qwfloatspindelegate.cpp

#include "qwfloatspindelegate.h"

#include  <QDoubleSpinBox>

QWFloatSpinDelegate::QWFloatSpinDelegate(QObject *parent):QStyledItemDelegate(parent)
{

}

QWidget *QWFloatSpinDelegate::createEditor(QWidget *parent,
   const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option);
    Q_UNUSED(index);

    QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
    editor->setFrame(false);
    editor->setMinimum(0);
    editor->setDecimals(2);
    editor->setMaximum(10000);

    return editor;
}

void QWFloatSpinDelegate::setEditorData(QWidget *editor,
                      const QModelIndex &index) const
{
    float value = index.model()->data(index, Qt::EditRole).toFloat();
    QDoubleSpinBox *spinBox = static_cast<QDoubleSpinBox*>(editor);
    spinBox->setValue(value);
}

void QWFloatSpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QDoubleSpinBox *spinBox = static_cast<QDoubleSpinBox*>(editor);
    spinBox->interpretText();
    float value = spinBox->value();
    QString str=QString::asprintf("%.2f",value);

    model->setData(index, str, Qt::EditRole);
}

void QWFloatSpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

4-8、qwintspindelegate.h

#ifndef QWINTSPINDELEGATE_H
#define QWINTSPINDELEGATE_H

//#include    <QObject>
//#include    <QWidget>
#include    <QStyledItemDelegate>

class QWIntSpinDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    QWIntSpinDelegate(QObject *parent=0);

//自定义代理组件必须继承以下4个函数

//创建编辑组件
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const Q_DECL_OVERRIDE;

//从数据模型获取数据,显示到代理组件中
    void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;

//将代理组件的数据,保存到数据模型中
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const Q_DECL_OVERRIDE;

//更新代理编辑组件的大小
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const Q_DECL_OVERRIDE;
};

#endif // QWINTSPINDELEGATE_H

4-9、qwintspindelegate.cpp

#include "qwintspindelegate.h"

#include    <QSpinBox>

QWIntSpinDelegate::QWIntSpinDelegate(QObject *parent):QStyledItemDelegate(parent)
{

}

QWidget *QWIntSpinDelegate::createEditor(QWidget *parent,
   const QStyleOptionViewItem &option, const QModelIndex &index) const
{ //创建代理编辑组件
    Q_UNUSED(option);
    Q_UNUSED(index);

    QSpinBox *editor = new QSpinBox(parent); //创建一个QSpinBox
    editor->setFrame(false); //设置为无边框
    editor->setMinimum(0);
    editor->setMaximum(10000);

    return editor;  //返回此编辑器
}

void QWIntSpinDelegate::setEditorData(QWidget *editor,
                      const QModelIndex &index) const
{//从数据模型获取数据,显示到代理组件中
//获取数据模型的模型索引指向的单元的数据
    int value = index.model()->data(index, Qt::EditRole).toInt();

    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);  //强制类型转换
    spinBox->setValue(value); //设置编辑器的数值
}

void QWIntSpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{ //将代理组件的数据,保存到数据模型中
    QSpinBox *spinBox = static_cast<QSpinBox*>(editor); //强制类型转换
    spinBox->interpretText(); //解释数据,如果数据被修改后,就触发信号
    int value = spinBox->value(); //获取spinBox的值

    model->setData(index, value, Qt::EditRole); //更新到数据模型
}

void QWIntSpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ //设置组件大小
    Q_UNUSED(index);
    editor->setGeometry(option.rect);
}

源码地址https://download.csdn.net/download/qq_30457077/85075848

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中的Model/View是一种基于MVC(Model-View-Controller)设计模式的实现方式。Model/View架构将数据的存储和显示分离开来,使得程序的结构更加清晰,并且可以提高程序的可维护性和可扩展性。 在Qt中,Model/View是面向对象的。它由三个基础类组成:QAbstractItemModel、QAbstractTableModel和QAbstractListModel。QAbstractItemModel为QAbstractTableModel和QAbstractListModel提供了接口规范,使用它可以将数据模型与View分离开来。QAbstractTableModel主要为表格型数据模型定义了一套标准。QAbstractListModel与之类似,为列表型数据模型定义了一套标准。 在Model/View中,Model提供了从数据源中获取数据并将其封装成数据项及其属性的方式。而View根据Model提供的数据项及其属性,对其进行可视化展示。对于数据的修改和删除等操作,则通过View传递给Model来进行实现。 Model的数据来源可以是任何类型的数据,例如数据库、XML文件、内存中的数据等等。ModelView之间的通信是通过信号和槽机制来实现的。当Model的数据发生变化时,它会发出数据变化的信号,View会从这些信号中得知数据发生了哪些改变,然后对其进行更新。 Model/View提供了一种灵活、高效、可扩展的方案来处理数据。在Qt中,开发者可以使用其提供的各种ModelView类,或者继承这些类来实现自己的数据模型和视图类,以便更好地满足自己的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值