品牌网站建设的要点,网站推广优化方法,大连里程科技做网站,手机屏幕网站一、Model/View结构
数据#xff1a;如数据库的一个数据表或者SQL查询结果#xff0c;如内存中的数据类对象#xff0c;或者磁盘文件结构等Model#xff1a;与数据通信#xff0c;并作为视图组件提供数据接口View#xff1a;屏幕界面组件#xff0c;视图从数据模型获得…一、Model/View结构
数据如数据库的一个数据表或者SQL查询结果如内存中的数据类对象或者磁盘文件结构等Model与数据通信并作为视图组件提供数据接口View屏幕界面组件视图从数据模型获得每个数据项的模型索引通过数据模型索引model index获取数据代理定制数据的界面或编辑方式在标准的视图组件中代理功能显示一个数据当数据被编辑时提供一个编辑器一般时QLineEdit。
模型、视图和代理之间使用信号和槽通信
1、数据模型
QStringListModel用于处理字符串列表数据的数据模型类QStandardItemModel标准的基于数据项的数据模型类每个数据项都可以是任何数据类型QFileSystemModel计算机上文件系统的数据模型类QSortFilterProxyModel与其他数据模型结合提供排序和过滤功能的数据类型模型类QSelQueryModel用于数据库SQL查询结果的数据模型类QSqlTableModel用于数据库的一个数据表的数据模型类QSqlRelationTableModel用于关系类型数据表的数据模型
继承关系
QAbstractItemmodelQAbstractListModelQStringListModelQAbstractProxyModelQSortFilterProxyModelQAbstractTableModelQSqlQueryModelQSlTableModelQSlRelationTableModelQStandardItemModelQFileSystemModel2、视图组件
显示数据时只需要调用视图类的setModel()函数QAbstractItemViewQListViewQListWidgetQTableViewQTableWidgetQTreeViewQTreeWidgetQColumnViewQHeaderView3、代理
代理时在视图组件上为编辑数据提供编辑器QAbstractItemDeleget是所有代理类的基类。二、QFileSystemModel
如Windows则资源管理器使用QFileSystemModel童工的接口函数可以创建目录、删除目录、重命名目录可以获得文件名称、目录名称、文件大小等参数还可以获取文件的详细信息。1、实现工具
1创建项目基于QMainWindow
2添加组件 3实现功能
#include mainwindow.h
#include ui_mainwindow.hMainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui-setupUi(this);fileModel new QFileSystemModel(this);fileModel-setRootPath(QDir::currentPath());ui-treeView-setModel(fileModel);ui-listView-setModel(fileModel);ui-tableView-setModel(fileModel);ui-tableView-verticalHeader()-setVisible(false);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-labelName-setText(fileModel-fileName(index));unsigned int sz fileModel-size(index)/1024;if(sz 1024){ui-labelSize-setText(QString::asprintf(%d KB, sz));}else{ui-labelSize-setText(QString::asprintf(%.2f MB, (float)sz/1024));}ui-labelType-setText(fileModel-type(index));ui-labelPath-setText(fileModel-filePath(index));ui-checkBox-setChecked(fileModel-isDir(index));
}三、QStringListModel
1、实现工具
1创建项目基于Widget
2添加组件 3添加功能
#include widget.h
#include ui_widget.hWidget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui-setupUi(this);theModel new QStringListModel(this);QStringList strList;strListItem1Item2Item3Item4Item5Item6;theModel-setStringList(strList);ui-listView-setModel(theModel);// 编辑双击或者选择项单击ui-listView-setEditTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::SelectedClicked);
}Widget::~Widget()
{delete ui;
}void Widget::on_btnDisplay_clicked()
{QStringList strList theModel-stringList();foreach (auto str, strList) {ui-plainTextEdit-appendPlainText(str);}
}void Widget::on_btnClear_clicked()
{ui-plainTextEdit-clear();
}void Widget::on_btnInitList_clicked()
{QStringList strList;strListItem1Item2Item3Item4Item5Item6;theModel-setStringList(strList);
}void Widget::on_btnListClear_clicked()
{theModel-removeRows(0, theModel-rowCount());
}void Widget::on_btnListDelete_clicked()
{theModel-removeRow(ui-listView-currentIndex().row());
}void Widget::on_btnListAppend_clicked()
{theModel-insertRow(theModel-rowCount());QModelIndex index theModel-index(theModel-rowCount()-1, 0); // 添加之后count会加一theModel-setData(index, new Item, Qt::DisplayRole);ui-listView-setCurrentIndex(index);
}void Widget::on_btnInsert_clicked()
{theModel-insertRow(ui-listView-currentIndex().row());QModelIndex index theModel-index(ui-listView-currentIndex().row()-1, 0); // 插入之后count会加一theModel-setData(index, insert Item, Qt::DisplayRole);ui-listView-setCurrentIndex(index);
}void Widget::on_listView_clicked(const QModelIndex index)
{ui-label-setText(QString::asprintf(行%d列%d, index.row(), index.column()));
}四、QStandardItemModel
以项数据为基础的标准数据模型类通常与QTableView组合成为Model/View结构实现通用的二位数据管理功能。QStandardItemModel可以处理二维数。每一项是一个QStandardItem类的变量用于存储项的数据、字体格式、对其方式等QTableView一个单元格显示QStandardItemModel数据模型中的一项。QItemSelectionModel跟踪视图组件的单元格选择状态的类通过QItemSelectionModel可以获得选中的单元格的模型索引。
1、实现工具
1创建项目基于QMainWindow
2添加图标资源文件、添加组件 3设置文本不自动换行 4设置信号与槽
#include mainwindow.h
#include ui_mainwindow.hMainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui-setupUi(this);labCurrFile new QLabel(当前文件, this);labCellPos new QLabel(当前单元格, this);labCellText new QLabel(单元格内容, this);theModel new QStandardItemModel(10, fixedColoumCount,this);theSelection new QItemSelectionModel(theModel);ui-tableView-setModel(theModel);ui-tableView-setSelectionModel(theSelection);labCurrFile-setMinimumWidth(200);labCellPos-setMinimumWidth(150);labCellText-setMinimumWidth(200);ui-statusBar-addWidget(labCurrFile);ui-statusBar-addWidget(labCellPos);ui-statusBar-addWidget(labCellText);connect(theSelection, SIGNAL(currentChanged(QModelIndex,QModelIndex)),this, SLOT(on_currentChanged(QModelIndex,QModelIndex)));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_currentChanged(const QModelIndex current, const QModelIndex previous)
{Q_UNUSED(previous)if(! current.isValid()){return;}QStandardItem *item theModel-itemFromIndex(current);labCellPos-setText(QString::asprintf(当前单元格%d行%d列, current.row(), current.column()));labCellText-setText(单元格内容item-text());QFont font item-font();ui-actFontBold-setChecked(font.bold());
}void MainWindow::initModelFromStringList(QStringList fileContent)
{theModel-setRowCount(fileContent.count()-1);// 表头QString header fileContent.at(0);QStringList headerList header.split(,);theModel-setHorizontalHeaderLabels(headerList);// 表格数据int col;QStandardItem *item;for (int row 1; row fileContent.count(); row) {QString lineText fileContent.at(row);QStringList colList lineText.split(,);for (col 0; col fixedColoumCount-1; col) {item new QStandardItem(colList.at(col));theModel-setItem(row-1, col, item);}item new QStandardItem(headerList.at(col));if(colList.at(col) 1){item-setCheckState(Qt::Checked);}else{item-setCheckState(Qt::Unchecked);}theModel-setItem(row-1, col, item);}
}#include QFileDialog
#include QFile
#include QTextStream
void MainWindow::on_actOpen_triggered()
{QString strCurrPath QCoreApplication::applicationDirPath();QString strFileName QFileDialog::getOpenFileName(this, 打开一个文件,strCurrPath, 数据文件(*.txt);;所有文件(*.*));if(strFileName.isEmpty()){return;}QStringList fileContent;QFile file(strFileName);if(file.open(QIODevice::ReadOnly|QIODevice::Text)){QTextStream stream(file);ui-plainTextEdit-clear();while (!stream.atEnd()) {QString str stream.readLine();ui-plainTextEdit-appendPlainText(str);if(!str.isEmpty()){fileContent.append(str);}}file.close();this-labCurrFile-setText(当前文件strFileName);initModelFromStringList(fileContent);ui-tableView-resizeColumnsToContents();ui-tableView-resizeRowsToContents();ui-actSave-setEnabled(true);ui-actAppend-setEnabled(true);ui-actDelete-setEnabled(true);ui-actInsert-setEnabled(true);}
}void MainWindow::on_actSave_triggered()
{QString strCurrPath QCoreApplication::applicationDirPath();QString strFileName QFileDialog::getSaveFileName(this, 另存为文件,strCurrPath, 数据文件(*.txt);;所有文件(*.*));if(strFileName.isEmpty()){return;}QStringList fileContent;QFile file(strFileName);if(file.open(QIODevice::ReadWrite|QIODevice::Text|QIODevice::Truncate)){QTextStream stream(file);ui-plainTextEdit-clear();QString str;int i;for (i 0; i theModel-columnCount()-1; i) {QStandardItem *item theModel-horizontalHeaderItem(i);str item-text(),;}QStandardItem *item theModel-horizontalHeaderItem(i);str item-text();streamstr\n;ui-plainTextEdit-appendPlainText(str);int j;for (int i 0; i theModel-rowCount(); i) {str ;for (j 0; j theModel-columnCount()-1; j) {QStandardItem *item theModel-item(i,j);str item-text(),;}QStandardItem *item theModel-item(i,j);if(item-checkState() Qt::Checked){str 1;}else{str 0;}streamstr\n;ui-plainTextEdit-appendPlainText(str);}file.close();}
}void MainWindow::on_actModelData_triggered()
{ui-plainTextEdit-clear();QString str;for (int i 0; i theModel-columnCount(); i) {QStandardItem *item theModel-horizontalHeaderItem(i);str item-text(),;}ui-plainTextEdit-appendPlainText(str);int j;for (int i 0; i theModel-rowCount(); i) {str ;for (j 0; j theModel-columnCount()-1; j) {QStandardItem *item theModel-item(i,j);str item-text(),;}QStandardItem *item theModel-item(i,j);if(item-checkState() Qt::Checked){str 1;}else{str 0;}ui-plainTextEdit-appendPlainText(str);}
}void MainWindow::on_actAppend_triggered()
{QListQStandardItem* itemList;QStandardItem *item;for (int i 0; i fixedColoumCount-1; i) {item new QStandardItem(0);itemList item;}QString str theModel-headerData(theModel-columnCount()-1,Qt::Horizontal, Qt::DisplayRole).toString();item new QStandardItem(str);item-setCheckState(Qt::Checked);itemList item;theModel-appendRow(itemList);theSelection-clearSelection();QModelIndex index theModel-index(theModel-rowCount()-1, 0);theSelection-setCurrentIndex(index, QItemSelectionModel::Select);
}void MainWindow::on_actInsert_triggered()
{QListQStandardItem* itemList;QStandardItem *item;for (int i 0; i fixedColoumCount-1; i) {item new QStandardItem(0);itemList item;}QString str theModel-headerData(theModel-columnCount()-1,Qt::Horizontal, Qt::DisplayRole).toString();item new QStandardItem(str);item-setCheckState(Qt::Checked);itemList item;theModel-insertRow(theSelection-currentIndex().row(), itemList);theSelection-clearSelection();QModelIndex index theModel-index(theSelection-currentIndex().row(), 0);theSelection-setCurrentIndex(index, QItemSelectionModel::Select);
}void MainWindow::on_actDelete_triggered()
{if(theSelection-currentIndex().row() theModel-rowCount()-1){theModel-removeRow(theSelection-currentIndex().row());}else{theModel-removeRow(theSelection-currentIndex().row());QModelIndex index theModel-index(theSelection-currentIndex().row(), 0);theSelection-setCurrentIndex(index, QItemSelectionModel::Select);}}void MainWindow::on_actAlignLeft_triggered()
{if(!theSelection-hasSelection()){return;}QModelIndexList selectedIndexes theSelection-selectedIndexes();for (int i 0; i selectedIndexes.count(); i) {QModelIndex index selectedIndexes.at(i);QStandardItem *item theModel-itemFromIndex(index);item-setTextAlignment(Qt::AlignLeft);}
}void MainWindow::on_actAlignCenter_triggered()
{if(!theSelection-hasSelection()){return;}QModelIndexList selectedIndexes theSelection-selectedIndexes();for (int i 0; i selectedIndexes.count(); i) {QModelIndex index selectedIndexes.at(i);QStandardItem *item theModel-itemFromIndex(index);item-setTextAlignment(Qt::AlignCenter);}
}void MainWindow::on_actAlignRight_triggered()
{if(!theSelection-hasSelection()){return;}QModelIndexList selectedIndexes theSelection-selectedIndexes();for (int i 0; i selectedIndexes.count(); i) {QModelIndex index selectedIndexes.at(i);QStandardItem *item theModel-itemFromIndex(index);item-setTextAlignment(Qt::AlignRight);}
}void MainWindow::on_actFontBold_triggered(bool checked)
{if(!theSelection-hasSelection()){return;}QModelIndexList selectedIndexes theSelection-selectedIndexes();for (int i 0; i selectedIndexes.count(); i) {QModelIndex index selectedIndexes.at(i);QStandardItem *item theModel-itemFromIndex(index);QFont font item-font();font.setBold(checked);item-setFont(font);}
}五、自定义代理
代理是介于Model和View之间主要用于数据修改。QAbstractItemDelegate所有代理类的查抽象基类QStyledItemDelegatte视图组件使用的缺省的代理类可以使用当前样式表设置来绘制组件建议使用此类QItemDelegate类似与QStyledItemDelegate不支持使用当前样式绘制组件
QAbstractItemDelegateQStyledItemDelegateQItemDelegateQSqlRelationalDelegate必须实现以下几个函数createEditor()创建用于编辑模型数据的widget组件setEditorData()从数据模型获取数据供widget组件进行编辑setModelData()将widget上的数据更新到数据模型updateEditorGeometry()用于给widget组件设置一个合适的大小
1、实现功能 1拷贝上一个项目
2添加类 3实现类功能
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui-setupUi(this);labCurrFile new QLabel(当前文件, this);labCellPos new QLabel(当前单元格, this);labCellText new QLabel(单元格内容, this);theModel new QStandardItemModel(10, fixedColoumCount,this);theSelection new QItemSelectionModel(theModel);ui-tableView-setModel(theModel);ui-tableView-setSelectionModel(theSelection);labCurrFile-setMinimumWidth(200);labCellPos-setMinimumWidth(150);labCellText-setMinimumWidth(200);ui-statusBar-addWidget(labCurrFile);ui-statusBar-addWidget(labCellPos);ui-statusBar-addWidget(labCellText);ui-tableView-setItemDelegateForColumn(0, intSpinDelegate); //给0列设置代理connect(theSelection, SIGNAL(currentChanged(QModelIndex,QModelIndex)),this, SLOT(on_currentChanged(QModelIndex,QModelIndex)));
}#include qintdelegate.h
#include QSpinBox
QIntDelegate::QIntDelegate()
{}QWidget *QIntDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem option, const QModelIndex index) const
{Q_UNUSED(index)Q_UNUSED(option)QSpinBox *edit new QSpinBox(parent);edit-setMinimum(0);edit-setMaximum(1000);edit-setFrame(false); //无边框return edit;
}void QIntDelegate::setEditorData(QWidget *editor, const QModelIndex index) const
{int value index.model()-data(index, Qt::EditRole).toInt();QSpinBox *spinBox static_castQSpinBox*(editor);spinBox-setValue(value);
}void QIntDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex index) const
{QSpinBox *spinBox static_castQSpinBox*(editor);spinBox-interpretText(); // 确保获得的是最新更新的数据int value spinBox-value();model-setData(index, value, Qt::EditRole);
}void QIntDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem option, const QModelIndex index) const
{Q_UNUSED(index)editor-setGeometry(option.rect);
}