QGraphicsPathItem,QGraphicsScene,QGraphicsView使用问题记录,QGraphicsScene::items()获取鼠标位置的QGraphicsPathItem

实现的功能是在界面上显示1000条线,每条线上有10000个数据,要鼠标点击或者移动到某条线上的时候显示该线条的一些信息
实现思路:
1.界面上放一个QGraphicsView
2.在QGraphicsView中放一个QGraphicsScene

m_scene=new QGraphicsScene();
ui->graphicsView->setScene(m_scene);

3.将条线的放到一个QPainterPath数组里,总工1000个元素

QPainterPath path[1000];
for( j=0 ; j < row ; j++ )
{
    
    
	path[j].moveTo(0,dataarray[0]+5*j);//每增加一条线,位置下移5个像素
	for ( i = 1 ; i < col ; i++ )
	{
    
    
	    path[j].lineTo(i*0.5, dataarray[i]+5*j);
	}
}

4.将QPainterPath放到QGraphicsPathItem里(我这里重写了QGraphicsPathItem类,也就是写了一个MyQgraphicPathItem类继承自QGraphicsPathItem)

MyQgraphicPathItem pathItem = new MyQgraphicPathItem(path[j]);

5.将QGraphicsPathItem放到QGraphicsScene里

m_scene->addItem(pathItem);

6.在我的代码里重写了QGraphicsView类,也就是写个myview类继承自QGraphicsView,然后在myview类里面重写了鼠标点击事件,通过QGraphicsScene::items()获取鼠标位置附近的QGraphicsPathItem

void mousePressEvent(QMouseEvent *event) override;//头文件里的
void myview::mousePressEvent(QMouseEvent *event)//源文件里的
{
    
    
    if(event->button()==Qt::LeftButton)
    {
    
    
        QPointF ptInScene = mapToScene(event->pos());
        QList<QGraphicsItem *> pItems=this->scene()->items(QRectF(ptInScene.x()-2,ptInScene.y()-2,4,4));
        if(pItems.size()>0 && pItems[0]->zValue()==0)
        {
    
    
            MyQgraphicPathItem* item = (MyQgraphicPathItem*)pItems[0];
            emit currentLineSig(event->pos().y(),item->getLineID());//将MyQgraphicPathItem里的信息通过信号传出去
         }
    }
}

这里注意一下
问题1
当场景中的item很多的时候,QGraphicsScene::items()方法会非常耗时!
我测试了一下,场景中有1000条线,每条线10000个数据,在debug模式下,QGraphicsScene::items()方法耗时1秒多!!!
release模式下会好一点,耗时减少2/3
但这也很影响用户体验,所以我本来想再鼠标移动mousemove事件里面去调用QGraphicsScene::items()获取item的,后来想想还是通过点击鼠标事件来获取item吧,毕竟鼠标移动事件被触发次数太多,太耗时。

问题2
QGraphicsView鼠标移动事件不触发
一开始再我重写myview类里面的mouseMoveEvent事件的时候,发现运行过程中不会直接触发鼠标移动事件,只有在点击鼠标的时候才会触发mouseMoveEvent,后来查到原因是需要在myview的构造函数里加上

this->setMouseTracking(true);

おすすめ

転載: blog.csdn.net/weixin_43935474/article/details/115935034