1.介绍
QT在QT4的时候推出了Model-view视图结构,这种结构更好的将软件中数据和UI分层处理,从而达到提升显示效果。QT中其实已经自带一些基本功能的model,如下:
以上的Model可以满足一般的基本需求
,使用起来方便简单。比如QStandardItemModel既可以满足一般的Table的结构,也可以满足树状的结构。但是自带缺点是使用起来不够灵活,对数据的操作受限于自带的接口。所以需要自定义model。
2.QAbstractItemModel
以上几个Model均是继承于QT的QAbstractItemModel这个类。QAbstractItemModel类为项目模型类提供了抽象接口。我们继承这个类需要实现以下几个接口 index(), parent(), rowCount(), columnCount(), and data().(均为QAbstractItemModel纯虚函数)
3.代码
model.h
class MeasureTableModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit MeasureTableModel(QObject *parent = 0);
~MeasureTableModel();
void setHeaderList(const QStringList &);
void delete_line(const int &);
void set_line_list(const QList <LineData> &);
virtual QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
virtual QModelIndex parent(const QModelIndex &child) const;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole)const;
virtual QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole)const;
private:
QList <LineData> m_linedata_list;
QStringList m_header_list;
};
model.cpp
MeasureTableModel::MeasureTableModel(QObject *parent)
{
setParent(parent);
}
MeasureTableModel::~MeasureTableModel()
{
}
void MeasureTableModel::setHeaderList(const QStringList &headerlist)
{
m_header_list = headerlist;
}
void MeasureTableModel::delete_line(const int & row)
{
m_linedata_list.removeAt(row);
endRemoveColumns();
}
void MeasureTableModel::set_line_list(const QList<LineData> & line_list)
{
m_linedata_list = line_list;
reset();
}
QModelIndex MeasureTableModel::parent(const QModelIndex &child)const
{
Q_UNUSED(child);
return QModelIndex();
}
QModelIndex MeasureTableModel::index(int row, int column, const QModelIndex &parent) const
{
return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex();
}
int MeasureTableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_linedata_list.count();
}
int MeasureTableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_header_list.count();
}
QVariant MeasureTableModel::data(const QModelIndex &item, int role) const
{
if (!item.isValid())
{
return QVariant();
}
role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
if((Qt::DisplayRole == role))
{
switch (item.column()) {
case 0:
{
double x = m_linedata_list.at(item.row()).m_first_point.x();
double y = m_linedata_list.at(item.row()).m_first_point.y();
QString s = '(' + QString::number(x, 'f' ,4) + ", " + QString::number(y,'f', 4) + ')';
return s;
}
case 1:
{
double x = m_linedata_list.at(item.row()).m_last_point.x();
double y = m_linedata_list.at(item.row()).m_last_point.y();
QString s = '(' + QString::number(x, 'f' ,4) + ", " + QString::number(y,'f', 4) + ')';
return s;
}
case 2:
return m_linedata_list.at(item.row()).m_distance;
default:
break;
}
}
else if (role == Qt::TextAlignmentRole)
{
return int(Qt::AlignLeft | Qt::AlignVCenter);
}
else if (role == Qt::BackgroundRole)
{
if (item.row() % 2)
{
return QBrush(QColor(Qt::lightGray));
}
else
{
return QColor(Qt::white);
}
}
else if (role == Qt::ToolTipRole)
{
switch (item.column()) {
case 0:
{
double x = m_linedata_list.at(item.row()).m_first_point.x();
double y = m_linedata_list.at(item.row()).m_first_point.y();
QString s = '(' + QString::number(x, 'f' ,4) + ", " + QString::number(y,'f', 4) + ')';
return s;
}
case 1:
{
double x = m_linedata_list.at(item.row()).m_last_point.x();
double y = m_linedata_list.at(item.row()).m_last_point.y();
QString s = '(' + QString::number(x, 'f' ,4) + ", " + QString::number(y,'f', 4) + ')';
return s;
}
case 2:
return m_linedata_list.at(item.row()).m_distance;
default:
break;
}
}
else
{
return QVariant();
}
}
QVariant MeasureTableModel::headerData(int section, Qt::Orientation orientation, int role)const
{
if(role != Qt::DisplayRole)
{
return QVariant();
}
if (orientation == Qt::Horizontal)
{
switch (section) {
case 0:
return m_header_list.at(0);
case 1:
return m_header_list.at(1);
case 2:
return m_header_list.at(2);
case 3:
return m_header_list.at(3);
default:
break;
}
}
return QVariant();
}
}
实际使用:
m_table_view = new QTableView(this);
m_table_model = new MeasureTableModel(m_table_view);
m_table_view->setModel(m_table_model);
QStringList header_list;
header_list << "startPos" << "endPos" << "result";
m_table_model->setHeaderList(header_list);
m_table_view->setSelectionMode(QAbstractItemView::SingleSelection);
m_table_view->horizontalHeader()->setClickable(false);
m_table_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_table_view->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
m_table_view->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
m_table_view->horizontalHeader()->setHighlightSections(false);
m_table_view->horizontalHeader()->setClickable(false);
m_table_view->verticalHeader()->setDefaultSectionSize(20);
m_table_view->verticalHeader()->setMinimumSectionSize(20);
m_table_view->verticalHeader()->hide();
for (int i = 0; i < 10; i ++)
{
LineData linedata;
linedata.m_first_point = QPointF(1, 1);
linedata.m_last_point = QPointF(1, 1);
linedata.m_distance = 1;
m_linedata_list.append(linedata);
}
m_table_model->set_line_list(m_linedata_list);
效果图: