【问题标题】:QGraphicsView not rendering some items on scrollQGraphicsView 未在滚动时呈现某些项目
【发布时间】:2013-12-24 06:39:04
【问题描述】:

我对 QGraphicsView、QGraphicsScene 和 QGraphicsPolygonItem 进行了子类化。该项目只是一个可以是不同颜色的小方块。场景将它们布置在 90 行 x 360 列的网格中。

头文件

class MyView : public QGraphicsView {
Q_OBJECT
public:
    MyView(QGraphicsScene * scene,QWidget *parent = NULL);

public slots:
    void zoomIn(){ scale(1.2,1.2);};
    void zoomOut(){ scale(1/1.2,1/1.2);};
    void wheelEvent(QWheelEvent * event);
};

cpp 文件

MyView::MyView(QGraphicsScene * scene,QWidget *parent) : QGraphicsView(scene,parent){
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
}
void MyView::wheelEvent(QWheelEvent * event){
if(event->modifiers() & Qt::ControlModifier){
     if(event->delta() > 0){
        zoomIn();
     } else {
        zoomOut();
     }
}else{
    QGraphicsView::wheelEvent(event);
}
}

头文件

#define MAX_ROW 90
#define MAX_COL 360
class MyScene : public QGraphicsScene
{
public:
    MyScene(QObject * parent =0);

};

cpp 文件

MyScene::MyScene(QObject *parent) : QGraphicsScene(parent){
   setSceneRect(0,0,MAX_COL*10,MAX_ROW*10);
   QGraphicsScene::setBackgroundBrush (QColor("lightblue"));
   MyCell * cell;
   for(int x=1;x<=MAX_COL;++x){
        for(int y=1;y<=MAX_ROW;++y){
            cell= new MyCell;
            cell->setPos(x*7,y*7);
            addItem(cell);
            cell->update();
        }
    }
}

头文件

class MyCell :public QGraphicsItem {
public:
    MyCell(QGraphicsItem * parent =0,int state =0);

    QRectF boundingRect() const;
    void drawImage();

    void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget =0);
    QColor color();
    int state(){return _state;}
    void setState(int state);
    enum{NO,HARD,SOFT};
private:
    int _state; 
    QImage _image;
};

cpp 文件

MyCell::MyCell (QGraphicsItem* parent, int state) : QGraphicsItem (parent) {
    _state=state;
}


void MyCell::drawImage() {
     QPainter paint;
     QImage image = QImage(boundingRect().size().toSize(),QImage::Format_ARGB32_Premultiplied);
     paint.begin(&image);
     paint.setRenderHint(QPainter::Antialiasing);
     paint.fillRect(boundingRect(),color());
     paint.end();
     _image = image.copy();
}
void MyCell::setState(int state){
    if(state != HARD && state != SOFT){
        _state=NO;
    }else{
        _state=state;
    }
        drawImage();
}
QColor MyCell::color(){
    if(_state==HARD) return QColor(0xFFFFFFFF);
    else if(_state==SOFT) return QColor(0xFF7F7F7F);
    else return QColor(0xFF000000);

}
void MyCell::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget){
    painter->save();
        painter->drawImage(boundingRect(),_image,boundingRect());
    painter->restore();
}

QRectF MyCell::boundingRect() const {
    return QRectF(0,0,6,6);

}

创建主窗口小部件的代码将启动它

    scene = new MyScene(this);
    view = new MyView(scene,this);
    setCentralWidget(view);

当我滚动视图时,某些行和列没有完全重新绘制。性能似乎也很慢。如果我从 MyView 构造函数中删除这一行:

setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);

性能提高了,但现在更多的行被遗忘了,当我缩放圆角矩形时,看起来不太正确。最终,我希望用户能够单击图形项目并更改它们的颜色。我还希望他们能够通过橡皮筋单击并选择多个正方形并以这种方式更改颜色。

但由于已经存在性能问题,我想只使用一个图形项并存储一个二维整数数组,并在绘制函数内部根据数组的值绘制单个图像。这会提高性能吗?在该实现中如何单击、选择多个正方形/橡皮筋?

更新:我更新了 MyCell 类中的代码。图形渲染现在更好了,但缩放和滚动时仍然很慢。有没有办法用我拥有的物品数量来加快速度? 360 x 90 = 32,400 个项目。如果不是,我可能只需要制作 360 个项目,而不是画一个正方形,我把它画成条形图。但是我必须跟踪 360 个垂直条的所有 90 个子部分的颜色并相应地绘制它们。这也会使细胞选择变得更加困难。

【问题讨论】:

  • 你有几样东西?一些性能提示: 1) 不要在 shape() 中创建新的 QPainterPath,在每个paint() 中也调用。缓存路径,或者在这种情况下,直接调用painter->drawRoundedRect() 2) 不要重新实现shape(),除非你真的关心确切的形状(碰撞)。否则就让 boundingRect() 返回矩形而不关心角落 3) QColor("red") 需要解析,因此比 QColor(255, 0, 0) 更昂贵(或使用静态常量)。
  • 32,400 项 - 另外,我已经更新了代码

标签: qt qt4


【解决方案1】:

这个问题可能是由不正确的QGraphicsPolygonItem 子类化引起的。 QGraphicsPolygonItem::boundingRect 的默认实现返回多边形的边界矩形。但是你没有设置任何多边形,也没有重新实现boundingRect 方法,所以MyCell::boundingRect 是空的。在项目的边界矩形之外绘制会导致图形视图的错误行为。

我认为在您的代码中子类化 QGraphicsPolygonItem 没有任何意义。您不妨继承QGraphicsItem,因为您不使用QGraphicsPolygonItem 的任何功能。也许QGraphicsPathItem 对你有用,没有子类化。如果您仍想重新实现paint 函数,请确保您正确地重新实现了boundingRect 虚函数。

【讨论】:

  • 图形渲染现已修复。代码仍然很慢。我已经更新了问题。
猜你喜欢
  • 2021-04-01
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多