下面的代码创建一个QTableView
。双击它的项目将使用委托的QComboBox
设置它。
问题
当单击ComboBox
时,它的下拉菜单会瞬间显示,然后它会折叠回其展开状态。
如果使用comboBox
将combox.setEditable(True)
设置为可编辑,则下拉菜单将按需要保持打开状态。但是,combobox
的项目变得可编辑,而不是所需要的。因为combobox
的项目只能被选择。
如何修复自我崩溃的combobox
的行为?
附注:我注意到当ComboBox
被设置为可编辑并展开它的下拉菜单时,模型的data()
经常被调用.自我崩溃行为很可能是由模型引发的吗?
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class ComboDelegate(QItemDelegate):
comboItems=['Combo_Zero', 'Combo_One','Combo_Two']
def createEditor(self, parent, option, proxyModelIndex):
combo = QComboBox(parent)
combo.addItems(self.comboItems)
# combo.setEditable(True)
self.connect(combo, SIGNAL("currentIndexChanged(int)"), self, SLOT("currentIndexChanged()"))
return combo
def setModelData(self, combo, model, index):
comboIndex=combo.currentIndex()
text=self.comboItems[comboIndex]
model.setData(index, text)
print '\t\t\t ...setModelData() 1', text
@pyqtSlot()
def currentIndexChanged(self):
self.commitData.emit(self.sender())
class MyModel(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items=['Data_Item01','Data_Item02','Data_Item03']
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
row=index.row()
item=self.items[row]
if row>len(self.items): return QVariant()
if role == Qt.DisplayRole:
print ' << >> MyModel.data() returning ...', item
return QVariant(item)
def flags(self, index):
return Qt.ItemIsEditable | Qt.ItemIsEnabled
def setData(self, index, text):
self.items[index.row()]=text
if __name__ == '__main__':
app = QApplication(sys.argv)
model = MyModel()
tableView = QTableView()
tableView.setModel(model)
delegate = ComboDelegate()
tableView.setItemDelegate(delegate)
tableView.resizeRowsToContents()
tableView.show()
sys.exit(app.exec_())
发布于 2015-01-21 23:00:48
您的原始代码在PyQt5中工作,combobox
保持打开。但是用户必须单击以打开编辑器,然后单击以打开combobox
。为了避免这种情况,我在代码中将QComboBox
替换为QlistWidget
。另外,我设置了editorGeometry
import sys
# from PyQt4.QtCore import *
# from PyQt4.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class ComboDelegate(QItemDelegate):
editorItems=['Combo_Zero', 'Combo_One','Combo_Two']
height = 25
width = 200
def createEditor(self, parent, option, index):
editor = QListWidget(parent)
# editor.addItems(self.editorItems)
# editor.setEditable(True)
editor.currentItemChanged.connect(self.currentItemChanged)
return editor
def setEditorData(self,editor,index):
z = 0
for item in self.editorItems:
ai = QListWidgetItem(item)
editor.addItem(ai)
if item == index.data():
editor.setCurrentItem(editor.item(z))
z += 1
editor.setGeometry(0,index.row()*self.height,self.width,self.height*len(self.editorItems))
def setModelData(self, editor, model, index):
editorIndex=editor.currentIndex()
text=editor.currentItem().text()
model.setData(index, text)
# print '\t\t\t ...setModelData() 1', text
@pyqtSlot()
def currentItemChanged(self):
self.commitData.emit(self.sender())
class MyModel(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items=['Data_Item01','Data_Item02','Data_Item03']
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
row=index.row()
item=self.items[row]
if row>len(self.items): return QVariant()
if role == Qt.DisplayRole:
# print ' << >> MyModel.data() returning ...', item
return QVariant(item)
def flags(self, index):
return Qt.ItemIsEditable | Qt.ItemIsEnabled
def setData(self, index, text):
self.items[index.row()]=text
if __name__ == '__main__':
app = QApplication(sys.argv)
model = MyModel()
tableView = QTableView()
tableView.setModel(model)
delegate = ComboDelegate()
tableView.setItemDelegate(delegate)
for i in range(0,tableView.model().rowCount()):
tableView.setRowHeight(i,tableView.itemDelegate().height)
for i in range(0,tableView.model().columnCount()):
tableView.setColumnWidth(i,tableView.itemDelegate().width)
tableView.show()
sys.exit(app.exec_())
发布于 2015-01-20 05:00:36
下面是用链接到QComboBox
和QAction
的QToolButton
替换QMenu
的尝试。
外观和感觉与QComboBox
大致相同,还有一个附加功能,即能够设置多个选中的QActions
(目前不可能检查多个组合框的项)。
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class ComboDelegate(QItemDelegate):
comboItems=['Combo_Zero', 'Combo_One','Combo_Two']
def __init__(self, parent):
QItemDelegate.__init__(self, parent=None)
self.actionEmitted=None
def createEditor(self, parent, option, index):
if not index.isValid(): return
model=index.model()
itemName=model.data(index, Qt.DisplayRole)
toolButton=QToolButton(parent)
toolButton.setText( itemName.toString() )
toolButton.setPopupMode(QToolButton.InstantPopup)
menu=QMenu(parent)
action1=QAction('Action 01', menu, checkable=True)
action2=QAction('Action 02', menu, checkable=True)
action3=QAction('Action 03', menu, checkable=True)
action1.setObjectName('Action 01')
action2.setObjectName('Action 02')
action3.setObjectName('Action 03')
action1.setChecked(True)
action3.setChecked(True)
self.connect(action1, SIGNAL("triggered(bool)"), self, SLOT("actionTriggered()"))
self.connect(action2, SIGNAL("triggered(bool)"), self, SLOT("actionTriggered()"))
self.connect(action3, SIGNAL("triggered(bool)"), self, SLOT("actionTriggered()"))
menu.addAction(action1)
menu.addAction(action2)
menu.addAction(action3)
toolButton.setMenu(menu)
return toolButton
def setModelData(self, toolButton, model, index):
print '\t\t\t ...setModelData() 1', toolButton, model, index
if not self.actionEmitted: return
menu=toolButton.menu()
for action in menu.actions():
actionName=action.objectName()
actionStatus=action.isChecked()
if actionStatus:
model.setData(index, actionName)
print '####', actionName, actionStatus
@pyqtSlot()
def actionTriggered(self):
self.actionEmitted=self.sender()
self.commitData.emit( self.actionEmitted )
print 'actionTriggered.....', self.actionEmitted
class MyModel(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items=['Data_Item01','Data_Item02','Data_Item03']
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
row=index.row()
item=self.items[row]
if row>len(self.items): return QVariant()
if role == Qt.DisplayRole:
print ' << >> MyModel.data() returning ...', item
return QVariant(item)
def flags(self, index):
return Qt.ItemIsEditable | Qt.ItemIsEnabled
def setData(self, index, itemName):
self.items[index.row()]=itemName
if __name__ == '__main__':
app = QApplication(sys.argv)
combo=QComboBox()
combo.addItems(['Combo_Zero', 'Combo_One','Combo_Two'])
model = MyModel()
tableView = QTableView()
tableView.setModel(model)
delegate = ComboDelegate(tableView)
tableView.setItemDelegate(delegate)
tableView.resizeRowsToContents()
tableView.show()
sys.exit(app.exec_())
https://stackoverflow.com/questions/28037126
复制相似问题