QGraphicsScene choked with updates?



  • I have a Worker Thread that copes with heavy and long computations (up to tenth of seconds). These computations produce several thousands of QLines, representing the edges of a dynamically-growing tree. These edges can be modified anytime, since they connect the nodes of the trees by checking the cost, represented by the distance. I would like a smooth update of the QGraphicsScene containing the edges. I tried with signal and slots:

    • Worker thread emits a signal, so when the buffer is full this signal gets caught by the main thread, that will cope with the update/drawing of the line
    • This signal gets still caught by the main thread, but it seems it gets emitted very often, so QGraphicsView/QGraphicsScene gets choked with QLine to be added
    • Changing the size of the buffer doesn't matter
    • Is there an alternative approach to this?

    The main slot is:

    void MainWindow::update_scene(bufferType buffer)
    {
      for (int i = 0; i < buffer.size(); ++i)
      {
          if (buffer[i].first < (g_edges.size() - 1))
          {
              delete g_edges[buffer[i].first];
              g_edges[buffer[i].first] = scene->addLine(buffer[i].second);
          }
          else
              g_edges.push_back(scene->addLine(buffer[i].second));
       }
    }
    

    Note that bufferType is of type QList<std::pair<int,QLine>>. Here is the heavy computing part

    while (T.size() < max_nodes_number && !_stop)
    {
        const cnode random_node = rand_conf ();
        const cnode nearest_node = T.nearest_node (random_node);
        cnode new_node = new_conf (nearest_node, random_node);
    
        if (obstacle_free(nearest_node, new_node))
        {
            QList<cnode*> X_near = T.neighbours (new_node, max_neighbour_radius);
            cnode lowest_cost_node = nearest_node;
            qreal c_min = nearest_node.cost() + T.distance (nearest_node, new_node);
    
            for (int j = 0; j < X_near.size(); ++j)
            {
                if (obstacle_free(*X_near[j], new_node) && ((X_near[j]->cost() + T.distance (*X_near[j], new_node)) < c_min))
                {
                    c_min = X_near[j]->cost() + T.distance (*X_near[j], new_node);
                    lowest_cost_node = *X_near[j];
                }
            }
    
            T.add_node (new_node, lowest_cost_node.id());
            queue (new_node.id(), QLine (new_node.x(), new_node.y(), lowest_cost_node.x(), lowest_cost_node.y()));
    
            for (int j = 0; j < X_near.size(); ++j)
            {
                if (obstacle_free(*X_near[j], new_node) && (new_node.cost() + T.distance (new_node, *X_near[j])) < X_near[j]->cost())
                {
                    queue (X_near[j]->id(), QLine (new_node.x(), new_node.y(), X_near[j]->x(), X_near[j]->y()));
    
                    T.update_parent (*X_near[j], new_node.id());
                    T.rewire_tree (X_near[j]->id());
                }
            }
        }
    }
    emit finished();
    
    

    Please note that T is a class representing a Tree. It is constituted by some methods allowing to add a node, searching for the nearest one, etc. It has a QList<cnode> as private member, storing the tree's nodes. cnode is a structure constituted of two coordinates, an id, a parent, a cost, a list of its children.


  • Qt Champions 2016


  • Lifetime Qt Champion

    Hi,

    Please don't post the same question multiple times. If you have additional informations to add to your thread, you can edit the post. rather than deleting it and write a new one.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.