【发布时间】: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 项 - 另外,我已经更新了代码