简体   繁体   English

Qt麻烦与绘画选择框

[英]Qt Troubles with painting selection box

I'm having troubles forcing a repaint/update of my Qt Widget (it extends the QGraphicsView class). 我在强制重新粉刷/更新Qt窗口小部件时遇到麻烦(它扩展了QGraphicsView类)。 What I want is a rectangular selection box to be drawn which will highlight the target selection area as the user presses and moves the mouse. 我要绘制一个矩形选择框,当用户按下并移动鼠标时,该框将突出显示目标选择区域。

The basic workflow: 基本工作流程:

  1. MousePressEvent sets the making_selection_box flag, and stores the start point (working). MousePressEvent设置making_selection_box标志,并存储起点(工作中)。
  2. MouseMoveEvent checks to see if the display needs to be updated. MouseMoveEvent检查是否需要更新显示。 If it does, it tries to do so (not working). 如果这样做,它将尝试这样做(不起作用)。
  3. MouseReleaseEvent handles gets the resulting selection box and handles it accordingly. MouseReleaseEvent句柄获取结果选择框并进行相应的处理。 making_selection_box is reset. making_selection_box被重置。 Screen should be updated to remove the selection box artifact (not working). 屏幕应该更新以删除选择框工件(不起作用)。

The overrided mouseMoveEvent: 重写的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);
}

My overrided paintEvent: 我重写的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 is just a small helper function I wrote to create the correct QRect for different selection box start/end points. 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);
}

I've verified that mouseMoveEvent is being triggered correctly when the user presses a button and moves the mouse around. 我已验证当用户按下按钮并四处移动鼠标时,可以正确触发mouseMoveEvent。

I've also verified that paintEvent is being called by the system when I perform various standard operations such as resize the window, minimize/maximize it, etc. 我还验证了在执行各种标准操作(例如调整窗口大小,最小化/最大化窗口等)时,系统正在调用paintEvent。

I've verified that the method I'm using to paint to my widget will work correctly with other paintEvent triggers, I just can't manage to trigger a repaint in my code. 我已经验证了我用来绘制小部件的方法可以与其他paintEvent触发器一起正常使用,但我只是无法设法在代码中触发重绘。

I've also tried forcing the update by using the update() method instead of repaint() , but no luck. 我也尝试通过使用update()方法而不是repaint()来强制更新,但是没有运气。

As a side note, am I going about creating this selection box functionality the wrong/hard way? 作为附带说明,我要以错误/困难的方式创建此选择框功能吗? Is there a better way to get a selection box without having to manually implement the mouse listeners and painting code? 是否有更好的方法来获得选择框,而无需手动实现鼠标侦听器和绘画代码?

I'm testing with Qt 4.8.4 on Windows 7 x64, using the Visual Studio 2010 MSVC compiler. 我正在使用Visual Studio 2010 MSVC编译器在Windows 7 x64上使用Qt 4.8.4进行测试。

After looking through the QGraphicsScene API I found an easy workaround for having to manually manage the selection box: The drag mode needs to be set to RubberBandDrag . 在浏览完QGraphicsScene API之后,我发现了一种手动解决选择框的简单方法:拖动模式需要设置为RubberBandDrag

edit: 编辑:

To further expand my answer which allows painting on the QGraphicsView for other purposes, it's the viewport which needs to receive the update/redraw, not my QGraphicsView object. 为了进一步扩展我的答案(允许在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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM