[PyQt] Segfault with QString

Phil Thompson phil at riverbankcomputing.com
Fri Mar 21 11:04:59 GMT 2008


On Friday 21 March 2008, Filip Gruszczyński wrote:
> > It's practically impossible to help if you just post a code fragment. The
> >  problem is almost certain to be in the bits of code you haven't posted.
> >
> >  Try and come up with a simple but complete script that demonstrates the
> >  problem so that other people can reproduce it.
>
> OK, I have created smaller script, that segfaults. Here it is:
>
> #!/usr/bin/python
>
> from PyQt4 import *
> from PyQt4.QtCore import *
> from PyQt4.QtGui import *
> import sys
>
> USE_SILENT = 1
> USE_REQUIRED = 2
>
> class NumericContent:
>
> 	def __init__(self, min = 0, max = 0):
> 		self.min = min
> 		self.max = max
>
> 	def getValues(self):
> 		return range(self.min, self.max + 1)
>
> class Element(QObject):
>
> 	def __init__(self, name, content = None, value = None):
> 		QObject.__init__(self)
> 		self.__name = name
> 		self.__content = content
> 		self.__value = value
>
> 	def getValue(self):
> 		return self.__value
>
> 	def setValue(self, value):
> 		self.__value = value
>
> 	def getName(self):
> 		return self.__name
>
> 	def hasContent(self):
> 		return self.__content != None
>
> 	def getContent(self):
> 		return self.__content
>
> 	def setContent(self, content):
> 		self.__content = content
>
> class Attribute(Element):
>
> 	def __init__(self, name, content):
> 		Element.__init__(self, name, content)
>
> 	def isFinal(self):
> 		return True
>
> 	def getValues(self):
> 		return self.getContent().getValues()
>
> 	def __repr__(self):
> 		return str(self.getName()) + " " + str(self.getValue()) + "\n"
>
> def display():
> 	print str(a.getValue())
>
> if __name__ == "__main__":
> 	app = QApplication(sys.argv)
> 	widget = QWidget()
> 	box = QComboBox()
> 	button = QPushButton("Button")
> 	layout = QHBoxLayout()
> 	layout.addWidget(box)
> 	layout.addWidget(button)
> 	widget.setLayout(layout)
> 	widget.show()
> 	a = Attribute('attr', NumericContent(1, 4))
> 	for i in a.getValues():
> 		box.addItem(QString(str(i)))
> 	box.connect(box, SIGNAL('currentIndexChanged(QString)'), a.setValue);
> 	box.emit(SIGNAL('currentIndexChanged(QString)'), box.currentText())
> 	box.connect(button, SIGNAL('clicked()'), display)
> 	sys.exit(app.exec_())
>
>
>
> To make it segfault, you just have to run it, change value in combo
> box, and push the button. If you don't change the the value in the
> combo box and push the button, it will correctly print the value onto
> the std out.
>
> Furthermore, if you change method
>
> 	def setValue(self, value):
> 		self.__value = value
>
> to
>
> 	def setValue(self, value):
> 		self.__value = str(value)
>
> it works perfectly fine. Can anyone explain me, what have I done wrong?

This is the same issue that came up the other day in the context of events. 
The QString that value is wrapping is a temporary, so you either need to 
convert it (as you do when calling str()) or copy it (by calling QString()).

Phil



More information about the PyQt mailing list