如何在QAbstractItemModel包装器模型中转发信号

时间:2016-04-04 20:54:16

标签: qt signals-slots qabstractitemmodel

我打算创建自己的项目模型,派生自QAbstractItemModel。该模型不包含数据,但包含一些数据存储库。在插入,删除,重命名项目等之后,该存储库会发出信号。

每当存储库中的某些内容发生变化时,我的项目模型都需要转发这些信号。

然而,存储库具有独立信号,如void itemRemoved(int index);,而QAbstractItemModel具有开始/结束对受保护功能(和信号),如beginInsertRows()endInsertRows()

我应该如何处理?例如。我可以将以下插槽连接到存储库的itemRemoved()信号:

void RepositoryItemRemoved(int i)
{
   beginInsertRows(QModelIndex(), i, i);
   endInsertRows();
}

基于上面的示例:在存储库中插入行之后,是否有效地调用beginInsertRows() / endInsertRows()

2 个答案:

答案 0 :(得分:1)

我有一个类似的场景,数据在不同的对象中,模型只是一个包装器,只有在视图中显示该数据集时才会创建。我在数据对象中使用了一个指向模型对象的指针,检查它是否在插入操作中为空,如果没有通过它调用beginInsertRows()endInsertRows()。当然,由于这些是受保护的,因此必须将数据类声明为模型类的朋友。

文档强调在插入任何数据之前调用beginInsertRows()非常重要:

  

在子类中重新实现insertRows()时,必须调用它   在将数据插入模型的底层数据存储之前的函数...

     

...否则,视图可能会以无效状态结束。

您应该使用视图进行测试,或者检查源中的实际实现。

答案 1 :(得分:0)

我也有类似的情况,只是在我的情况下,Qt模型将底层模型包含在字面上:底层模型包含的数据远远超过视图必须知道的数据。所以我让Qt模型包含自己的每个底层模型的数据项的小块列表供视图/委托处理。因此,处理底层模型更新的插槽如下所示:

List<string[]> fileContents = new List<string[]>();

            var lines = File.ReadAllLines(ofd.FileName).ToList();
            foreach (var item in lines)
            {
                string RegNo = string.Format("{0}", item.ToString().Substring(0, 19));
                string accHolder = string.Format("{0}", item.ToString().Substring(21, 30));
                string amount = string.Format("{0}", item.ToString().Substring(52, 11));
                string accNo = string.Format("{0}", item.ToString().Substring(64, 13));
                string branch = string.Format("{0}", item.ToString().Substring(78, 6));
                string date = string.Format("{0}-{1}-{2}", "20" + item.ToString().Substring(85, 2), item.ToString().Substring(87, 2), item.ToString().Substring(89, 2));
                string code = string.Format("{0}", item.ToString().Substring(92, 2));
                string orphenColumn = string.Format("{0}", item.ToString().Substring(95, 1));

                lstRegNo.Add(RegNo.Trim());
                lstAccHolder.Add(ExtensionMethods.RemoveSpecialCharacters(accHolder.Trim()));
                lstAmount.Add(amount.Trim());
                lstAccNo.Add(accNo.Trim());
                lstBranch.Add(branch.Trim());
                lstDate.Add(date);
                lstCode.Add(code.Trim());
                lstOrphenColumn.Add(orphenColumn);
            }

这样的设计解决了视图无效状态的问题,尽管对于让Qt模型包含其自己的项目列表的用例可能是不切实际的,这意味着要复制正在使用的足够数量的数据。