QT的TableView之自定义Model

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);

    

效果图:

猜你喜欢

转载自blog.csdn.net/Mario_z/article/details/85280823