[PyQt] QCompleter with any data Model will cause Segmentation fault in pyQt4?

Robert Kent rob at gulon.co.uk
Wed Dec 26 10:42:00 GMT 2012


What OS, python version and PyQt version are you using? I'm running OSX10.8, python 2.7 and PyQt 4.9.6 and I can't reproduce your error.

On 25 Dec 2012, at 12:46, "^_^Sisyphus^_^" <freesisyphuswang at gmail.com> wrote:

> Dear all,
> 
> I create QCompleters 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 QThread
> Segmentation 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()
> 
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20121226/9a209925/attachment-0001.html>


More information about the PyQt mailing list