0

全体として、これを処理する良い方法を判断するのに苦労しています。と呼ぶデータモデルがあります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);
}

今、私の見解は2つの別々のものです:

  1. QGraphicsView使用してポイントを表す がありますQGraphicsEllipseItem
  2. ポイントをリストするためにaQListViewを使用する aがあります。QAbstractItemModel

シグナルとスロットを使用して、これら 2 つのグラフィカル ビューを同期します (QGraphicsItem をサブクラス化して、QObject から継承します)。

質問:テーブルが変更を行うと、 MyDataQGraphicsViewAddedPointに接続されていることを通知します。 ただしMyData::AddedPointもテーブルに接続されているため、同期を試みると 2 つの同一のポイントが追加されます。進め方について誰かアドバイスをいただけますか?


これまでの私の考えとアイデア:

  • ポイントが存在するかどうかを確認し、繰り返しを防ぐことができました。挿入には適していますが、削除や更新には適していません。
  • 私が思う最善の方法はMyDataスロットで、sender() を 1 秒間ブロックしてから、ブロックを解除することです。

編集: MyData実際には「コントローラー/インターフェース」クラスです。実際のモデルはOpenCVタイプを使用しているため、Qtアーキテクチャから分離したままにします。

4

1 に答える 1

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 に追加し、モデルのand/orシグナルにQGraphicsScene接続できます。rowsInserted(...)rowsRemoved(...)

これも読むことをお勧めします

于 2012-11-02T22:44:39.587 に答える