设为首页 加入收藏

TOP

【Qt6】列表模型——抽象基类(三)
2023-09-23 15:44:27 】 浏览:648
Tags:Qt6
ndex(row, column)
; }

QModelIndex 无法直接访问其成员,要产生索引请调用 createIndex 方法。

实现 data 方法。返回数据,这里咱们实现了正常显示的文本和作为工具提示用的文本。

QVariant MyItemModel::data(const QModelIndex &index, int role) const
{
    // 注意 role 这个参数,返回前必须判断
    if(role == Qt::DisplayRole)
    {
        // DisplayRole 说明获取的数据是用在界面呈现上的
        // 咱们只考虑行号,列号嘛,反正只有一列
        int idx = index.row();
        return m_list.at(idx);
    }
    // 可以提供工具提示
    if(role == Qt::ToolTipRole)
    {
        int i = index.row();
        int val = m_list.at(i);
        return QString("这是整数值:%1").arg(val);
    }
    // 如果是其他role,就返回一个默认的QVariant给它
    return QVariant();
}

其他未用到的数据角色返回空的 QVariant 就可以。data 方法返回的值,是对应着二维表中某个单元格的,所以,你希望在那个单元格中显示什么就返回什么。

最后实现的两个方法是用来获取或设置数据源的(即原始数据)。

QList<int> MyItemModel::intList() const
{
    return m_list;
}

void MyItemModel::setIntList(const QList<int> &list)
{
    m_list = list;
}

 

至此,一个简单的模型就有了,当然,没有实现 setData 方法,它只能读数据,不支持编辑。现在我们可以拿来用了。

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    // 创建视图实例
 QListView lv;
    lv.setWindowTitle("简单模型");
    // 准备点数据
    QList<int> theList;
    theList << 100 << 300 << 4500 << 600 << 1200;
    // 实例化模型
    MyItemModel *model;
    model = new MyItemModel(theList);
    //model->setIntList(theList);
    // 为视图设置模型
 lv.setModel(model);
    // 显示窗口
    lv.show();

    // 主循环
    return QApplication::exec();
}

QListView 作为视图组件,适合显示简单的列表。调用视图的 setModel 方法就可以关联指定的模型对象了。如上述代码中,咱们自定义的 MyItemModel 在设置了原始数据后,就可以传递给 setModel 方法以提供数据。

结果如下图所示:

把鼠标移到某个项上,还能看到工具提示呢。

 

咱们给 MyItemModel 加上 setData 方法的重写,使它支持编辑功能。

// 头文件
bool setData(const QModelIndex &index, const QVariant &value, int 
                   role = Qt::EditRole) override;

Qt::ItemFlags flags(const QModelIndex &index) const override;
// 实现代码
bool MyItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    // 设置数据时数据角色通常是编辑
    if(role == Qt::EditRole)
    {
        // 因为只有一列,我们不用关心列号,只取行号
        int row = index.row();
        if(value.canConvert<int>() == false)
        {
            // 不是int值,玩不下去了
            return false;
        }
        // 更新数据
        m_list.replace(row, value.toInt());
        // 发出信号
        QList<int> roles = { Qt::DisplayRole, Qt::EditRole, Qt::ToolTipRole };
        emit dataChanged(index, index, roles);
        // 输出一下,主要是检查list有没有顺利修改
        qDebug() << m_list;
        return true;
    }
    return false;
}

Qt::ItemFlags MyItemModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags oldFlags = QAbstractItemModel::flags(index);
    return oldFlags | Qt::ItemIsEditable;
}

先说说为什么要同时重写 flags 方法,此方法返回 ItemFlag 枚举的值(值可以合并)。如果想让视图组件知道此模型允许编辑,那么返回的 ItemFlags 必须包含 ItemEditable 值。

现在说 setData 方法。首先,role 参数得是 EditRole 才表明用户界面已进入编辑状态,并且这个值是在编辑状态下传送过来的。canConvert 方法是检查一下传过来的是不是 int 值,这里如果是 QListView 组件默认处理的话,一般不会搞错类型。

咱们的原始数据就是存放在 QList<int> 对象中的,所以只调用 replace 方法把某个索引处的值替换下就可以了;如果数据来自文件,就得写入文件以保存。

在数据更新后,记得发送一个 dataChanged 信号,通知所有连接到此信号的对象,数据已变更,赶紧刷新提取最更的值。dataChanged 信号需要三个参数:

void dataChanged(
         const QModelIndex &topLeft, 
         const QModelIndex &bottomRight,
         const QList<int> &roles = QList<int>());

topLeft 参数和 bottomRight 参数是两个索引,它们描述了被修动数据的区域,用左上角和右下角的索引来表示。本示例中,每次只修改一个行,所以,左上角和右下角的索引都是被修改项的索引。roles 参数告诉程序:哪些角色的数要更新一下。一般 EditRole 和 DisplayRole 的要更新,这样可让应用程序知道去刷新数据。模型只用在 QListView 视图中,所以就算不发出 dataChanged 信号,组件也能自动刷新。但如果模型同时应用在多个视图中,并且有其他代码连接了 dataChanged 信号,那就得发出这个信号了。

setData 方法返回 bo

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇2.10 PE结构:重建重定位表结构 下一篇2.12 PE结构:实现PE字节注入

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目