我创建QCompleter
s for QLineEdit
,如果子类中没有动态定义的函数/方法,它工作正常(尝试使用./bugCompleterFilesysModel.py n
n in运行脚本[0, 1, 2, 9]
,然后尝试通过删除 LineEdit 框中的一些字符来显示完成者)。QCompleter
可以与QStringList
、QStringListModel
和一起使用QFileSystemModel
。
QCompleter
如果我使用of simple在子类中添加一些动态定义的函数/方法QStringList
,则实例也可以正常工作(尝试使用./bugCompleterFilesysModel.py n
n in运行脚本[10, 20, 30]
,然后尝试通过删除 LineEdit 框中的一些字符来显示完成者)。
但是,如果我动态定义任何函数/方法,具有任何类型数据模型的 QCompleter 在关闭 GUI 窗口期间将引发错误:
QObject::startTimer: QTimer can only be used with threads started with QThread
Segmentation fault
要重复错误,请尝试使用./bugCompleterFilesysModel.py mn
m in [1,2,3]
、 n in运行脚本[1, 2, 9]
,然后尝试通过删除 LineEdit 框中的一些字符来调出完成程序,然后关闭窗口。
谁能告诉我这是为什么以及如何解决?我已经挠头好几个小时了。提前谢谢!
完整脚本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()