0

我创建QCompleters for QLineEdit,如果子类中没有动态定义的函数/方法,它工作正常(尝试使用./bugCompleterFilesysModel.py nn in运行脚本[0, 1, 2, 9],然后尝试通过删除 LineEdit 框中的一些字符来显示完成者)。QCompleter可以与QStringListQStringListModel和一起使用QFileSystemModel

QCompleter如果我使用of simple在子类中添加一些动态定义的函数/方法QStringList,则实例也可以正常工作(尝试使用./bugCompleterFilesysModel.py nn in运行脚本[10, 20, 30],然后尝试通过删除 LineEdit 框中的一些字符来显示完成者)。

但是,如果我动态定义任何函数/方法,具有任何类型数据模型的 QCompleter 在关闭 GUI 窗口期间将引发错误:

QObject::startTimer: QTimer can only be used with threads started with QThread
Segmentation fault

要重复错误,请尝试使用./bugCompleterFilesysModel.py mnm 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()
4

1 回答 1

1

这可能与删除顺序有关。

尝试将 设置QLineEdit为 的父级QCompleter,以便它被删除QLineEdit而不是在它之前被删除。

于 2012-12-26T11:10:12.093 回答