PDA

View Full Version : Is there any substitution function for the obsolete QGraphicsScene drawItems ?



tonnot
25th November 2011, 09:06
For QGraphicsScene::drawItems the reference says :
Reimplement this function to provide custom painting of all items for the scene; gaining complete control over how each item is drawn.
But this function is marked as obsolete .
Is there any new equivalent method ?

veiovis
29th July 2014, 23:34
This would interest me as well.
I would to hide to small items in a view completely, when the user zooms out.
Hiding them in the scene would hide them in all views, so drawItems would seem like the right function.

Is there a replacement for that function?
Or is there another way for solving this?

wysota
30th July 2014, 08:56
I would to hide to small items in a view completely, when the user zooms out.
The proper way to do it is to teach your items to make use of the level-of-detail information provided by the QStyleOptionGraphicsItem::levelOfDetailFromTransfo rm() method and skip drawing parts or whole items when the item is "far enough" from the viewer.

veiovis
30th July 2014, 23:16
Hi, thanks for your reply.
I did not find this function before. Could be what I need.
But I tried using it, and it always returned 1.
I'm scaling my view with QGraphicsView::scale() and this always prints 1 for lod and lodT (level of detail):




void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
qreal lod = option->levelOfDetail;
qreal lodT = option->levelOfDetailFromTransform(painter->worldTransform());
ARMARX_INFO << "lod: " << lod << " lodT: " << lodT << " width: " << mapRectToScene(bounds).width() << std::endl;
...


What am I understanding wrong here? :)

Also the paint-function is not called when zooming in or out (kinda suspicious).

wysota
30th July 2014, 23:44
Works quite fine for me:


#include <QtWidgets>

class Item : public QGraphicsRectItem {
public:
Item(QGraphicsItem *parent = 0) : QGraphicsRectItem(parent) {
setRect(0,0,50,50);
setPen(QPen(Qt::red));
}

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) {
qDebug() << "LOD:" << QStyleOptionGraphicsItem::levelOfDetailFromTransfo rm(painter->worldTransform());
QGraphicsRectItem::paint(painter, option, widget);
}
};

class GraphicsView : public QGraphicsView {
public:
GraphicsView() : QGraphicsView() {}
protected:
void mousePressEvent(QMouseEvent *e) {
if(e->button() == Qt::LeftButton) scale(2,2);
else scale(0.5, 0.5);
}
};

int main(int argc, char **argv) {
QApplication app(argc, argv);
GraphicsView view;
QGraphicsScene scene;
view.setScene(&scene);
scene.addItem(new Item);
view.show();
view.scale(3,3);
return app.exec();
}

If paint() is not getting called for you then either you may have caching enabled or your paint() signature is incorrect.

veiovis
31st July 2014, 00:15
Paint is called, when resizing my widget or when i drag something over it. Also, all the paint is done in there for my widget and its painted correctly.

I'll have a look at your code and try to figure out the difference, thanks :)

Edit: Your code works for me too...so let the hunt begin

Added after 10 minutes:

Caching was the problem:


setCacheMode(ItemCoordinateCache);

I needed to removed that line, thanks.

Edit: Using DeviceCoordinateCache works also and the paint function is not called as often.