具有两种不同视图的Qt数据模型

时间:2012-11-02 17:58:26

标签: c++ qt

所有,我无法确定处理此问题的好方法。我有一个数据模型,我们称之为MyData。我已将数据建模为QObject,因此它有信号和插槽。

要修改模型中的任何数据,您可以连接到其插槽,也可以直接调用插槽。当发生修改时,模型会发出信号表明其数据已发生变化。例如:

class MyData : public QObject
{
   ...
public slots:
     void AddPoint(QPointF);

signals:
     void AddedPoint(QPointF);
};

void MyData::AddPoint(QPointF p)
{
    //added the point
    emit AddedPoint(p);
}

现在我的观点是两个独立的事情:

  1. 我有QGraphicsView代表使用QGraphicsEllipseItem
  2. 的点
  3. 我有QListView使用QAbstractItemModel列出积分。
  4. 我使用信号和插槽同步这两个图形视图(我将子类QGraphicsItem继承自QObject)。

    问题:当表格进行更改时,它会发出MyData信号,而AddedPoint会发信号通知MyData::AddedPoint,它连接到QGraphicsView。 但是MyData也连接到表格,因此在尝试同步时会添加两个相同的点。有人可以就如何进行提出任何建议吗?


    到目前为止我的想法和想法:

    • 我可以检查该点是否存在,并防止重复。适用于插入,非常适合删除和更新。
    • 我认为最好的方法是:在MyData个广告位中,阻止发送方()一秒钟,然后取消阻止。

    编辑: {{1}}实际上是一个“控制器/接口”类,真正的模型使用OpenCV类型,因此我希望将它与Qt架构分开。

1 个答案:

答案 0 :(得分:3)

您可以从QAbstractListModel这样派生出来:

class MyData : public QAbstractListModel
{
    Q_OBJECT
public:
    enum CustomRoles {
        PositionRole = Qt::UserRole + 1,
        BoundingRectRole
    };
    MyData(QObject *parent = 0) : QAbstractListModel(parent)
    {
        QHash<int, QByteArray> roles;
        roles[PositionRole] = "Position";
        roles[BoundingRectRole] = "BoundingRect";
        setRoleNames(roles);
    }
    int rowCount(const QModelIndex & parent = QModelIndex()) const
    {
        return points.count();
    }

    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const
    {
        if (index.row() < 0 || index.row() > points.count())
             return QVariant();

         const QGraphicsEllipseItem &p = points[index.row()];
         QVariant actualData;
         if (role == Qt::DisplayRole)
             actualData = "some point";
         else if (role == PositionRole)
             actualData = p.scenePos();
         else if (role == BoundingRectRole)
             actualData = p.boundingRect();

         return actualData;
    }

public slots:
    void addPoint(int x, int y)
    {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        QGraphicsEllipseItem *it = new QGraphicsEllipseItem(0,0, 5, 5);
        it->setPos(x,y);
        points << it;
        endInsertRows();
    }

private:
    QVector<QGraphicsEllipseItem*> points;
};

现在,您可以将此模型简单地添加到QListView,并在QGraphicsScene连接到模型的rowsInserted(...)和/或rowsRemoved(...)信号。

我也建议您阅读this