#include "mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* 新建一个QDirModel对象,对数据访问做准备,QDirModel的创建还可以设置过滤器,即只有符合条件的文件或目录才能被访问
* QDirModel类继承自QAbstractItemModel类,为访问本地文件系统提供数据模型,它提供了新建、删除、创建目录等一系列与
* 文件操作相关的函数,此处只是用来显示本地文件系统
*
* 新建三种不同的View对象,以便文件目录可以以三种不同的方式显示
*
* tree.setModel(&model):调用setModel()函数设置View对象的Model为QDirModel对象的model。
*
* tree.setSelectionMode (QAbstractItemView::MultiSelection):设置QTreeView对象的选择方式为多选
*
*list.setSelectionModel (tree.selectionModel ()):设置QListView对象与QTreeView对象使用相同的选择类型
*
* 为了实现双击QTreeView对象中的某个目录时,QListView对象和QTableView对象中显示此选定目录下的所有文件和目录,
* 需要链接QTreeView对象的doubleClicked()信号与QListView对象和QTableView对象的setRootIndex()槽函数
*/
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDirModel model;
QTreeView tree;
QListView list;
QTableView table;
tree.setModel (&model);
list.setModel (&model);
table.setModel (&model);
tree.setSelectionMode (QAbstractItemView::MultiSelection);
list.setSelectionModel (tree.selectionModel ());
table.setSelectionModel (tree.selectionModel ());
QObject::connect (&tree, SIGNAL(doubleClicked(QModelIndex)),
&list, SLOT(setRootIndex(QModelIndex)));
QObject::connect (&tree, SIGNAL(doubleClicked(QModelIndex)),
&table, SLOT(setRootIndex(QModelIndex)));
QSplitter *spliter = new QSplitter;
spliter->addWidget (&tree);
spliter->addWidget (&list);
spliter->addWidget (&table);
spliter->setWindowTitle (QObject::tr ("Model/View"));
spliter->show();
return a.exec();
}
常量
|
描述
|
Qt::DisplayRole |
显示文字
|
Qt::DecorationRole
|
绘制装饰数据(通常是图标) |
Qt::EditRole | 在编辑器中编辑的数据 |
Qt::ToolTipRole |
工具提示
|
Qt::StatusTipRole
|
状态栏提示
|
Qt::WhatsThisRole
|
What's This文字
|
Qt::SizeHintRole
|
尺寸提示
|
Qt::FontRole
|
默认代理的绘制使用的字体 |
Qt::TextAlignmentRole | 默认代理的对齐方式 |
Qt::BackgroundRole
|
默认代理的背景画刷 |
Qt::ForegroundRole | 默认代理的前景画刷 |
Qt::CheckStateRole |
默认代理的检查框状态
|
Qt::UserRole
|
用户自定义的数据的起始位置 |
#ifndef MODELEX_H
#define MODELEX_H
#include
#include
#include
#include
/*
* QMap提供了一个从类型为Key的键到类型为T的值的映射。
* rowCount()、columnCount()、data()和返回表头数据的headerData()函数
* 是QAbstractTableModel类的纯数函数
*
* 纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,
* 而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用
*/
class ModelEx : public QAbstractTableModel
{
public:
explicit ModelEx(QObject *parent = 0);
virtual int rowCount (const QModelIndex &parent) const;
virtual int columnCount (const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData (int section, Qt::Orientation orientation, int role) const;
signals:
public slots:
private:
QVector<short> army; //定义一个短型军种类型容器
QVector<short> weaponType; //定义一个短型武器类型容器
QMap<short, QString> armyMap; //定义一个从short类型的键值到类型QString的值得映射
QMap<short, QString> weaponTypeMap; //定义一个从short类型的键值到类型QString的值得映射
QStringList weapon; //定义一个字符串武器链表
QStringList header; //定义一个头结点链表
void populateModel(); //完成表格数据的初始化填充
};
#endif // MODELEX_H
#include "modelex.h"
ModelEx::ModelEx(QObject *parent) :
QAbstractTableModel(parent)
{
armyMap[1] = tr("空军");
armyMap[2] = tr("海军");
armyMap[3] = tr("陆军");
armyMap[4] = tr("海军陆战队");
weaponTypeMap[1] = tr("轰炸机");
weaponTypeMap[2] = tr("航空母舰");
weaponTypeMap[3] = tr("直升机");
weaponTypeMap[4] = tr("两栖攻击舰");
weaponTypeMap[5] = tr("驱逐舰");
weaponTypeMap[6] = tr("两栖战舰");
weaponTypeMap[7] = tr("坦克");
weaponTypeMap[8] = tr("战斗机");
populateModel ();
}
void ModelEx::populateModel ()
{
header << tr("军种") << tr("种类") << tr("武器");
army << 1 << 2 << 3 << 4 << 4 << 2 << 3 << 1;
weaponType << 1 << 2 << 3 << 4 <<5 << 6 << 7 << 8;
weapon << tr("B-2") << tr("尼米兹级") << tr("阿帕奇") << tr("黄蜂级")
<< tr("阿利伯克级") << tr("AAAV") << tr("MIAI") << ("F-22");
}
/*
* 返回行
*/
int ModelEx::rowCount (const QModelIndex &parent) const
{
return army.size ();
}
/*
* 返回列
*/
int ModelEx::columnCount (const QModelIndex &parent) const
{
return 3;
}
/*
* QVariant类类似于C++的联合(union)数据类型,它不仅能够保存很多Qt类型的值,包括QColor、QBrush、QFont、
* QPen、QRect、QString和QSize等,也能够存放容器类的值。
* data()函数返回指定索引的数据,即将数值映射为文字
*/
QVariant ModelEx::data (const QModelIndex &index, int role) const
{
if(!index.isValid ())
{
return QVariant();
}
/*Qt::DisplayRole用来存取视图中显示的文字*/
if(role == Qt::DisplayRole)
{
switch(index.column ())
{
case 0:
return armyMap[army[index.row ()]];
break;
case 1:
return weaponTypeMap[weaponType[index.row ()]];
break;
case 2:
return weapon[index.row ()];
break;
default:
return QVariant();
break;
}
}
return QVariant();
}
/*
* headerData()函数返回固定的表头数据,设置水平表头的标题
*/
QVariant ModelEx::headerData (int section, Qt::Orientation orientation, int role) const
{
if(role == Qt::DisplayRole && orientation == Qt::Horizontal)
return header[section];
return QAbstractTableModel::headerData (section, orientation, role);
}
#include
#include "modelex.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ModelEx modelEx;
QTableView view;
view.setModel(&modelEx);
view.setWindowTitle(QObject::tr("modelEx"));
view.resize(400,400);
view.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
#include "histogramview.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
void createAction();
void createMenu();
void setupModel();
void setupView();
void openFile(QString);
private:
QMenu *fileMenu;
QAction *openAct;
QStandardItemModel *model;
QTableView *table;
QSplitter *splitter;
HistogramView *histogram;
public slots:
void slotOpen();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
createAction ();
createMenu ();
setupModel ();
setupView ();
setWindowTitle (tr("View Example"));
resize(600, 660);
}
MainWindow::~MainWindow()
{
}
void MainWindow::createAction ()
{
openAct = new QAction(tr("打开"), this);
connect (openAct, SIGNAL(triggered(bool)), this, SLOT(slotOpen()));
}
/*
* 创建一个文件菜单栏
* 将openAct动作插入到这个菜单栏里
*/
void MainWindow::createMenu ()
{
fileMenu = new QMenu(tr("文件"), this);
fileMenu->addAction(openAct);
menuBar ()->addMenu (fileMenu);
}
void MainWindow::setupModel ()
{
model = new QStandardItemModel(4, 4, this);
model->setHeaderData (0, Qt::Horizontal, tr("部门"));
model->setHeaderData (1, Qt::Horizontal, tr("男"));
model->setHeaderData (2, Qt::Horizontal, tr("女"));
model->setHeaderData (3, Qt::Horizontal, tr("退休"));
}
void MainWindow::setupView ()
{
splitter = new QSplitter;
splitter->setOrientation (Qt::Vertical);
histogram = new HistogramView(splitter);
histogram->setModel (model);
table = new QTableView; //新建一个QTableView对象
table->setModel (model); //为QTableView对象设置相同的Model
/*新建一个QItemSelectModel对象作为QTableView对象使用的选择模型*/
QItemSelectionModel *selectionModel = new QItemSelectionModel(model);
table->setSelectionModel (selectionModel);
histogram->setSelectionModel (selectionModel);
splitter->addWidget (table);
splitter->addWidget (histogram);
setCentralWidget (splitter);
connect (selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), table,
SLOT(selectionChanged(QItemSelection,QItemSelection)));
connect (selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), histogram,
SLOT(selectionChanged(QItemSelection,QItemSelection)));
}
/*
* 打开一个*.txt文件
* 如果文件非空读取文件信息
*/
void MainWindow::slotOpen ()
{
QString name;
name = QFileDialog::getOpenFileName (this, "打开", ".", "histogram files(*.txt)");
if(!name.isEmpty ())
{
openFile (name);
}
}
/*
* 一行行读取*.txt文件内容,当遇到“,”分割数据
* QFile类提供了一个接口,用于读取或写入文件
* QTextStream类可以方便地读取单词、行和数字。
* 在循环中一次读取文件中的一行数据,然后插入到表格对应的一行数据中
*/
void MainWindow::openFile (QString path)
{
if(!path.isEmpty ())
{
QFile file(path);
if(file.open (QFile::ReadOnly | QFile::Text))
{
QTextStream stream(&file);
QString line;
/*从文本中移除一行的数据*/
model->removeRows (0, model->rowCount (QModelIndex()), QModelIndex());
int row = 0;
do
{
line = stream.readLine ();
if(!line.isEmpty ())
{
/*设置一行插入多个数据,一次插入一个数据*/
model->insertRows (row, 1, QModelIndex());
QStringList pieces = line.split (",", QString::SkipEmptyParts);
/*将数据设置到row行、0、1、2、3列*/
model->setData (model->index (row, 0, QModelIndex()), pieces.value (0));
model->setData (model->index (row, 1, QModelIndex()), pieces.value (1));
model->setData (model->index (row, 2, QModelIndex()), pieces.value (2));
model->setData (model->index (row, 3, QModelIndex()), pieces.value (3));
row++;
}
}while(!line.isEmpty ());
file.close ();
}
}
}
#ifndef HISTOGRAMVIEW_H
#define HISTOGRAMVIEW_H
#include
#include
#include
#include
/*
* visualRect (),scrollTo (),indexAt (),moveCursor (),horizontalOffset (),verticalOffset ()
* isIndexHidden (),setSelection ()和visualRegionForSelection ():QAbstractItemView类中的纯虚函数
* 这些纯虚函数不一定要实现,可以根据需要选择性地实现,但一定要声明。
*
* QModelIndex indexAt(const QPoint &point) const:当鼠标在视图中单击或位置发生改变时被触动,它返回鼠标所
* 在点的QModelIndex值。当鼠标处在某一个数据项的区域中,则返回此数据项的Index值,否则返回一个空的Index。
*
* void mousePressEvent (QMouseEvent *event):柱状统计图可以被鼠标单击选择,选中后以不同的方式显示。
*
* selectionChanged (const QItemSelection &selected, const QItemSelection &deselected):当数据项
* 选择发生变化时,此槽函数将响应。
*
* void dataChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight):当模型中的数据发生
* 变更时,此槽函数将响应。
*
* void setSelection (const QRect &rect, QItemSelectionModel::SelectionFlags flags):将位于QRect内
* 的数据项按照SelectionFlags(描述被选择的数据项以何种方式进行更新)指定的方式进行更新。QItemSelectModel类提供
* 多种可用的SelecttionFlags,常用的有QItemSelectModel::Select、QItemSelectModel::Current类。
*
* QItemSelectionModel *selections:用于保存与视图选择项相关的内容。
*
* QListMRegionList:用于保存其中某一类型柱状图的区域范围,而每个区域是QList中的一个值。
*/
class HistogramView : public QAbstractItemView
{
public:
HistogramView(QWidget *parent = 0);
QRect visualRect (const QModelIndex &index) const;
void scrollTo (const QModelIndex &index, ScrollHint hint=EnsureVisible);
QModelIndex indexAt(const QPoint &point) const;
//为selecttions赋初值
void setSelectionModel (QItemSelectionModel *selectionModel);
QRegion itemRegion(QModelIndex index);
void paintEvent (QPaintEvent *);
void mousePressEvent (QMouseEvent *event);
protected slots:
void selectionChanged (const QItemSelection &selected, const QItemSelection &deselected);
void dataChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight);
protected:
QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction,Qt::KeyboardModifiers modifiers);
int horizontalOffset () const;
int verticalOffset () const;
bool isIndexHidden (const QModelIndex &index) const;
void setSelection (const QRect &rect, QItemSelectionModel::SelectionFlags flags);
QRegion visualRegionForSelection (const QItemSelection &selection) const;
private:
QItemSelectionModel *selections;
QList <QRegion> MRegionList;
QList <QRegion> FRegionList;
QList <QRegion> SRegionList;
};
#endif // HISTOGRAMVIEW_H
#include "histogramview.h"
#include
HistogramView::HistogramView(QWidget *parent)
:QAbstractItemView(parent)
{
}
//paintEvent()函数具体完成柱状统计图绘制的工作
void HistogramView::paintEvent (QPaintEvent *)
{
QPainter painter(viewport ()); //将viewport()作为绘图设备新建一个QPainter对象
painter.setPen (Qt::black);
int x0 = 40;
int y0 = 280;
//绘制y轴坐标
painter.drawLine (x0, y0, 40, 18);
painter.drawLine (36, 22, 40, 18);
painter.drawLine (44, 22, 40, 18);
painter.drawText (27, 15, tr("人数"));
for(int i = 0; i <= 5; i++)
{
painter.drawLine (40, 280 - (5 - i) * 50, 42, 280 - (5 - i) * 50);
painter.drawText (25, 285 - (5 - i) * 50, tr("%1").arg ((5 - i) * 5));
}
//绘制x轴坐标
painter.drawLine (x0, y0, 562, 280);
painter.drawLine (558, 276, 562, 280);
painter.drawLine (558, 284, 562, 280);
painter.drawText (567, 285, tr("部门"));
// for(int i = 0; i <= 9; i++)
// {
// painter.drawLine (490 - (8 - i) * 50, 280, 490 - (8 - i) * 50, 278);
// painter.drawText (487 - (8 - i) * 50, 295, tr("%1").arg (i + 1));
// }
int posD = x0 + 20;
int row;
//读取文件中每一行的第一例数据
for(row = 0; row < model()->rowCount (rootIndex ()); ++row)
{
QModelIndex index = model()->index (row, 0, rootIndex ());
QString dep = model ()->data (index).toString ();
painter.drawText (posD, y0 + 15, dep);
posD += 50;
}
/*完成了表格第1列数据的柱状统计图的绘制*/
//男
int posM = x0 + 20;
for(row = 0; row < model()->rowCount (rootIndex ()); row++)
{
QModelIndex index=model()->index(row,1,rootIndex());
int male=model()->data(index).toDouble();
int width = 10;
//使用不同画刷颜色区别选中与未选中的数据项
if(selections->isSelected(index))
painter.setBrush(QBrush(Qt::blue,Qt::Dense3Pattern));
else
painter.setBrush(Qt::blue);
//绘制长方形条x,y,w,h
painter.drawRect(QRect(posM, y0 - male * 10, width, male * 10));
QRegion regionM(posM, y0 - male * 10, width, male * 10);
//将此数据所占据的区域保存到MRegionList列表中,为后面的数据项选择做准备。
MRegionList << regionM;
posM += 50;
}
/*完成了表格第2列数据的柱状统计图的绘制*/
//女条目框
int posF = x0 + 30;
for(row = 0; row < model()->rowCount (rootIndex ()); ++row)
{
QModelIndex index = model()->index (row, 2, rootIndex ());
int female = model()->data (index).toDouble ();
int width = 10;
if(selections->isSelected (index))
painter.setBrush (QBrush(Qt::red, Qt::Dense3Pattern));
else
painter.setBrush (Qt::red);
//绘制长方形x,y,w,h
painter.drawRect (QRect(posF, y0 - female * 10, width, female * 10));
QRegion regionF(posF, y0 - female * 10, width, female * 10);
//将此数据所占据的区域保存到FRegionList列表中,为后面的数据项选择做准备。
FRegionList << regionF;
posF += 50;
}
/*完成了表格第3列数据的柱状统计图的绘制*/
//退休条目框
int posS = x0 + 40;
for(row = 0; row < model()->rowCount (rootIndex ()); ++row)
{
QModelIndex index = model ()->index (row, 3, rootIndex ());
int retire = model()->data (index).toDouble ();
int width = 10;
if(selections->isSelected (index))
painter.setBrush (QBrush(Qt::green, Qt::Dense3Pattern));
else
painter.setBrush (Qt::green);
//绘制长方形x,y,w,h
painter.drawRect (QRect(posS, y0 - retire * 10, width, retire * 10));
QRegion regionS(posS, y0 - retire * 10, width, retire * 10);
SRegionList << regionS;
posS += 50;
}
}
/*
* dataChanged()函数实现当Model中的数据改变时,调用绘图设备的update()函数进行更新,反应数据的变化
*/
void HistogramView::dataChanged (const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
QAbstractItemView::dataChanged (topLeft, bottomRight);
viewport ()->update ();
}
/*
* 设置选择模式,至此View已经能正确显示表格的统计数据,而且对表格中的某个数据项进行修改时能够及时显示将变化反应在柱状统计图中
*/
void HistogramView::setSelectionModel (QItemSelectionModel *selectionModel)
{
selections = selectionModel;
}
/*
* 完成当数据项发生变化时调用update()函数,重绘绘图设备即可工作。此函数是将其他View中的操作引起的数据项选择变化放映到自身
* View的显示中。
*/
void HistogramView::selectionChanged (const QItemSelection &selected, const QItemSelection &deselected)
{
viewport ()->update ();
}
/*
* 在调用setSelection()函数确定鼠标单击点是否在某个数据项的区域内,并设置选择项
*/
void HistogramView::mousePressEvent (QMouseEvent *event)
{
QAbstractItemView::mousePressEvent (event);
setSelection (QRect(event->pos().x (), event->pos().y (), 1, 1), QItemSelectionModel::SelectCurrent);
}
/*
* QModelIndex selectIndex:用于保存被选中的数据项的Index值。此处只实现用鼠标单击选择,而没有实现鼠标拖曳框选,因此,鼠标
* 动作只可能选中一个数据项。
*
* for循环里面:确定在rect中是否含有数据项。此处采用遍历的方式将每个数据项的区域与rect区域进行intersected操作,获得两者之间的
* 交集。若此交集不为空则说明此数据项被选中,将它的Index值赋给selectIndex。
*
* QRegion region = itemRegion (index):返回指定index的数据项所占用的区域
*
* 完成select()函数的调用,即完成最后对选择项的设置工作。select()函数时在实现setSelection()函数的调用,即完成最后对选择项的
* 设置。select()函数是在实现setSelection()函数时必须调用的。
*/
void HistogramView::setSelection (const QRect &rect, QItemSelectionModel::SelectionFlags flags)
{
int rows = model()->rowCount (rootIndex ()); //获得总行数
int columns = model()->columnCount (rootIndex()); //获得总列数
QModelIndex selectedIndex;
for(int row = 0; row < rows; ++row)
{
for(int column = 1; column < columns; ++column)
{
QModelIndex index = model()->index (row, column, rootIndex ());
QRegion region = itemRegion (index);
if(!region.intersected (rect).isEmpty ())
selectedIndex = index;
}
}
if(selectedIndex.isValid ())
selections->select (selectedIndex, flags);
else
{
QModelIndex noIndex;
selections->select (noIndex, flags);
}
}
QModelIndex HistogramView::indexAt (const QPoint &point) const
{
QPoint newPoint(point.x (), point.y ());
QRegion region;
//男列
foreach(region, MRegionList)
{
if(region.contains (newPoint))
{
int row = MRegionList.indexOf (region);
QModelIndex index = model()->index (row, 1, rootIndex ());
return index;
}
}
//女列
foreach (region, FRegionList)
{
if(region.contains (newPoint))
{
int row = FRegionList.indexOf (region);
QModelIndex index = model ()->index (row, 2, rootIndex ());
return index;
}
}
//合计列
foreach(region, SRegionList)
{
if(region.contains (newPoint))
{
int row = SRegionList.indexOf (region);
QModelIndex index = model()->index (row, 3, rootIndex ());
return index;
}
}
return QModelIndex();
}
QRegion HistogramView::itemRegion (QModelIndex index)
{
QRegion region;
if(index.column () == 1) //男
region = MRegionList[index.row ()];
if(index.column () == 2) //女
region = FRegionList[index.row ()];
if(index.column () == 3)
region = SRegionList[index.row ()];
return region;
}
QRect HistogramView::visualRect(const QModelIndex &index)const{}
void HistogramView::scrollTo(const QModelIndex &index,ScrollHint){}
QModelIndex HistogramView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers){}
int HistogramView::horizontalOffset()const{}
int HistogramView::verticalOffset()const{}
bool HistogramView::isIndexHidden(const QModelIndex &index)const{}
QRegion HistogramView::visualRegionForSelection(const QItemSelection &selection)const{}
#include "mainwindow.h"
#include
#include
#include
#include
#include
#include "datedelegate.h"
#include "combodelegate.h"
#include "spindelegate.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
/*定义一个4*4的表格对象*/
QStandardItemModel model(4, 4);
QTableView tableView;
tableView.setModel (&model);
DateDelegate dateDelegate;
tableView.setItemDelegateForColumn (1, &dateDelegate);
ComboDelegate comboDelegate;
tableView.setItemDelegateForColumn (2, &comboDelegate);
SpinDelegate spinDelegate;
tableView.setItemDelegateForColumn (3, &spinDelegate);
model.setHeaderData (0, Qt::Horizontal, QObject::tr("姓名"));
model.setHeaderData (1, Qt::Horizontal, QObject::tr ("生日"));
model.setHeaderData (2, Qt::Horizontal, QObject::tr("职业"));
model.setHeaderData (3, Qt::Horizontal, QObject::tr("收入"));
QFile file("test.txt");
if(file.open (QFile::ReadOnly | QFile::Text))
{
QTextStream stream(&file);
QString line;
model.removeRows (0, model.rowCount (QModelIndex()), QModelIndex());
int row = 0;
do{
line = stream.readLine ();
if(!line.isEmpty ())
{
/*一次插入一行数据,每次插入一个数据*/
model.insertRows (row, 1, QModelIndex());
/*当遇到”,“跳过该项,将数据插入pieces链表中*/
QStringList pieces = line.split (",", QString::SkipEmptyParts);
model.setData (model.index (row, 0, QModelIndex()), pieces.value(0));
model.setData (model.index (row, 1, QModelIndex()), pieces.value (1));
model.setData (model.index (row, 2, QModelIndex()), pieces.value (2));
model.setData (model.index (row, 3, QModelIndex()), pieces.value (3));
row++;
}
}while(!line.isEmpty ());
file.close ();
}
tableView.setWindowTitle (QObject::tr ("Delegate"));
tableView.resize (450, 250);
tableView.show();
return a.exec();
}
#ifndef COMBODELEGATE_H
#define COMBODELEGATE_H
#include
#include
class ComboDelegate : public QItemDelegate
{
public:
ComboDelegate(QObject *parent = 0);
QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData (QWidget *editor, const QModelIndex &index) const;
void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry (QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif // COMBODELEGATE_H
#include "combodelegate.h"
#include
ComboDelegate::ComboDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
/*
* createEditor()函数中创建了一个QComboBox控件,并插入可现实的条目,安装事件过滤器。
*/
QWidget *ComboDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *editor = new QComboBox(parent);
editor->addItem (tr("工人"));
editor->addItem (tr("农民"));
editor->addItem (tr("医生"));
editor->addItem (tr("律师"));
editor->addItem (tr("军人"));
editor->installEventFilter (const_cast<ComboDelegate*>(this));
return editor;
}
/*
* 更新代理控件中的数据显示
*/
void ComboDelegate::setEditorData (QWidget *editor, const QModelIndex &index) const
{
QString str = index.model ()->data (index).toString ();
QComboBox *box = static_cast<QComboBox*>(editor);
int i = box->findText (str);
box->setCurrentIndex (i);
}
/*
* 更新model中的数据
*/
void ComboDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *box = static_cast<QComboBox*>(editor);
QString str = box->currentText ();
model->setData (index, str);
}
void ComboDelegate::updateEditorGeometry (QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry (option.rect);
}
#ifndef DATEDELEGATE_H
#define DATEDELEGATE_H
#include
#include
class DateDelegate : public QItemDelegate
{
public:
DateDelegate(QObject *parent = 0);
QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData (QWidget *editor, const QModelIndex &index) const;
void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry (QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif // DATEDELEGATE_H
#include "datedelegate.h"
#include
DateDelegate::DateDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
/*
* 完成创建控件的工作,创建由参数中的QModelIndex对象指定的表项数据的编辑控件,并对控件的内容进行设定
*
* 新建一个QDateTimeEdit对象作为编辑时的输入控件
* 设置此QDateTimeEdit对象的显示格式为yyyy-MM-dd,此为ISO标准显示方式
* 设置日历选择的显示以Popup的方式,即下拉菜单的方式显示
* 调用QObject类的installEventFilter()函数安装事件过滤器,使DateDelegate能够捕获QDateTimeEdit对象的事件
*/
QWidget *DateDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QDateTimeEdit *editor = new QDateTimeEdit(parent);
editor->setDisplayFormat ("yyyy-MM-dd");
editor->setCalendarPopup (true);
editor->installEventFilter (const_cast<DateDelegate*>(this));
return editor;
}
/*
* QString dataStr = index.model ()->data (index).toString (): 获取指定index数据项的数据,调用QModelIndex的
* model()函数可获得提供index的Model对象,data()函数返回的是一个QVariant对象,toString()函数将它转换为一个QString类型数据
*
* 通过QDate的fromString()函数将以QString类型表示的日期数据转换为QDate类型。Qt::ISODate表示QDate类型的日期是以ISO格式
* 保存的,这样最终转换得的QDate数据也是ISO格式,使控件显示与表格显示保持一致。
*
* QDateTimeEdit *edit = static_cast(editor):将editor装换为QDateTimeEdit对象,以获得编辑控件的
* 对象指针。
*/
void DateDelegate::setEditorData (QWidget *editor, const QModelIndex &index) const
{
QString dataStr = index.model ()->data (index).toString ();
QDate date = QDate::fromString (dataStr, Qt::ISODate);
QDateTimeEdit *edit = static_cast<QDateTimeEdit*>(editor);
edit->setDate (date);
}
/*
* static_cast(editor):通过紧缩转换获得编辑控件的对象指针
* QDate date = edit->date ():获得编辑控件中的数据更新
* model->setData (index, QVariant(date.toString (Qt::ISODate))): 调用setData()函数
* 将数据修改更新到Model中。
*
*/
void DateDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QDateTimeEdit *edit = static_cast<QDateTimeEdit*>(editor);
QDate date = edit->date ();
model->setData (index, QVariant(date.toString (Qt::ISODate)));
}
void DateDelegate::updateEditorGeometry (QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry (option.rect);
}
#ifndef SPINDELEGATE_H
#define SPINDELEGATE_H
#include
class SpinDelegate : public QItemDelegate
{
public:
SpinDelegate(QObject *parent = 0);
QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData (QWidget *editor, const QModelIndex &index) const;
void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry (QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif // SPINDELEGATE_H
#include "spindelegate.h"
#include
SpinDelegate::SpinDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
QWidget *SpinDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QSpinBox *editor = new QSpinBox(parent);
editor->setRange (0, 10000);
editor->installEventFilter (const_cast<SpinDelegate*>(this));
return editor;
}
void SpinDelegate::setEditorData (QWidget *editor, const QModelIndex &index) const
{
int value = index.model ()->data (index).toInt ();
QSpinBox *box = static_cast<QSpinBox*>(editor);
box->setValue (value);
}
void SpinDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QSpinBox *box = static_cast<QSpinBox*>(editor);
int value = box->value ();
model->setData (index, value);
}
void SpinDelegate::updateEditorGeometry (QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry (option.rect);
}