Reputation: 2450
I'm developing a software in PyQt to edit tile maps in a game - it has support to lots of things exclusive to my game.
My game mainly has small maps, but I wanted to try doing a bigger map - but unfortunately, my editor seems to be sluggish (at best) with bigger maps - specifically at creation. Each tile in the editor is a label with a image. So I did a 90x90 map on it and used the python profile to understand what was keeping it down.
python -m cProfile Editor.py > profile.log
The lines that reached more than one second in total time are below:
ncalls tottime percall cumtime percall filename:lineno(function)
8205 22.397 0.003 22.397 0.003 {built-in method show}
1 5.09 5.09 37.913 37.913 {built-in method exec_}
1 1.824 1.824 1.824 1.824 {getExistingDirectory}
1 1.038 1.038 1.038 1.038 {question}
Ok, so getExistingDirectory takes the time I take to select the directory, so I'm excluding it.
Turns out show gets called 8205 times! since there are 8100 tiles in the map, I think this is related to it - I made a 90x90 map, which is 8100 tiles. At the same time, there are other controls in the screen and even a palette with 117 elements - all other controls probably sum 200 widgets at least.
So the tiles that are in the central widget are created after I click new file. My question is, is there a away so that show, instead of being called once for each label widget, to be called only once for the bigger widget where they are inside?
update:
Turns out I'm calling show myself at creation of each. I removed the calls! Unfortunately, time went up.
ncalls tottime percall cumtime percall filename:lineno(function)
1 43.588 43.588 53.901 53.901 {built-in method exec_}
1 2.325 2.325 2.325 2.325 {getExistingDirectory}
1 1.447 1.447 1.447 1.447 {question}
2 0.265 0.132 1.773 0.887 Editor.py:59(DrawMap)
8452 0.244 0 0.244 0 {built-in method scaled}
8442 0.227 0 1.233 0 TileXtra.py:319(initTile)
24852 0.221 0 0.221 0 {built-in method connect}
42260 0.128 0 0.128 0 {PIL._imaging.alpha_composite}
42260 0.077 0 0.115 0 Image.py:472(_new)
8452 0.077 0 0.24 0 ImageQt.py:44(__init__)
8452 0.074 0 0.074 0 {fromImage}
42260 0.072 0 0.403 0 Image.py:2033(alpha_composite)
1 0.064 0.064 54.158 54.158 Editor.py:3(<module>)
8452 0.042 0 0.042 0 {method 'encode' of 'ImagingEncoder' objects}
8452 0.038 0 0.132 0 Image.py:530(tobytes)
67740 0.036 0 0.05 0 Image.py:628(load)
24852 0.033 0 0.033 0 {PyQt4.QtCore.SIGNAL}
42664 0.03 0 0.03 0 Image.py:461(__init__)
Upvotes: 4
Views: 7388
Reputation: 2450
OK found solution.
In the draw method of the widget with multiple widgets, make it hidden then showit in pyqt using QWidget.setVisible (self, bool visible)
, like:
class BigWidget(QWidget):
def __init__(self, parent=None, **kwargs):
QWidget.__init__(self, parent, **kwargs)
...
def DrawManyWidgets(self, parent):
self.setVisible(False)
...
self.setVisible(True)
Upvotes: 1