Search code examples
c++qtqgraphicsviewqgraphicsitemqtwidgets

How can I change the color of a QGraphicsItem?


I'm trying to cast a QGraphicsRectItem and then use its setBrush(Qt::QColor) method, but it didn't work.

int r = rand() %itemList.length();
MyItem *item = itemList.at(r);
QGraphicsRectItem *rect = qgraphicsitem_cast<QGraphicsRectItem *>(item);
rect->setBrush(Qt::black);
rect->update();

I even tried to change MyItem in QGraphicsRectItem (for what I'm doing there's no difference), but still didn't work.


Solution

  • I can't reproduce it. It works fine. You may be changing some rect that's not visible on screen. Likely you have multiple overlapping rects at the same position, due to bugs elsewhere, and you don't see the changes even though they occur. The update() call is unnecessary: it'd mean that the implementation of the item is broken. Whenever a visible property of the item is changed, the item should automatically update. And indeed, it does. If you coded your own item types and they require manual update() calls, you need to fix them!

    Here's a little demo that show that setBrush does indeed work on a QGraphicsRectItem:

    // https://github.com/KubaO/stackoverflown/tree/master/questions/qgraphicsitem-brush-62028912
    #include <QtWidgets>
    #include <cstdlib>
    
    QColor randColor() { return QRgb((rand() << 16) ^ rand()); }
    
    int main(int argc, char *argv[])
    {
       srand(QDateTime::currentDateTime().toMSecsSinceEpoch());
       QApplication a(argc, argv);
       QGraphicsScene scene;
       QGraphicsView view(&scene);
    
       auto *rect = scene.addRect(0, 0, 100, 100);
       view.fitInView(rect);
    
       QTimer timer;
       QObject::connect(&timer, &QTimer::timeout, &view, [rect]{
          rect->setBrush(randColor());
       });
       timer.start(500);
    
       view.show();
       return a.exec();
    }
    

    This demo will work for you. Then you have to figure out what other bugs you have, because setBrush is not the culprit.