Reputation: 17818
All, I am having trouble determining a good way to handle this. I have a Data Model, which we will call MyData
. I have modelled my data as a QObject
and thus it has signals and slots.
To modify any data in the model, you can either connect to its slots, or directly call the slots. When that modification occurs, the model signals that its data has changed. eg:
class MyData : public QObject
{
...
public slots:
void AddPoint(QPointF);
signals:
void AddedPoint(QPointF);
};
void MyData::AddPoint(QPointF p)
{
//added the point
emit AddedPoint(p);
}
Now my views are two seperate things:
QGraphicsView
which represents the point using QGraphicsEllipseItem
QListView
which uses a QAbstractItemModel
to list the points.I sync these two graphical views using signals and slots (I subclasses QGraphicsItem to inherit from QObject).
The question: When a table makes the change, it signals MyData
, which in turn signals AddedPoint
which is connected to the QGraphicsView. However, MyData::AddedPoint
is also connected to the table, and thus two identical points are added when it attempts to sync. Could anyone offer any advice on how to proceed?
My thoughts and ideas so far:
MyData
slots, block the sender() for a second, then unblock.Edit: MyData
is really a "controller/interface" class, the real model uses OpenCV types and as thus I would like to keep it separated from the Qt architecture.
Upvotes: 1
Views: 1684
Reputation: 1837
You could derive from QAbstractListModel
like this:
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;
};
Now you can add this model simply to your QListView and in your QGraphicsScene
connect to the rowsInserted(...)
and/or rowsRemoved(...)
signal of the model.
I also can recommend reading this
Upvotes: 5