I develop an application where a lot of objects need to be added to a QGraphicsScene
object in order to represent the diagram of an electric power system. When the grid is large this process takes a while and the main window remains unresponsive. Hence, I'd like to know a way to create the objects asynchronously.
The following code is an very very simplified version of the actual code. In the example I create objects and I add them to the scene
using the function add_objects
. This is the function that should run in a thread.
import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
def add_objects(scene: QGraphicsScene, n=1000):
for i in range(n):
item = QGraphicsEllipseItem(i * 5, 10, 60, 40)
scene.addItem(item)
class MyView(QGraphicsView):
def __init__(self):
QGraphicsView.__init__(self)
self.setGeometry(QRect(100, 100, 600, 250))
self.scene = QGraphicsScene(self)
self.scene.setSceneRect(QRectF())
self.setScene(self.scene)
if __name__ == '__main__':
app = QApplication(sys.argv)
view = MyView()
view.show()
add_objects(scene=view.scene, n=100)
sys.exit(app.exec_())
------ EDIT --------
Since I've been asked for another example, here goes the complete case:
import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from GridCal.Gui.GridEditorWidget import GridEditor
from GridCal.Engine.IO.file_handler import FileOpen
class AddObjectsThreaded(QThread):
def __init__(self, editor: GridEditor, explode_factor=1.0):
QThread.__init__(self)
self.editor = editor
self.explode_factor = explode_factor
def run(self):
"""
run the file open procedure
"""
# clear all
self.editor.diagramView.scene_.clear()
# first create the buses
for bus in self.editor.circuit.buses:
bus.graphic_obj = self.editor.add_api_bus(bus, self.explode_factor)
for branch in self.editor.circuit.branches:
branch.graphic_obj = self.editor.add_api_branch(branch)
# figure limits
min_x = sys.maxsize
min_y = sys.maxsize
max_x = -sys.maxsize
max_y = -sys.maxsize
# Align lines
for bus in self.editor.circuit.buses:
bus.graphic_obj.arrange_children()
# get the item position
x = bus.graphic_obj.pos().x()
y = bus.graphic_obj.pos().y()
# compute the boundaries of the grid
max_x = max(max_x, x)
min_x = min(min_x, x)
max_y = max(max_y, y)
min_y = min(min_y, y)
# set the figure limits
self.editor.set_limits(min_x, max_x, min_y, max_y)
# center the view
self.editor.center_nodes()
if __name__ == '__main__':
app = QApplication(sys.argv)
fname = r'1354 Pegase.xlsx' # this file you need to download from https://github.com/SanPen/GridCal/tree/master/Grids_and_profiles/grids
circuit = FileOpen(fname).open()
view = GridEditor(circuit)
view.resize(600, 400)
view.show()
thr = AddObjectsThreaded(editor=view)
thr.start()
sys.exit(app.exec_())
This process crases cleanly with the following error:
Process finished with exit code -1073740791 (0xC0000409)
from Add objects asynchronously to QGraphicsScene
No comments:
Post a Comment