Qt麻烦与绘画选择框

时间:2013-01-05 02:01:51

标签: c++ qt qt4

我遇到麻烦,迫使重新编辑/更新我的Qt Widget(它扩展了QGraphicsView类)。我想要的是一个矩形选择框,当用户按下并移动鼠标时,它将突出显示目标选择区域。

基本工作流程:

  1. MousePressEvent设置making_selection_box标志,并存储起点(工作)。
  2. MouseMoveEvent检查是否需要更新显示。如果是这样,它会尝试这样做(不工作)。
  3. MouseReleaseEvent句柄获取结果选择框并相应地处理它。 making_selection_box已重置。应更新屏幕以删除选择框工件(不工作)。
  4. 重写的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进行测试。

1 个答案:

答案 0 :(得分: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);
}