2

Qtウィジェットの再描画/更新を強制するのに問題があります(QGraphicsViewクラスを拡張します)。私が欲しいのは、ユーザーがマウスを押して動かすと、ターゲット選択領域を強調表示する長方形の選択ボックスを描画することです。

基本的なワークフロー:

  1. MousePressEventはmaking_selection_boxフラグを設定し、開始点を保存します(動作中)。
  2. MouseMoveEventは、表示を更新する必要があるかどうかを確認します。もしそうなら、それはそうしようとします(動作しません)。
  3. MouseReleaseEventハンドルは、結果の選択ボックスを取得し、それに応じて処理します。making_selection_boxリセットされます。画面を更新して、選択ボックスのアーティファクトを削除する必要があります(機能していません)。

オーバーライドされたmouseMoveEvent:

void QSchematic::mouseMoveEvent(QMouseEvent *event)
{
    if(making_selection_box)
    {
        // get selection box
        qDebug() << "updating selection box";
        curr_selection_end = event->pos();
        repaint(box(drag_select_start, curr_selection_end));
    }
    // propogate event
    QGraphicsView::mouseMoveEvent(event);
}

オーバーライドされたpaintEvent:

void QSchematic::paintEvent(QPaintEvent *event)
{
    qDebug() << "paintEvent";
    if(making_selection_box)
    {
        qDebug() << "drawing selection box";
        QPainter painter(viewport());
        painter.setPen(Qt::black);
        painter.drawRect(box(drag_select_start, curr_selection_end));
        painter.end();
    }
    // propogate event
    QGraphicsView::paintEvent(event);
}

Boxは、さまざまな選択ボックスの開始点/終了点に対して正しいQRectを作成するために作成した小さなヘルパー関数です。

static QRect box(const QPoint& p1, const QPoint &p2)
{
    int min_x = p1.x();
    int min_y = p1.y();
    int max_x = p2.x();
    int max_y = p2.y();
    if(max_x < min_x)
    {
        max_x = min_x;
        min_x = p2.x();
    }
    if(max_y < min_x)
    {
        max_y = min_y;
        min_y = p2.y();
    }
    return QRect(min_x, min_y, max_x - min_x, max_y - min_y);
}

ユーザーがボタンを押してマウスを動かすと、mouseMoveEventが正しくトリガーされることを確認しました。

また、ウィンドウのサイズ変更、最小化/最大化などのさまざまな標準操作を実行するときに、paintEventがシステムによって呼び出されていることを確認しました。

ウィジェットへのペイントに使用しているメソッドが他のpaintEventトリガーで正しく機能することを確認しましたが、コードで再ペイントをトリガーすることができません。

update()また、の代わりにメソッドを使用して更新を強制しようとしましたrepaint()が、うまくいきませんでした。

ちなみに、この選択ボックスの機能を間違った/難しい方法で作成しようとしていますか?マウスリスナーを手動で実装したりコードをペイントしたりせずに、選択ボックスを取得するためのより良い方法はありますか?

Visual Studio 2010 MSVCコンパイラを使用して、Windows7x64でQt4.8.4をテストしています。

4

1 に答える 1

1

QGraphicsScene APIを調べた後、選択ボックスを手動で管理する必要があるという簡単な回避策を見つけました。ドラッグモードをに設定する必要がありますRubberBandDrag

編集:

他の目的でQGraphicsViewにペイントできるようにする私の答えをさらに拡張するには、QGraphicsViewオブジェクトではなく、更新/再描画を受け取る必要があるのはビューポートです。

void QSchematic::mouseMoveEvent(QMouseEvent *event)
{
    if(making_selection_box)
    {
        // get selection box
        qDebug() << "updating selection box";
        curr_selection_end = event->pos();
        viewport()->repaint(box(drag_select_start, curr_selection_end));
    }
    // propogate event
    QGraphicsView::mouseMoveEvent(event);
}
于 2013-01-05T16:21:01.423 に答える