Smoothly Updating QGraphicsscene

407 views Asked by At

Hi I have managed to add a number of qgraphicsitems to a qgraphicsscene using the code below

def generate_graph_and_update_scene(self):

try:
    local_params=locals() #for error log  get local paramters
    this_function_name=sys._getframe().f_code.co_name #for error log  get function name


    self.vertex_dict.clear()
    self.clear() #clear graphicsscene

    self.graph_pos.clear() #clear graph position holder object

    #function that generates the node data
    root_nodes=my_database_query.get_nodes_information()
    for node in root_nodes:
        # add nodes to nx.graph object
        self.nx_graph.add_node(node['column1'])


    # create networkx graph
    self.graph_pos = nx.spring_layout(self.nx_graph, iterations=25,scale=10)

    for node in self.nx_graph.nodes(): # Add nodes to qgraphicsscene

        v=default_nodeobject.my_ellipse(node,self.graph_pos)               
        self.addItem(v) # Add ellipse to qgraphics scene

    for edge in self.nx_graph.edges():
        self.addItem(defaultedgeview.edgeview(edge[0], edge[1],self.graph_pos))#add edges to qgraphicscene

except:
    #Exception handler
    message=str(sys.exc_info())
    message=message + str(local_params)+" "+ str(this_function_name)
    print message

This allows me to add say 600 'nodes' to my qgraphics scene, however when I clear the scene and add another say 1500 nodes, adding the items blocks the UI and my whole application freezes for a few seconds. Also whenever I am doing things like looping through the graphicsitems say looking for the nodes that have a certain property, again the main thread freezes while I am looping,

Could anyone suggest a good method of keeping the UI responsive while things are being done to the grpahicsscene/items in the scene. Ideally would like to have smooth, non-blocking updates to the scene, even when I have a few thousand items showing.

1

There are 1 answers

2
TheDarkKnight On

The problem here is the management of each node as a graphics item. Adding and removing to a scene, as well as rendering each item is going to take time. With this many items, I suggest designing it differently.

Consider the node graph as a single, custom graphics item which stores a group of nodes and manages them as a single unit, rather than 600+ separate items.

Designed this way, you only add one item to the scene (the node graph) which allows rapid addition and removal of nodes and you will also see a performance improvement in rendering the scene, as all nodes are drawn in one call to paint().

Of-course, if you need to move nodes around by clicking and dragging them, you'll have to add additional code to handle detecting which node is being selected in the item and move it yourself.

However, this is the optimal way to handle such a large number of items in a scene.