其实这个问题,原因是QGraphicsItem的boundingRect的范围不在当前的View范围内,当然不会刷新,特别是自定义的一些Item,特别要注意自己的boundingrect是否在准确的位置,所以其实是boundingrect没有自动更新位置导致的。
当遇到相似的问题时,不妨把boundingrect画出来就可以见分晓了。
下面是我们的代码:
#ifndef LIDARPOINTS_H
#define LIDARPOINTS_H
#include <QColor>
#include <QGraphicsItem>
#include <QImage>
class Lidarpoints : public QGraphicsItem
{
public:
Lidarpoints(const QColor &color, int x, int y);
Lidarpoints(/*const QImage image*/);
void setLidarData(QPoint pos, std::vector<QPoint>& data);
QRectF boundingRect() const Q_DECL_OVERRIDE;
QPainterPath shape() const Q_DECL_OVERRIDE;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) Q_DECL_OVERRIDE;
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE;
private:
int x;
int y;
QColor color;
QVector<QPointF> stuff;
//
QImage imageContent;
std::vector<QPoint> lidar_points;
bool paint_state = false;
int rect_value = 100;
QRectF paintRect;
};
#endif // LIDARPOINTS_H
#include "lidarpoints.h"
#include <QtWidgets>
#include <iostream>
Lidarpoints::Lidarpoints(const QColor &color, int x, int y)
{
this->x = x;
this->y = y;
this->color = color;
//
//setZValue(1000);
setFlags(ItemIsSelectable | ItemIsMovable);
setAcceptHoverEvents(true);
//QSize size(20,20);
paintRect.setRect(0,0,20,20);
}
Lidarpoints::Lidarpoints(/*const QImage image*/)
{
//this->imageContent = image;
}
QRectF Lidarpoints::boundingRect() const
{
//return paintRect;
return paintRect;
}
QPainterPath Lidarpoints::shape() const
{
QPainterPath path;
path.addRect(14, 14, 82, 42);
return path;
}
void Lidarpoints::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(widget);
const qreal lod = option->levelOfDetailFromTransform(painter->worldTransform());
std::cout << "lod " << lod << std::endl;
//QRect rect(0,0,imageContent.width(),imageContent.height());
//painter->setCompositionMode(QPainter::CompositionMode_Overlay);
//painter->drawImage(rect,imageContent);
//painter->setPen(QPen(Qt::blue,4));//设置画笔形式
//painter->drawRect(rect);
//painter->drawEllipse(QPoint(0,0),20,20);//画圆
std::cout << "paint now" << std::endl;
QPen pen;
pen.setColor(Qt::red); // 画笔颜色设置
//pen.setWidth(10);
painter->setPen(pen);
for(auto it : lidar_points){
painter->drawPoint(it.x(), -1*it.y());
}
//QRect rect(0,0,rect_value,rect_value);
//painter->drawRect(rect);
//rect_value+=1;
//std::cout << "rect_value " << rect_value << std::endl;
/*
QRectF rect = boundingRect();
std::cout << "rect " << rect.x()
<< " " << rect.y()
<< " " << rect.width()
<< " " << rect.height()
<< std::endl;
painter->drawRect(rect);
*/
paint_state = true;
}
void Lidarpoints::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsItem::mousePressEvent(event);
update();
}
void Lidarpoints::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
//
//prepareGeometryChange();
if (event->modifiers() & Qt::ShiftModifier) {
stuff << event->pos();
update();
return;
}
QGraphicsItem::mouseMoveEvent(event);
}
void Lidarpoints::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsItem::mouseReleaseEvent(event);
update();
}
void Lidarpoints::setLidarData(QPoint pos, std::vector<QPoint>& data){
paintRect.setRect(pos.x(), pos.y(),20,20);
prepareGeometryChange();
//boundingRect();
if(paint_state == true){
std::cout << "Lidarpoints::setLidarData " << lidar_points.size() << std::endl;
lidar_points.clear();
lidar_points = data;
}
else{
//std::cout << "auto paint fail " << std::endl;
// lidar_points.clear();
//lidar_points = data;
// 调用此函数以告知 Qt 几何形状即将改变
//prepareGeometryChange();
//update();
}
paint_state = false;
}
大家可以做个参考。