PDA

View Full Version : PyQt4 - QPlainTextEdit: performance when hidding blocks



josemaria.alkala
25th June 2010, 10:05
Morning,
I am making a little text editor in python. As many others have probably done before, I am trying to implement some folding functionality in it.

For each block I want to hide I execute:
_block.setVisible(False)

Afterwards I execute:
self.viewport().update()

I have problems when hiding everything but the first line. The loop hiding more than 80000 plus updating the viewport takes less than second which is perfectly acceptable. But afterthat, the application gets stuck for about 6 minutes showing the message "Not Responding". I cannot interact with application. After that, the result is as expected, with no error messages. And everything works great.

Any suggestion about what I could do to improve this performance?
Might it be a bug?

Kind regards,
José M.

josemaria.alkala
25th June 2010, 10:10
One more thing, after that first execution, next executions take less than second which is exactly what I would expect, from the very beginning.

Cheers,
JM

josemaria.alkala
25th June 2010, 16:36
I have made an experiment with a small file. The problem seem to happen whenever I fold or unfold and the text is bigger than QPlainTextEdit. Any clue about where should I look at?

Cheers,
JM

josemaria.alkala
27th June 2010, 12:02
I keep on trying to spot the problem. I have created my own class by mean of:

class TextEditor(QtGui.QPlainTextEdit):
and I have implemented my own event function which captures key presses:

def event(self, event):
if event.type() == QtCore.QEvent.KeyPress:
if event.key()==QtCore.Qt.Key_Tab:
self.key_tab_pressed.emit()
return True
.....

When I hide most of the text (>80000 blocks) the profiler shows that the event function is called >81000 times taking 0.7sg per call. The cumulative time is about 340sg.

Is there any way to avoid this events to be produced?

Regards,
José M.

josemaria.alkala
27th June 2010, 12:18
Crappy workaround:

It looks like changing the visibility creates events. (I don't have a good understanding of this area). So changing the visilibility of >80000 blocks creates >80000events calls. The workaround is I get the document, I assign an empty document to QPlainTextEdit, afterwards I setVisible(False) to the former document and assign again the document to QPlainTextEdit:

_document = self.document()
self.setDocument(QtGui.QTextDocument())
for _i in xrange(0,80000):
.... setVisible(False)....
self.setDocument(_document)

There has to be a far more elegant solution to this.

Kind regards,
José M.

prof.ebral
27th June 2010, 13:54
have you tried .hide() instead of .setVisible(False) ?

josemaria.alkala
27th June 2010, 14:58
Hi prof.ebral,
QTextBlock doesn't have member: hide.

Thanks anyway,
José M.