我想重载QInputDialog
,因为我想将QCombobox
替换为我自己的QCombobox
派生词。我检查了QInputDialog
的源代码,并尝试重载ensureCombobox()
。但是,当我尝试类似的东西时:
class AutoCompleteInputDialog(QtGui.QInputDialog):
def __init__(self, *args, **kwargs):
self.ensureComboBox()
super(AutoCompleteInputDialog, self).__init__(*args, **kwargs)
def ensureComboBox(self):
print "ensureComboBox"
self.comboBox = AutoCompleteComboBox(self)
self.comboBox.hide()
self.comboBox.editTextChanged.connect(self.textChanged)
self.comboBox.currentIndexChanged.connect(self.textChanged)
AutoCompleteInputDialog.getItems(None, "test title", "test label", ["albatross 12", "tiger 12", "item 2", "item 3"])
ensureCombobox
永远不会被调用。
我还尝试定义一个创建QInputDialog
并设置其组合框的静态方法。但它也不起作用。
@staticmethod
def getItem(*args, **kwargs):
dialog = QtGui.QInputDialog()
dialog.comboBox = AutoCompleteComboBox(dialog)
return dialog.getItem(*args, **kwargs)
为完整起见,AutoCompleteCombobox
class AutoCompleteComboBox(QtGui.QComboBox):
def __init__(self, *args, **kwargs):
super(AutoCompleteComboBox, self).__init__(*args, **kwargs)
self.setEditable(True)
self.setInsertPolicy(self.NoInsert)
# self.comp = QtGui.QCompleter([""], self)
self.comp = CustomQCompleter([""], self)
self.comp.setCompletionMode(QtGui.QCompleter.PopupCompletion)
self.comp.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.setCompleter(self.comp)#
self.setModel(["hallo babe", "world", "we", "are babe"])
def setModel(self, strList):
# self.comp.model().setStringList(strList)
self.clear()
self.insertItems(0, strList)
self.comp.setModel(self.model())
def focusInEvent(self, event):
self.clearEditText()
super(AutoCompleteComboBox, self).focusInEvent(event)
class CustomQCompleter(QtGui.QCompleter):
"""
copied from: http://stackoverflow.com/a/7767999/2156909
"""
def __init__(self, *args):#parent=None):
super(CustomQCompleter, self).__init__(*args)
self.local_completion_prefix = ""
self.source_model = None
def setModel(self, model):
self.source_model = model
super(CustomQCompleter, self).setModel(self.source_model)
def updateModel(self):
local_completion_prefix = self.local_completion_prefix
class InnerProxyModel(QtGui.QSortFilterProxyModel):
def filterAcceptsRow(self, sourceRow, sourceParent):
index0 = self.sourceModel().index(sourceRow, 0, sourceParent)
return local_completion_prefix.lower() in self.sourceModel().data(index0).lower()
proxy_model = InnerProxyModel()
proxy_model.setSourceModel(self.source_model)
super(CustomQCompleter, self).setModel(proxy_model)
def splitPath(self, path):
self.local_completion_prefix = path
self.updateModel()
return ""
答案 0 :(得分:4)
为了在PySide或PyQt中重新实现C ++方法,必须至少满足三个条件:
注意,如果第二个条件不成立,那么python中的方法的重新实现永远不会被Qt内部调用,因此几乎没用。 Qt文档应该始终清楚地表明方法是否是虚拟的,例如:
virtual QSize sizeHint() const
因此,由于ensureCombobox
没有满足上述条件,因此应该很清楚重新实现它并不会有效(正如您已经发现的那样)。
但无论如何,对于像输入对话框这样简单的东西,尝试创建子类真的值得花费吗?它只是对话框中的四个小部件......
答案 1 :(得分:2)
好的,问题是当你调用QInputDialog时,它会在C ++中设置子窗口小部件 - 或者在我看来是这样的,所以你不能直接替换你最喜欢的味道。因此,您需要按照所示的更典型的路线:
class AutoCompleteInputDialog(QtGui.QDialog):
def __init__(self, *args, **kwargs):
super(AutoCompleteInputDialog, self).__init__(*args, **kwargs)
self.comboBox = AutoCompleteComboBox(self)
self.va = QtGui.QVBoxLayout(self)
self.va.addWidget(self.comboBox)
self.box = QtGui.QWidget(self)
self.ha = QtGui.QHBoxLayout(self)
self.va.addWidget(self.box)
self.box.setLayout(self.ha)
self.OK = QtGui.QPushButton("OK",self)
self.OK.setDefault(True)
self.cancel = QtGui.QPushButton("Cancel",self)
self.ha.addWidget(self.OK)
self.ha.addWidget(self.cancel)
self.OK.clicked.connect(self.accept)
self.cancel.clicked.connect(self.reject)
结果值存储在acid.comboBox.currentText()
。
答案 2 :(得分:0)
AutoCompleteInputDialog.getItems是一个类方法,在这种情况下,通过继承实际上与QtGui.QInputDialog.getItems相同。重载仅适用于实例方法,通过传递隐式self。所以为了使这个工作,您需要重新实现getItems,或者直接使用该类而没有便利功能:
acid = AutoCompleteInputDialog(parent=None)
#set up options, buttons
answer = acid.exec_()