【发布时间】:2017-08-01 16:54:31
【问题描述】:
基础模拟:
你好,
我有什么:
- QAbstractListModel 包含我的项目。
- QListView 将包含单个小部件或委托。
- QListView 中的每个单独项目都需要在小部件中有 3 个可编辑区域。
前言:
我无法弄清楚如何让适当的分层小部件系统正常工作。如果您查看附加的图像,每个绿色框代表我模型中的一个“项目”,以及在我看来用户的一个单独项目,而每个绿色框内的“小部件”上的数据是来自并与模型中的该项目相关。
因此,如果有人在 Widget 1 中编辑 QLineEdit1,我希望模型中的数据将更新 Widget1 相关的项目。
问题:
我不知道如何让多个编辑器在同一个委托中工作。如果我点击项目(QLineEdit),索引当然会与主要的小部件项目(绿色框)相关 - 我找不到任何东西告诉我我点击了绘制的 QLineEdit,所以如果我只是在 createEditor 中返回一个可编辑的 QLineEdit,它只是一个通用的,放置在任何地方,我需要弄清楚它与哪个小部件相关,以便我可以正确更新模型,还可以让编辑器绘制我点击绘制的 QLineEdit 的位置。
我不知道如何让一个好的系统正常工作。我了解代表,我了解 MVC,这一切都很好。我只是不知道我正在尝试做的事情是否可行,或者我需要改变它并做其他事情。如果我确实需要尝试其他东西,我会很感激一些建议。
谢谢。
这里有一些基本代码(现在没有在小部件内绘制单个项目,但已经设置了基础):
import sys
from PySide import QtCore, QtGui
DELEGATE_DATA_ROLE = 37
DELEGATE_INDEX = 0
class ItemWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(ItemWidget, self).__init__(parent=parent)
self.main_layout = QtGui.QVBoxLayout()
self.setLayout(self.main_layout)
class ItemDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
super(ItemDelegate, self).__init__(parent=parent)
def sizeHint(self, option, index):
return QtCore.QSize(80, 80)
def createEditor(self, parent, option, index):
editor = QtGui.QLineEdit(parent)
editor.setFixedWidth(200)
editor.setFixedHeight(50)
return editor
def setEditorData(self, editor, index):
item_str = index.data(QtCore.Qt.DisplayRole)
description = item_str['description']
editor.setValue(description)
def setEditorData(self, editor, index):
print 'running setEditorData'
if index.column() == DELEGATE_INDEX:
print 'delegate'
else:
QtGui.QStyledItemDelegate(self, editor, index)
class ItemModel(QtCore.QAbstractListModel):
def __init__(self, parent=None):
super(ItemModel, self).__init__(parent=parent)
self.items = [
{'one': '1', 'name': 'one', 'thumbnail': 'charlie.jpg', 'description': 'aabb'},
{'two': '2', 'name': 'two', 'thumbnail': 'charlie.jpg', 'description': 'aabb'},
{'three': '3', 'name': 'three', 'thumbnail': 'charlie.jpg', 'description': 'aabb'},
{'four': '4', 'name': 'four', 'thumbnail': 'charlie.jpg', 'description': 'aabb'},
{'five': '5', 'name': 'five', 'thumbnail': 'charlie.jpg', 'description': 'aabb'},
{'six': '6', 'name': 'six', 'thumbnail': 'charlie.jpg', 'description': 'aabb'}
]
def rowCount(self, index):
return len(self.items)
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
if role == QtCore.Qt.DisplayRole:
if 0 <= index.row() < self.rowCount(index):
return self.items[index.row()]
if role == DELEGATE_DATA_ROLE:
item = self.items[index.row()]
return item, item.get('name'), item.get('description'), item.get('thumbnail')
if role == QtCore.Qt.EditRole:
return self.items[index.row()]
def setData(self, index, value, role=QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
self.items[index.row()] = value
self.dataChanged.emit(index, index)
return True
return False
def flags(self, index):
flag = super(ItemModel, self).flags(index)
return flag | QtCore.Qt.ItemIsEditable
class ListView(QtGui.QListView):
def __init__(self, parent=None):
super(ListView, self).__init__(parent=parent)
class TestUI(QtGui.QDialog):
def __init__(self, parent=None):
super(TestUI, self).__init__(parent)
self.main_layout = QtGui.QVBoxLayout()
self.resize(700, 500)
self.view = ListView()
self.item_delegate = ItemDelegate()
self.view.setItemDelegate(self.item_delegate)
self.model = ItemModel()
self.view.setModel(self.model)
self.item_widget = ItemWidget()
self.setLayout(self.main_layout)
self.main_layout.addWidget(self.view)
self.main_layout.addWidget(self.item_widget)
def start():
app = QtGui.QApplication(sys.argv)
ui = TestUI()
ui.show()
ui.setWindowState(QtCore.Qt.WindowActive)
ui.raise_()
app.exec_()
if __name__ == '__main__':
start()
【问题讨论】:
-
你的模型适合你吗?
-
是的,我的模型工作正常 - 现在没有任何显示,直到您双击,因为这只是表明我无法弄清楚如何知道在委托中点击了什么。
-
在
role == QtCore.Qt.DisplayRole中你必须返回一个字符串,但你返回的是一个字典,这对我来说似乎很奇怪。 -
我得到以下信息:imgur.com/a/18XX6
-
再一次,里面什么都没有显示,这只是一个非常基本的视图,没有填充委托绘制的项目 - 随意在角色部分返回一个字符串,但这不是问题所在参考。
标签: qt delegates pyqt4 pyside pyqt5