6

我的应用程序存储了一些从对象继承的类型的 QAbstractListModel对象。

当使用一般的添加、删除和多选功能将简单 std::vector<T>或 a包装到模型中时,这会生成大量重复代码。QList<T>

是应该使用这种方式QAbstractListModel还是有一些适配器类可以删除重复的代码(至少对于作为 Qt 一部分的容器)?

示例:我想将其包装vector<ObjectA>vector<ObjectB>一个模型。insertRows,等的代码总是相同的deleteRowscolumnCount我想巩固一下(通过一些元编程甚至可以与tupleand一起工作data)。

4

2 回答 2

6

您必须在两个单独的类中执行此操作,因为 Qt 对 c++ 的扩展(SIGNALS、SLOTS 等)不能很好地与模板配合使用。可以在以下位置找到基本原理和解决方法:https ://doc.qt.io/archives/qq/qq15-academic.html

这是解决方案的大致轮廓。(这是基于我们在应用程序中使用的代码,并且运行良好。)

1. 做 Qt 东西的抽象列表类

class FooListModelQt : public QAbstractTableModel {
  Q_OBJECT

public:
  // Non-template methods, signals, slots, etc. can be used here. For example...
  QSet<int> SelectedRows() const;
  // ... etc. ...

signals:
  void SelectionChanged();
  // ... etc. ...

protected:
  explicit FooListModelQt(QObject *parent = NULL);
  virtual ~FooListModelQt() = 0;
  // ... etc. ...

};

2. 做模板的抽象类

template <typename T>
class FooListModel : public FooListModelQt {
public:
  const T* at(int index) const { return items_.at(index); }
  int count() const { return items_.count(); }
  void Append(T *item);
  // ... etc. ...

protected:
  explicit FooListModel(QObject *parent = NULL);
  virtual ~FooListModel();

private:
  QList<T*> items_;
};

3.实际列表类

class BarListModel : public FooListModel<Bar> {
  Q_OBJECT

public:
  explicit BarListModel(QObject *parent = NULL);
  int columnCount(const QModelIndex &parent) const;
  QVariant data(const QModelIndex &index, int role) const;
  // ... etc. ...
};
于 2012-01-17T16:08:59.330 回答
1

通常我会实现我自己的直接继承的模型,QAbstractItemModel并为表示功能提供我自己的实现,例如data()处理我给模型的数据存储容器。

如果您有代码重复使用QList<T>std::vector<T>那么我建议通过执行以下任一操作将一个转换为另一个:

QList<T> list = QList::fromVector(QVector::fromStdVector(vector));

或其他方式。

std::vector<T> vector = qlist.toVector().toStdVector();

我会做后者,但你可以选择任何一个。

根据您的其他评论,您可以采取 2 种行动途径:

路径一:

实施objectA如下objectB

class objectA : baseObject

class objectB : baseObject

哪里baseObject是:

struct baseObject
{
    virtual std::string toString() = 0;
};

可能比其他任何东西更容易转换为字符串。

路径 2 将基本上涉及使用std::vector<boost::any>()作为数据存储容器的模型内部,这样您就可以实现单个模型子类化QAbstractListModel

您必须考虑的事情是,如果您的数据存储容器可以使数据表示变得通用,那么您可以做的事情是有限的,因为data()可以为您提供视图的功能必须返回元素,QVariant并且它受限于您可以构造它的内容从。

于 2012-01-17T14:46:23.230 回答