[PyQt] Segfault when trying newDoc.setDocumentLayout(QtGui.QPlainTextDocumentLayout(newDoc))

Phil Thompson phil at riverbankcomputing.com
Mon Feb 2 13:32:39 GMT 2009


On Mon, 02 Feb 2009 13:49:23 +0100, GT6 <gt6 at gmx.net> wrote:
> Phil Thompson wrote:
>> On Mon, 02 Feb 2009 03:37:13 +0100, GT6 <gt6 at gmx.net> wrote:
>>   
>>> Hi there.
>>>
>>> When running the below sample script, and clicking the button, it will
>>> segfault, and I don't understand why or how. I've overwritten a
function
>>> in QPlainTextEdit and it should create a new document, set the
>>> PlainTextDocumentLayout and then set the document on the QPlainTextEdit
>>> widget. The important part is this (1st way):
>>>
>>>         newDoc = QtGui.QTextDocument()
>>>        
newDoc.setDocumentLayout(QtGui.QPlainTextDocumentLayout(newDoc))
>>>         self.setDocument(newDoc)
>>>
>>> The above segfaults. I also tried this (2nd way):
>>>
>>>             newDoc = QtGui.QTextDocument()
>>>             newDoc.setDocumentLayout(self.documentLayout())
>>>             self.setDocument(newDoc)
>>>
>>> This one doesn't segfault, but I get this error:
>>>
>>> AttributeError: documentLayout
>>>
>>> Apart from that, I tried this third option (3rd way):
>>>
>>>         newDoc = QtGui.QTextDocument()
>>>
>>>
newDoc.setDocumentLayout(QtGui.QPlainTextDocumentLayout.__init__(newDoc))
>>>         self.setDocument(newDoc)
>>>
>>> with the only difference from the first one being that __init__ is
>>> called explicitly instead of expecting it to be defaultet. This one
>>> _doesn't_ segfault, but gives this error:
>>>
>>> QPlainTextEdit::setDocument: Document set does not support
>>> QPlainTextDocumentLayout
>>>
>>> Which makes no sense as not calling __init__ directly shouldn't be any
>>> different than calling it explicitly.
>>>     
>>
>> __init__() initialises a class, it doesn't create one.
>>
>>   
>>> So, does anyone have any idea why
>>> this is happening? Do you have a bug tracker?
>>>     
>>
>> Keep a reference to "newDoc" - it is getting garbage collected too soon.
>>
>> Phil
>>
>>   
> Thanks for your help.
> 
> Well, that only works once. So I replace the plzsegfault function in the 
> sample with this (full sample binned here
http://rafb.net/p/P6sqML59.html):
> 
>     def plzsegfault(self):
>         self.newDoc = QtGui.QTextDocument()
>         
>
self.newDoc.setDocumentLayout(QtGui.QPlainTextDocumentLayout(self.newDoc)) 
> # First way
>         self.setDocument(self.newDoc)
> 
> Then, I can safely click the button once, and it also does what I expect 
> it to do, but clicking the button a second time will again segfault.
> What I'm trying to do is that clicking the button will clear the 
> textfield and make a new document and display it. Do I really have to 
> care about the document names? I *could* implement a counter and have 
> all the documents have different names but I don't really need those 
> specific names in the future. I just need the textfield to discard the 
> old one and get a new one, everytime the button is clicked. The only 
> reference to the document that I use lateron is self.document(). I don't 
> need the name...

You might not but Python needs a reference of some sort to stop the object
being garbage collected.

Your new version is still garbage collecting too soon. Just add the
following to the end of plzsegfault() in your *original* version...

    self._doc = newDoc

Phil


More information about the PyQt mailing list