Qt Notes - Mouse Crosswire Auxiliary Line, QGraphics View and SetScene Rect of Scene

Posted by wenxi on Thu, 19 Sep 2019 09:12:36 +0200

1. When zooming in View, it's better to use Matrix for control. Add the following when inheriting QGraphicsView:

QWGraphicsView::QWGraphicsView(QWidget *parent):QGraphicsView(parent)  //Here's the change (QWidget * parent): QGraphics View (parent)
{

    //this->setMouseTracking(true);
//    m_img_scene_ptr = new ShowGraphicsScene();
//    this->setScene(m_img_scene_ptr);

    double width_scale = double(this->width()) / double(640);
    double height_scale = double(this->height()) / double(360);
    m_zoom_factor = width_scale < height_scale ? width_scale : height_scale;
    //m_zoom_factor = 1;
    this->updateScene();

}
void QWGraphicsView::wheelEvent(QWheelEvent *event)
{
    if (event->delta() > 0 && m_zoom_factor < 3)
    {
        m_zoom_factor *= 1.15;
    }
    else if(event->delta() <= 0 && m_zoom_factor > 0.1)
    {
        m_zoom_factor *= 0.9;
    }

    this->updateScene();

}
void QWGraphicsView::updateScene()
{
    QMatrix matrix;
    matrix.scale(m_zoom_factor, m_zoom_factor);
    this->setMatrix(matrix);
}

Add:

 double m_zoom_factor;
 void wheelEvent(QWheelEvent *event);
 void updateScene();

2. There are two problems when adding the mouse cross-follower wire auxiliary line in the scene: one is the error, item's scene (xxx) is different from scene (xxxx). The other is that when the mouse enters the scene, it joins the scene as two LineItem s. View will expand the viewport by default, which causes the added image to move.  

The second question is blogging. https://blog.csdn.net/wingover/article/details/88036106 It is introduced that as long as the View's SetSceneRect function is used to set the View's view, the default settings of Qt will not cause the scene Item to move.

The first problem was found for a long time and it was finally found that the address of scene was reassigned when Scene - > clear (), and the LineItem I added to scene was added to the scene of the previous scene, which led to different errors in reporting scene scenes when removeItem was removeItem.

The solution is to assign the address of Item when scene - > clear (), and then add the cross wire.

Code reference:

First, the code part when the Scene scene changes (I'm switching the pictures shown in the scene)

    if(xLineOldAdress!=nullptr ) //Crosswire Horizontal Line, Type QGraphics LineItem, Defined in Header File
    {
        delete xLineOldAdress;
        xLineOldAdress = nullptr;
    }
    if( yLineOldAdress != nullptr) //Crosswire Longitudinal Line
    {
        delete yLineOldAdress;
        yLineOldAdress = nullptr;
    }

    xLineOldAdress = new QGraphicsLineItem;
    yLineOldAdress = new QGraphicsLineItem;

    LineCur = false;  //Whether or not to display the cross filament (unrealistic when no images are loaded)


    SceneImg->clear();
    SceneImg->addPixmap(pix);//Add image
    ui->ViewPicture->setSceneRect(0,0,w,h); //Set Viewport to avoid default settings that trigger Viewport changes
    ui->ViewPicture->setScene(SceneImg); //Display scenario

Then add the following code to the slot function of mouse movement:

    if(xLineOldAdress && LineCur)//xLineOldAdress records the previous position of the cross wire
    {
        SceneImg->removeItem(xLineOldAdress);
        SceneImg->update();

    }
    if(yLineOldAdress && LineCur) //yLineOldAdress
    {
        SceneImg->removeItem(yLineOldAdress);
        SceneImg->update();
    }

    if(xLineOldAdress!=nullptr) //Adding Cross Wire to Scene after Enabling Cross Wire
    {
        xLineOldAdress->setLine(pointScene.x()-2000,pointScene.y(),pointScene.x()+2000,pointScene.y());
        SceneImg->addItem(xLineOldAdress);
        LineCur = true;
    }

    if(yLineOldAdress!=nullptr)
    {
        yLineOldAdress->setLine(pointScene.x(),pointScene.y()-2000,pointScene.x(),pointScene.y()+2000);
        SceneImg->addItem(yLineOldAdress);
        LineCur = true;

    }

The effect of cross wire is as follows:

The mouse is not shown because of the screenshot tool. It is actually used.

ui->ViewPicture->setCursor(Qt::CrossCursor);

Set to the form of cross-wire, the cross-wire will follow the mouse movement and will not increase memory consumption.

Topics: Qt