QDataWidgetMapper и несколько делегатов


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 5

3 ответа:

Вы должны использовать один единственный делегат и обрабатывать поведение различных виджетов в функциях setEditorData и setModelData делегата. Для примера (C++, но прямо вперед) проверьте Эту статью из Qt Quarterly.

Ладно, я понял. (По крайней мере, для меня это работает). Итак, основная идея-это класс (упрощенная версия), который хранит список реальных экземпляров делегата и направляет данные в\из них:

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

Я тоже нашел эту проблему, и это действительно отстой. Я прямо сейчас пытаюсь подкласс QtGui.QDataWidgetMapper чтобы обойти это, подкласс имеет свой собственный addMapping () с аргументом делегата, dict для хранения делегата для каждого виджета и соответствующий мета-делегат, который вызывает соответствующий делегат для каждого случая.

Самое странное в этом то, что проблема также существовала в более ранних версиях Qt 4 в QAbstractItemView (то есть таблицах и деревьях) и позже была исправлена добавление метода 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))