Qt随记

您所在的位置:网站首页 nasa照片十字线 Qt随记

Qt随记

2024-07-13 00:05| 来源: 网络整理| 查看: 265

1.缩放View时最好使用Matrix进行控制。在继承QGraphicsView时添加以下内容:

QWGraphicsView::QWGraphicsView(QWidget *parent):QGraphicsView(parent) //这里改动(QWidget *parent):QGraphicsView(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.1) { m_zoom_factor *= 0.9; } this->updateScene(); } void QWGraphicsView::updateScene() { QMatrix matrix; matrix.scale(m_zoom_factor, m_zoom_factor); this->setMatrix(matrix); }

相应头文件中添加:

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

2.在场景中加入鼠标十字跟随丝辅助线时,出现了两个问题:一个是报错,item's scene (xxx) is different from scene(xxx). 一个是鼠标在进入场景的时候是作为两个LineItem加入的场景,View会默认进行视口扩展,导致加入的图片出现移动。 

第二个问题在博客https://blog.csdn.net/wingover/article/details/88036106 有介绍,只要用View的SetSceneRect函数设置View的视口即可,就不会因为Qt的默认设置导致场景Item的移动。

第一个问题找了好久最后发现是因为在Scene->clear()时会给scene重新分配地址,而我在scene中添加的十字丝(LineItem)是add进前一个场景scene的,这就导致removeItem的时候报scene场景不同的错误。

解决办法就是 在scene->clear()时分配Item的地址,再进行十字丝的add操作。

代码参考:

首先在Scene场景改变时的代码部分(我这里是在切换scene中显示的图片时)

if(xLineOldAdress!=nullptr ) //十字丝横向线,QGraphicsLineItem类型,定义于头文件 { delete xLineOldAdress; xLineOldAdress = nullptr; } if( yLineOldAdress != nullptr) //十字丝纵向线 { delete yLineOldAdress; yLineOldAdress = nullptr; } xLineOldAdress = new QGraphicsLineItem; yLineOldAdress = new QGraphicsLineItem; LineCur = false; //是否显示十字丝(在无图片载入的时候不现实) SceneImg->clear(); SceneImg->addPixmap(pix);//加入影像 ui->ViewPicture->setSceneRect(0,0,w,h); //设置视口,避免触发View视口改变的默认设置 ui->ViewPicture->setScene(SceneImg); //显示场景

然后在鼠标移动的槽函数中添加以下代码:

if(xLineOldAdress && LineCur)//xLineOldAdress 记录前一位置十字丝 { SceneImg->removeItem(xLineOldAdress); SceneImg->update(); } if(yLineOldAdress && LineCur) //yLineOldAdress { SceneImg->removeItem(yLineOldAdress); SceneImg->update(); } if(xLineOldAdress!=nullptr) //启用十字丝以后在场景中添加十字丝 { 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; }

十字丝效果如图:

鼠标因为截图工具的原因没有显示出来,实际上是用

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

设置为十字丝形式,十字丝会跟随鼠标移动并不会增加内存的消耗。

 

3.在设计十字丝的时候想着使用Qt的paintEvent事件进行绘制,最后还是作罢,因为需要在图片上进行绘图。使用PaintEvent显然没有scene机制方便。

这里记录一下在View中使用PaintEvent,以备不时之需。同样也是实现十字丝跟踪。

在继承QGraphicsView中添加paintEvent函数

void MyGraphicsView::paintEvent(QPaintEvent *) { QPainter painter(this->viewport()); QPen pen; pen.setWidth(5); pen.setColor(Qt::red); painter.setPen(pen); //绘制横向线 painter.drawLine(0, lasPos.y(), width(), lasPos.y()); //绘制纵向线 painter.drawLine(lasPos.x(), 0, lasPos.x(), height()); }

在同时添加mouseMoveEvent函数

void MyGraphicsView::mouseMoveEvent(QMouseEvent *event) { //鼠标移动事件 lasPos = event->pos(); //在头文件中声明QPoint lasPos viewport()->update(); QGraphicsView::mouseMoveEvent(event); }

记得在构造函数中设置鼠标可跟踪

this->setMouseTracking(true);

 

效果:

没有研究如何在这里面加入背景图片进行绘制。感觉还是scene方便。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3