0

グラフィックフレームワークを使用して、単純なドラッグ可能なアイテムを作成しようとしています。これまでに行ったことのコードは次のとおりです。

ウィジェットクラス:

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

};

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    DragScene *scene = new DragScene();
    DragView *view = new DragView();
    QHBoxLayout *layout = new QHBoxLayout();

    DragItem *item = new DragItem();
    view->setAcceptDrops(true);
    scene->addItem(item);
    view->setScene(scene);
    layout->addWidget(view);
    this->setLayout(layout);

}

Widget::~Widget()
{
}

DragViewクラス:

class DragView : public QGraphicsView
{
public:
    DragView(QWidget *parent = 0);
};

DragView::DragView(QWidget *parent) : QGraphicsView(parent)
{
    setRenderHints(QPainter::Antialiasing);
}

DragSceneクラス:

class DragScene : public QGraphicsScene
{
public:
    DragScene(QObject* parent = 0);

protected:
    void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
    void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
    void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
    void dropEvent(QGraphicsSceneDragDropEvent *event);
};

DragScene::DragScene(QObject* parent) : QGraphicsScene(parent)
{
}

void DragScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event){
}

void DragScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event){
}

void DragScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event){
}

void DragScene::dropEvent(QGraphicsSceneDragDropEvent *event){
    qDebug() << event->pos();
    event->acceptProposedAction();
    DragItem *item = new DragItem();
    this->addItem(item);
    // item->setPos(event->pos()); before badgerr's tip
    item->setPos(event->scenePos());
}

DragItemクラス:

class DragItem : public QGraphicsItem
{
public:
    DragItem(QGraphicsItem *parent = 0);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);

protected:
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};

DragItem::DragItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{
    setFlag(QGraphicsItem::ItemIsMovable);
}

QRectF DragItem::boundingRect() const{
    const QPointF *p0 = new QPointF(-10,-10);
    const QPointF *p1 = new QPointF(10,10);
    return QRectF(*p0,*p1);
}

void DragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    if(painter == 0)
        painter = new QPainter();
    painter->drawEllipse(QPoint(0,0),10,10);
}

void DragItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event){

}

void DragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
}

void DragItem::mousePressEvent(QGraphicsSceneMouseEvent *event){
    QMimeData* mime = new QMimeData();
    QDrag* drag = new QDrag(event->widget());
    drag->setMimeData(mime);
    drag->exec();
}

void DragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
}

main.cppはウィジェットをインスタンス化し、それを表示します。円をドラッグしようとすると、ドラッグを放した場所に関係なく、アプリは元の円の上に別の円を作成するだけです。DragSceneのdropEvent()のqDebug()は、ドラッグが終了するたびにQPointF(0,0)を表示します。これを機能させるために、自分が何をしなければならないか、どのクラスをサブクラス化する必要があるか、どのメソッドをオーバーライドする必要があるかを正確に理解しようとするのに苦労しています。これに関するドキュメントはあまり詳細ではありません。これを機能させる方法を知りたいのですが、公式ドキュメント(優れていますが、より詳細なものがあれば素晴らしいです)の他に、グラフィックスビューフレームワークについて学ぶためのより包括的なリソースが他にある場合は主題に関する論文)。

編集:

Badgerrのアドバイスに従って、DragScene :: dropEvent()のitem-> pos()をitem->scenePos()に置き換えました。これで、dropイベントがdropサイトに新しい円を作成します。これは、多かれ少なかれ私が望んでいたものです。ただし、元の円はそのままで、ドラッグの進行中は、アイテムはマウスカーソルに追従しません。

QGraphicsSceneDragDropEventのドキュメントには、pos()は、イベントを送信したビューに関連するカーソル位置を返す必要があると記載されています。これは、間違っていない限り、常に(0,0)であってはなりません。変。

フォーラムの投稿で、QDrag :: setPixMap()を使用してドラッグ中に何かを表示できることを読みました。例では、画像がピックスマップとして設定されているのを見ましたが、グラフィックスアイテムと同じようにピックスマップを作成するにはどうすればよいですか。ドラッグすることになっていますか?

4

1 に答える 1

1

QDrag メソッドを使用しているように見える「ドラッグ アンド ドロップ ロボットの例」と呼ばれる Qt Assistant の例があります。

編集:簡単な観察では、イベント自体の mimeData() を使用する代わりに、DropEvent で新しい DragItem を作成しているように見えます。アイテムは 0,0 で描画されるため、新しいDragItem をドロップする場所に関係なく、その位置に表示されます。


これに似たグラフィックスをドラッグするものを書いたとき、私はそれを少し異なる方法で行いました. 多分それはあなたを助けるでしょう:

QDrag を使用する代わりに、QGraphicsItem の mousePressEvent、mouseReleaseEvent、および mouseMoveEvent 関数のみを使用しました。マウスのプレス/リリースは、ドラッグ状態を示すフラグを設定し、移動は次のプロセスに従いました

  • prepareGeometryChange() を呼び出します。
  • QGraphicsItem の境界を更新します (私の boundingRect() 関数はこれらの境界を返します。すべてのグラフィックアイテムの境界は QGraphicsScene 空間にあります)
  • update() を呼び出します。

次に、paint() 関数で、boundingRect() を使用して形状を描画します。

申し訳ありませんが、共有できるコード サンプルがありません。時間があれば作成します。

于 2010-04-29T08:10:06.793 に答える