创建 QAbstractModelItem 的代理

发布于 2024-10-24 19:06:53 字数 2514 浏览 12 评论 0原文

我正在编写一个 Qt 应用程序来实现非常大的数据集的可视化。

所以,我有一个 SourceDataModel 类,继承自 QAbstractItemModel ,它似乎工作正常(目前,我只在 QTableView/QTreeView 中显示它,但稍后,我将创建一些自定义视图)。

现在,我希望能够过滤这些数据,即

  1. 能够拥有不同的数据 分辨率(即仅暴露 1 2)

    中的数据项
  2. 能够 对数据应用一些过滤器(即 将 Unix 时间戳显示为 dd/MM/yyyy hh:mm:ss)

所以我开始创建一个 ProxySourceDataModel 类,它继承自我的 SourceDataModel 并存储一个实例,基本上将所有内容委托给实例。从这个 ProxySourceDataModel 中,我注意到当我在 QTableView 中使用它时没有显示任何数据。经过一番调查,似乎是因为我必须从底层 SourceDataModel 转发信号和槽。没问题,我做到了。

但仍然存在两个问题,我不知道如何处理它们:

  1. 我无法选择视图中的数据。如果我直接使用 SourceDataModel ,没有问题。但是使用 ProxySourceDataModel 我无法选择任何内容。

  2. 数据根本没有被过滤!我在 ProxySourceDataModel 中重载了 data(),并将所有其他调用转发给底层的 SourceDataModel。但仍然只调用了 SourceDataModel::data()

这是一些代码来说明我正在做的事情:

class SourceDataModel : public QAbstractItemModel
{
  //...
};

class ProxySourceDataModel : public SourceDataModel
{
public:
  ProxySourceDataModel(SourceDataModel& model)
    : model_(model)
  {
    // For all QAbstractItemModel's signals emitted by the underlying model,
    // I propagate them like this
    QObject::connect( &model_, SIGNAL(        the_signal()),
                      this,    SLOT  (forward_the_signal())) ;
  }

slots:
  void forward_the_signal()
  {
    emit the_signal();
  }

public:
  // For all QAbstractItemModel's virtual function, I do something like this
  virtual void the_function()
  {
    model_.the_function();
  }

  // This is where I was hoping to do the filtering
  virtual QVariant data( const QModelIndex& index,int role=Qt::DisplayRole )
  {
    return filter( model_.data(index,role) );
  }

private:
  SourceDataModel& model_;
};

SourceDataModel sourceDataModel;
QTableView      view;
view.setModel( new ProxySourceDataModel(sourceDataModel) );

非常感谢任何帮助或建议,感谢您的阅读!

-------------------- 编辑 ------------------------

我找到了!

问题是视图不使用其模型中的 QAbstractItemModel::data() ,而是调用 QModelIndex::data( ) 其项目,进而调用项目底层模型的 QAbstractItemModel::data() 。 由于我的代理从底层模型返回模型索引,这就是为什么总是调用 SourceDataModel::data() 而不是 ProxySourceDataModel()

我刚刚重新实现了 ProxySourceDataModel::index() 来返回本地索引,它的工作方式就像一个魅力。 访问在 QT 中,链接模型无法按预期工作 了解更多信息。

谢谢!

I'm writing a Qt application to allow the visualization of very heavy data sets.

So, I have a SourceDataModel class, inheriting from QAbstractItemModel that seems to work properly (currently, I only display it in QTableView/QTreeView but later on, I'll create some custom views).

Now, I would like to be able to filter this data, that is

  1. being able to have different data
    resolution (i.e. only exposing 1
    data item out of 2)

  2. being able to
    apply some filters on the data (i.e.
    displaying unix timestamps as
    dd/MM/yyyy hh:mm:ss)

So I started to create a ProxySourceDataModel class, which inherits from my SourceDataModel and stores one instance, and basically delegates everything to the instance. From this ProxySourceDataModel, I noticed that no data was displayed when I used it in a QTableView. After some investigation, it seems that it was because i had to forward the signals and slots from the underlying SourceDataModel. No problem, i did it.

But still 2 problems remain, and I can't figure out how to handle them:

  1. I am not able to select the data in the views. If I use the SourceDataModel directly, no problem. But using the ProxySourceDataModel i can't select anything.

  2. The data is not filtered at all! I overloaded data() in ProxySourceDataModel, and forward all the other calls to the underlying SourceDataModel. But still, only SourceDataModel::data() is called.

Here is some code to illustrate what I'm doing:

class SourceDataModel : public QAbstractItemModel
{
  //...
};

class ProxySourceDataModel : public SourceDataModel
{
public:
  ProxySourceDataModel(SourceDataModel& model)
    : model_(model)
  {
    // For all QAbstractItemModel's signals emitted by the underlying model,
    // I propagate them like this
    QObject::connect( &model_, SIGNAL(        the_signal()),
                      this,    SLOT  (forward_the_signal())) ;
  }

slots:
  void forward_the_signal()
  {
    emit the_signal();
  }

public:
  // For all QAbstractItemModel's virtual function, I do something like this
  virtual void the_function()
  {
    model_.the_function();
  }

  // This is where I was hoping to do the filtering
  virtual QVariant data( const QModelIndex& index,int role=Qt::DisplayRole )
  {
    return filter( model_.data(index,role) );
  }

private:
  SourceDataModel& model_;
};

SourceDataModel sourceDataModel;
QTableView      view;
view.setModel( new ProxySourceDataModel(sourceDataModel) );

Any help or advice greatly appreciated, thanks for reading!

-------------------- EDIT ------------------------

I found it!

The problem was that the view do not use QAbstractItemModel::data() from its model, but rather calls QModelIndex::data() on its items, which in turn calls the QAbstractItemModel::data() of the item's underlying model.
And since my proxy returned model indexes from the underlying model, that is why the SourceDataModel::data() was always called instead of ProxySourceDataModel()!

I just reimplemented ProxySourceDataModel::index() to return local indexes, and it works like a charm.
Visit In QT, chaining models does not work as expected for more informations.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仙女山的月亮 2024-10-31 19:06:53

问题是视图不使用其模型中的 QAbstractItemModel::data() ,而是在其项目上调用 QModelIndex::data() ,后者又调用项目底层模型的 QAbstractItemModel::data()
由于我的代理从底层模型返回模型索引,这就是为什么总是调用 SourceDataModel::data() 而不是 ProxySourceDataModel()

我刚刚重新实现了 ProxySourceDataModel::index() 来返回本地索引,它的工作方式就像一个魅力。
访问在 QT 中,链接模型无法按预期工作 了解更多信息。

The problem was that the view do not use QAbstractItemModel::data() from its model, but rather calls QModelIndex::data() on its items, which in turn calls the QAbstractItemModel::data() of the item's underlying model.
And since my proxy returned model indexes from the underlying model, that is why the SourceDataModel::data() was always called instead of ProxySourceDataModel()!

I just reimplemented ProxySourceDataModel::index() to return local indexes, and it works like a charm.
Visit In QT, chaining models does not work as expected for more informations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文