Python 具有任何数据模型的QCompleter是否会导致分段错误?
我为Python 具有任何数据模型的QCompleter是否会导致分段错误?,python,qt,qt4,pyqt,Python,Qt,Qt4,Pyqt,我为QLineEdit创建了QCompleter,如果子类中没有动态定义的函数/方法,它就可以正常工作(尝试在[0,1,2,9]中使用/BugCompleterFilesModel.py nn运行脚本,然后通过删除行编辑框中的一些字符来打开补全器)。QCompleter可以使用QStringList、QStringListModel和QFileSystemModel 如果我在simpleQStringList的QCompleter子类中添加了一些动态定义的函数/方法,那么实例也可以正常工作(尝试
QLineEdit
创建了QCompleter
,如果子类中没有动态定义的函数/方法,它就可以正常工作(尝试在[0,1,2,9]
中使用/BugCompleterFilesModel.py n
n运行脚本,然后通过删除行编辑框中的一些字符来打开补全器)。QCompleter
可以使用QStringList
、QStringListModel
和QFileSystemModel
如果我在simpleQStringList
的QCompleter
子类中添加了一些动态定义的函数/方法,那么实例也可以正常工作(尝试在[10,20,30]
中使用/bugcleterfilesysmodel.py n
n运行脚本,然后尝试通过删除行编辑框中的一些字符来打开补全器)
但是,如果我动态定义了任何函数/方法,则具有任何类型数据模型的QCompleter将在关闭GUI窗口时引发错误:
QObject::startTimer: QTimer can only be used with threads started with QThread
Segmentation fault
若要重复此错误,请尝试使用[1,2,9]
中的/bugcompleterfilesymodel.py mn
m运行脚本,然后尝试通过删除行编辑框中的一些字符来显示补全符,然后关闭窗口
谁能告诉我为什么会这样以及如何修复它?我搔头已经好几个小时了。谢谢你
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()
这可能与删除顺序有关
尝试将
QLineEdit
设置为QCompleter
的父级,以便它被QLineEdit
删除,而不是在它之前被删除。非常感谢!这解决了我的问题。但这是否也意味着我不能在不同的小部件之间共享同一个完成符,因为QLineEdit必须拥有所有权?