QDataWidgetMapper和多个委托

时间:2012-04-01 21:04:02

标签: qt pyqt pyside

mapper = QtGui.QDataWidgetMapper()
mapper.setModel(my_table_model)
mapper.addMapping(widgetA, 0) #mapping widget to a column
mapper.addMapping(widgetB, 1) #mapping widget to a column
mapper.setItemDelegate(MyDelegateA(widgetA)) #Hmm. Where is the 'column' parameter?
mapper.setItemDelegate(MyDelegateB(widgetB)) #now itemDelegate is rewritten, MyDelegateB will be used

那么......如何为单个QDataWidgetMapper设置多个代理?据我所知,没有QDataWidgetMapper.setItemDelegateForColumn()或者我是否需要创建一些代理工厂,它将使用适当的代理?

谢谢!

3 个答案:

答案 0 :(得分:4)

您必须使用一个委托,并在委托的setEditorDatasetModelData函数中处理不同窗口小部件的行为方式。举个例子(C ++但是直截了当)检查this article from Qt Quarterly

答案 1 :(得分:3)

好的,我明白了。 (至少,它对我有用)。所以,主要的想法是这个类(一个简化版本),它保存一个真实的委托实例列表并将数据路由到它们:

class DelegateProxy(QtGui.QStyledItemDelegate):

    def __init__(self, delegates, parent=None):
        QtGui.QStyledItemDelegate.__init__(self, parent)
        self.delegates = delegates

    def setEditorData(self, editor, index):
        delegate = self.delegates[index.column()] 
        delegate.setEditorData(editor, index)

    def setModelData(self, editor, model, index):
        delegate = self.delegates[index.column()]
        delegate.setModelData(editor, model, index)

完整的工作示例位于pastebin

答案 2 :(得分:1)

我也发现了这个问题,而且真的很糟糕。我现在正在尝试子类化QtGui.QDataWidgetMapper以便解决这个问题,子类有自己的带有委托参数的addMapping(),用于存储每个窗口小部件的委托的字典,以及调用适当的匹配元委托每个案件的代表。

最奇怪的是QAbstractItemView(即表格和树)中早期版本的Qt 4中也存在问题,后来修复了添加setItemDelegateForColumn()方法,但QDataWidgetMapper没有得到修复。

替代方法可能是使用多个映射器,并在必要时连接它们以使它们保持同步,但它有点混乱,特别是如果您需要许多不同的特殊代表:

mainMapper = QtGui.QDataWidgetMapper()
mainMapper.setModel(my_table_model)

auxMapper1 = QtGui.QDataWidgetMapper()
auxMapper1.setModel(my_table_model)

# If you move the index in the main mapper, the auxiliary will follow
mainMapper.currentIndexChanged.connect(auxMapper1.setCurrentIndex)

mainMapper.addMapping(widgetA, 0) #mapping widget to a column
auxMapper1.addMapping(widgetB, 1) #mapping widget to a column

mainMapper.setItemDelegate(MyDelegateA(widgetA))
auxMapper1.setItemDelegate(MyDelegateB(widgetB))