• 自定义模型CityModel


      参考<<C++ GUI Programming with Qt 4>>中文版第二版中的例子:城市距离。具体描述请看书本,主要重写继承自QAbstractTableModel的CityModel,该模型底层的数据是一个QStringList类型的对象和一个QVector<int>类型的对象。前者用于保存城市的名字,后者保存城市之间的距离。

      citymodel.h文件:

    #ifndef CITYMODEL_H
    #define CITYMODEL_H
    
    #include <QAbstractTableModel>
    #include <QVector>
    #include <QStringList>
    
    class CityModel : public QAbstractTableModel
    {
    public:
        CityModel(QObject *parent = 0);
        void setCities(const QStringList &cityNames);
        int rowCount(const QModelIndex &parent) const;
        int columnCount(const QModelIndex &parent) const;
        QVariant data(const QModelIndex &index, int role) const;
        bool setData(const QModelIndex &index, const QVariant &value, int role);
        QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    
        Qt::ItemFlags flags(const QModelIndex &index) const;
    
    private:
        int offsetOf(int row, int column) const;
        QStringList cities;
        QVector<int> distances;
    };
    
    #endif

      citymodel.cpp文件:

    #include "citymodel.h"
    
    CityModel::CityModel(QObject *parent)
        :QAbstractTableModel(parent)
    {
    }
    
    int CityModel::rowCount(const QModelIndex &parent) const
    {
        return cities.count();
    }
    
    int CityModel::columnCount(const QModelIndex &parent) const
    {
        return cities.count();
    }
    
    QVariant CityModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
        {
            return QVariant();
        }
        if (role == Qt::TextAlignmentRole)
        {
            return int(Qt::AlignRight | Qt::AlignVCenter);
        }
        else if (role == Qt::DisplayRole)
        {
            if (index.row() == index.column())
            {
                return 0;
            }
            int offset = offsetOf(index.row(), index.column());
            return distances[offset];
        }
        return QVariant();
    }
    
    QVariant CityModel::headerData(int section, Qt::Orientation orientation, int role) const
    {
        if (role == Qt::DisplayRole)
        {
            return cities[section];
        }
        return QVariant();
    }
    
    bool CityModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if (index.isValid() && index.row() != index.column() && role == Qt::EditRole)
        {
            int offset = offsetOf(index.row(), index.column());
            distances[offset] = value.toInt();
            QModelIndex transposedIndex = createIndex(index.column(), index.row());
    
            emit dataChanged(index, index);
            emit dataChanged(transposedIndex, transposedIndex);
            return true;
        }
        return false;
    }
    
    Qt::ItemFlags CityModel::flags(const QModelIndex &index) const
    {
        Qt::ItemFlags flags = QAbstractItemModel::flags(index);
        if (index.row() != index.column())
        {
            flags |= Qt::ItemIsEditable;
        }
        return flags;
    }
    
    void CityModel::setCities(const QStringList &cityNames)
    {
        cities = cityNames;
        distances.resize(cities.count() * (cities.count() - 1)/2);
        distances.fill(0);
        reset();
    }
    
    int CityModel::offsetOf(int row, int column) const
    {
        if (row < column)
        {
            qSwap(row, column);
        }
        return (row * (row - 1)/2) + column;
    }

      main.cpp文件:

    #include <QtGui/QApplication>
    #include "citymodel.h"
    #include <QTableView>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QStringList cities;
        cities<<"Arvika"<<"Boden"<<"Eskilstuna"<<"Falun"<<"Filipstad";
        CityModel cityModel;
        cityModel.setCities(cities);
    
        QTableView tableView;
        tableView.setModel(&cityModel);
        tableView.setAlternatingRowColors(true);
        tableView.setWindowTitle("cities");
        tableView.show();
    
        return a.exec();
    }

      运行界面:

                             

  • 相关阅读:
    linux sleep用法
    linux下set命令的参数及用法
    给vim编辑器自动添加行号
    linux一些基本常识(三)
    shell脚本面试题
    linux下字符串的比较方式
    浅谈Windows API编程
    WIN32 API ------ 最简单的Windows窗口封装类
    Microsoft函数调用约定
    Android UI 设计规范
  • 原文地址:https://www.cnblogs.com/venow/p/2731901.html
Copyright © 2020-2023  润新知