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 编译器在 Windows 7 x64 上使用 Qt 4.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 回答