Ser*_*ele 2 python qt model pyqt qcombobox
有一个QTableView(),其中一列填充了QComboBoxes。问题是如何QTableView()根据字典中的数据选择组合框中的项目
我知道我应该申请,self.combo.setCurrentIndex(self.combo.findText( status_str))但无法理解如何将该变量status_str放入comboBox或放置在代码中应用它的位置。我也无法理解 makecomboBox只有在双击后才会出现。如果没有双击单元格,它必须看起来像任何其他单元格。
代码示例:
data = {"first":{"status":"closed"},"second":{"status":"expired"},"third":{ "status":"cancelled"}}
class ComboDelegate(QItemDelegate):
def __init__(self, parent):
QItemDelegate.__init__(self, parent)
def paint(self, painter, option, index):
self.combo = QComboBox(self.parent())
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
self.combo.addItems(li)
#self.combo.setCurrentIndex(self.combo.findText( status_str ))
if not self.parent().indexWidget(index):
self.parent().setIndexWidget( index, self.combo )
class TableView(QTableView):
def __init__(self, *args, **kwargs):
QTableView.__init__(self, *args, **kwargs)
self.setItemDelegateForColumn(1, ComboDelegate(self))
class MainFrame(QWidget):
def __init__(self):
QWidget.__init__(self)
table = TableView(self)
self.model = QStandardItemModel()
table.setModel(self.model)
MainWindow = QVBoxLayout()
MainWindow.addWidget(table)
self.setLayout(MainWindow)
self.fillModel()
def fillModel(self):
for i in data:
print i
name_str = i
status_str = data[i]["status"]
name = QStandardItem(name_str)
status = QStandardItem(status_str)
items = [name, status]
self.model.appendRow(items)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainFrame()
main.show()
main.move(app.desktop().screen().rect().center() - main.rect().center())
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
重写QItemDelegate.paint不是创建委托的推荐方法。QItemDelegate有诸如createEditor和 之类的方法setEditorData,您应该重写这些方法。这些方法由 Qt 适当调用。
在createEditor你应该创建你的comboBox,并返回它。例如:
def createEditor(self, parent, option, index):
editor = QComboBox(parent)
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
editor.addItems(li)
return editor
Run Code Online (Sandbox Code Playgroud)
在setEditorData您查询模型以获取组合框的当前索引。这将被称为例如:
def setEditorData(self, editor, index):
value = index.model().data(index, Qt.EditRole)
editor.setCurrentIndex(editor.findText(value))
Run Code Online (Sandbox Code Playgroud)
请注意,在此示例中,我依赖于的默认实现QItemDelegate.setModelData()将 的当前文本保存combobox到EditRole. 如果您想做一些更复杂的事情(例如保存combobox索引而不是文本),您可以将数据保存/恢复到不同的角色(例如Qt.UserRole),在这种情况下,您还需要修改在setEditorData方法中获得角色的位置setModelData像这样覆盖:
def setEditorData(self, editor, index):
value = index.model().data(index, Qt.UserRole)
editor.setCurrentIndex(int(value))
def setModelData(self, editor, model, index):
model.setData(index, editor.currentIndex(), Qt.UserRole)
Run Code Online (Sandbox Code Playgroud)
这是上述代码的最小工作示例!请注意,我已关闭对QVariantusing 的支持,sip以便模型返回本机 Python 类型。
import sys
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import *
from PyQt4.QtCore import *
data = {"first":{"status":"closed"},"second":{"status":"expired"},"third":{ "status":"cancelled"}}
class ComboDelegate(QItemDelegate):
def createEditor(self, parent, option, index):
editor = QComboBox(parent)
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
editor.addItems(li)
return editor
def setEditorData(self, editor, index):
value = index.model().data(index, Qt.EditRole)
editor.setCurrentIndex(editor.findText(value))
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.tableview = QTableView()
self.tableview.setItemDelegateForColumn(1, ComboDelegate())
self.setCentralWidget(self.tableview)
self.model = QStandardItemModel()
self.tableview.setModel(self.model)
self.fillModel()
self.show()
def fillModel(self):
for i in data:
name_str = i
status_str = data[i]["status"]
name = QStandardItem(name_str)
status = QStandardItem(status_str)
items = [name, status]
self.model.appendRow(items)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
我刚刚注意到您关于comboBox双击后自动显示的另一个问题。我有一个 hack 来做我以前用过的。它依赖于将视图传递给委托并将以下几行添加到createEditor方法中:
editor.activated.connect(lambda index, editor=editor: self._view.commitData(editor))
editor.activated.connect(lambda index, editor=editor: self._view.closeEditor(editor,QAbstractItemDelegate.NoHint))
QTimer.singleShot(10,editor.showPopup)
Run Code Online (Sandbox Code Playgroud)
完整的工作示例:
import sys
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import *
from PyQt4.QtCore import *
data = {"first":{"status":"closed"},"second":{"status":"expired"},"third":{ "status":"cancelled"}}
class ComboDelegate(QItemDelegate):
def __init__(self, view):
QItemDelegate.__init__(self)
self._view = view
def createEditor(self, parent, option, index):
editor = QComboBox(parent)
li = []
li.append("closed")
li.append("expired")
li.append("cancelled")
li.append("waiting")
editor.addItems(li)
editor.activated.connect(lambda index, editor=editor: self._view.commitData(editor))
editor.activated.connect(lambda index, editor=editor: self._view.closeEditor(editor,QAbstractItemDelegate.NoHint))
QTimer.singleShot(10,editor.showPopup)
return editor
def setEditorData(self, editor, index):
value = index.model().data(index, Qt.EditRole)
editor.setCurrentIndex(editor.findText(value))
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.tableview = QTableView()
self.tableview.setItemDelegateForColumn(1, ComboDelegate(self.tableview))
self.setCentralWidget(self.tableview)
self.model = QStandardItemModel()
self.tableview.setModel(self.model)
self.fillModel()
self.show()
def fillModel(self):
for i in data:
name_str = i
status_str = data[i]["status"]
name = QStandardItem(name_str)
status = QStandardItem(status_str)
items = [name, status]
self.model.appendRow(items)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1092 次 |
| 最近记录: |