【问题标题】:Qt Troubles with painting selection boxQt 绘画选择框的问题
【发布时间】:2013-01-05 02:01:50
【问题描述】:

我在强制重绘/更新我的 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 进行测试。

【问题讨论】:

    标签: c++ qt qt4


    【解决方案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);
    }
    

    【讨论】:

    • 太棒了,这正是我想要的,它确实有助于知道——因为 qt 在 QGraphicsScene/View 上造成了伪影,我自然而然地想使之无效并更新它,而忘记了视口,所以我很高兴你发布了这个我可能在弄清楚之前已经发疯了......!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2022-06-12
    • 2020-06-06
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    相关资源
    最近更新 更多