[PyQt] QCompleter with any data Model will cause Segmentation fault in pyQt4?
^_^Sisyphus^_^
freesisyphuswang at gmail.com
Tue Dec 25 12:46:04 GMT 2012
Dear all,
I create *QCompleter*s for *QLineEdit*, which work fine if there is no
dynamically defined function/method in the subclasses (try to run the
script with *./bugCompleterFilesysModel.py n* n in [0, 1, 2, 9], then try
to bring up the completer by deleting some char in the LineEdit box). The
QCompleter can work with *QStringList*, *QStringListModel*, and *
QFileSystemModel*.
If I add some dynamically defined function/method in the subclass with
QCompleter of simple *QStringList*, the instances work fine too (try to run
the script with *./bugCompleterFilesysModel.py* n n in [10, 20, 30], then
try to bring up the completer by deleting some char in the LineEdit box).
However, if I defined any function/method dynamically, the QCompleter with
any kind of *data model*, will *raise an error* during closing the GUI
window:
QObject::startTimer: QTimer can only be used with threads started with
QThreadSegmentation fault
To repeat the error, try to run the script with *./bugCompleterFilesysModel.py
mn* m in [1,2,3], n in [1, 2, 9], then try to bring up the completer by
deleting some char in the LineEdit box, then close the window.
Can anyone tell my why is that and how to fix it? I have been scratching my
head for hours.
Thanks ahead!
Full script of *bugCompleterFilesysModel.py*:
#!/usr/bin/env python# -*- coding: UTF-8 -*-class MyBaseWidget(QtGui.QWidget):
dirChanged=QtCore.pyqtSignal(QtCore.QString)
def __init__(self,parent=None,addfunc0=False,*args,**kwargs):
super(MyBaseWidget, self).__init__(parent)
self.addfunc0=addfunc0
self.func0=None
self.dummyWgt=1
self.initUI()
def initUI(self,*args,**kwargs):
addfunc0=self.addfunc0
if addfunc0 == 1:
self.func0=self.funcFactory0('1')
_func0str="self.funcFactory0('1')"
if addfunc0 == 2:
self.func0=self.funcFactory1('1')
_func0str="self.funcFactory1('1')"
if addfunc0 == 3:
self.func0=self.funcFactory1b()
_func0str="self.funcFactory1b()"
if addfunc0 > 0:
#print self.printWgt
print 'use %s as func0'%(_func0str)
print 'self.func0 = %s'%(self.func0)
self.func0()
self.show()
def printWgt(self,wgt0):
print 'Input obj is:', wgt0.__class__.__name__
def funcFactory0(self,wgt0):
def _func():
self.printWgt(wgt0)
return _func
def funcFactory1(self,wgt0):
import types
def _func(self):
self.printWgt(wgt0)
return types.MethodType(_func,self,mainWidget)
def funcFactory1b(self):
import types
def _func(self):
self.printWgt(self.dummyWgt)
return types.MethodType(_func,self,mainWidget)
class StringWidget(MyBaseWidget):
dirChanged=QtCore.pyqtSignal(QtCore.QString)
def initUI(self,*args,**kwargs):
currdir=r'/tmp'
self.currdir=currdir
self._tb=[]
completer=QtGui.QCompleter(QtCore.QStringList(['/tmp/'+i for i
in 'abcdefg']), parent=self)
completer.setMaxVisibleItems(5)
self.completer=completer
_tb=QtGui.QLineEdit(currdir)
_tb.setCompleter(completer)
theLayout=QtGui.QHBoxLayout(self)
theLayout.addWidget(_tb)
self._tb=_tb
MyBaseWidget.initUI(self,*args,**kwargs)
class StringModelWidget(MyBaseWidget):
dirChanged=QtCore.pyqtSignal(QtCore.QString)
def initUI(self,*args,**kwargs):
currdir=r'/tmp'
self.currdir=currdir
self._tb=[]
fsModel=QtGui.QStringListModel(['/tmp/'+i for i in 'abcdefg'])
self.fsModel=fsModel
#self.fsModel.setParent(self)
completer=QtGui.QCompleter()
completer.setMaxVisibleItems(5)
completer.setModel(fsModel)
self.fsModel.setParent(completer)
self.completer=completer
_tb=QtGui.QLineEdit(currdir)
_tb.setCompleter(completer)
theLayout=QtGui.QHBoxLayout(self)
theLayout.addWidget(_tb)
self._tb=_tb
MyBaseWidget.initUI(self,*args,**kwargs)
class FileModelWidget(MyBaseWidget):
dirChanged=QtCore.pyqtSignal(QtCore.QString)
def initUI(self,*args,**kwargs):
currdir=r'/tmp'
self.currdir=currdir
self._tb=[]
fsModel=QtGui.QFileSystemModel(parent=self)
fsModel.setRootPath('')
fsModel.setFilter(QtCore.QDir.AllDirs|QtCore.QDir.Dirs)
self.fsModel=fsModel
#self.fsModel.setParent(self)
completer=QtGui.QCompleter(parent=self)
completer.setMaxVisibleItems(5)
completer.setModel(fsModel)
self.fsModel.setParent(completer)
self.completer=completer
_tb=QtGui.QLineEdit(currdir)
_tb.setCompleter(completer)
theLayout=QtGui.QHBoxLayout(self)
theLayout.addWidget(_tb)
self._tb=_tb
MyBaseWidget.initUI(self,*args,**kwargs)
class mainWidget(MyBaseWidget):
def initUI(self,*args,**kwargs):
self.mainLayout=QtGui.QVBoxLayout(self)
self.wgts=[]
_wgt0=StringWidget(self)
self.wgts.append(_wgt0)
_wgt1=StringModelWidget(self)
self.wgts.append(_wgt1)
_wgt2=FileModelWidget()
self.wgts.append(_wgt2)
for _w in self.wgts:
print _w
self.mainLayout.addWidget(_w)
MyBaseWidget.initUI(self,*args,**kwargs)
def main():
app = QtGui.QApplication(sys.argv)
argv=sys.argv
mainWgt = None
if len(argv)>1:
nwgt = int(sys.argv[1])
_addfunc0=nwgt/10
_nwgt=nwgt-_addfunc0*10
print _nwgt,_addfunc0
if _nwgt == 0:
_MainWgt=StringWidget
if _nwgt == 1:
_MainWgt=StringModelWidget
if _nwgt == 2:
_MainWgt=FileModelWidget
if _nwgt == 9:
_MainWgt=mainWidget
print 'use %s as main widget'%(_MainWgt.__name__)
mainWgt=_MainWgt(addfunc0=_addfunc0)
else:
mainWgt = mainWidget(addfunc0=0)
if mainWgt:
sys.exit(app.exec_())
if __name__ == '__main__':
main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20121225/0f009d3a/attachment-0001.html>
More information about the PyQt
mailing list