Настройка и получение «данных» из элементов виджетов PyQt?

Это не столько вопрос, сколько просьба объяснить. Я следую «Быстрому графическому программированию на языке Python и Qt» Марка Саммерфилда, и я, должно быть, что-то пропустил, потому что не могу понять следующий механизм, чтобы связать реальный «экземпляр-элемент», который я использую, и полон различных типов данных и «widget_item», который представляет его в модели QTreeWidget для удобства.

Окружение:

widget_item.setData(0, Qt.UserRole, QVariant(long(id(instance_item)))) 

Получение

 widget_item.data(0, Qt.UserRole).toLongLong()[0] 

Вещи вроде toLongLong() не кажутся «Pythonic» вообще, и почему мы вызываем Qt.UserRole и QVariant? являются частью функции setData и «data» частью структуры Qt или это более общая команда Python?

Есть как минимум 2 лучших решения. В порядке возрастания питоничности:

1) Вам не нужна такая упаковка данных

 widget_item.setData(0, Qt.UserRole, QVariant(instance_item)) widget_item.data(0, Qt.UserRole).toPyObject() 

2) Существует альтернативный API для PyQt4, где QVariant покончено, а преобразование в QVariant происходит прозрачно. Чтобы включить его, вам нужно добавить следующие строки перед любыми операциями импорта PyQt4:

 import sip sip.setapi('QVariant', 2) 

Затем ваш код выглядит так:

 widget_item.setData(0, Qt.UserRole, instance_item) widget_item.data(0, Qt.UserRole) # original python object 

Обратите внимание, что есть также опция sip.setapi('QString', 2) где QString покончено, и вы можете использовать unicode вместо этого.

Все эти методы – setData (), data (), toLongLong () – все это часть Qt и изначально предназначались для использования на C ++, где они имеют гораздо больше смысла. Я не совсем уверен, что автор пытается здесь сделать, но если вы обнаружите, что делаете что-то ужасно непитоноязычное, возможно, лучший способ:

 ## The setter: widget_item.instance_item = instance_item ## The getter: instance_item = widget_item.instance_item 

Документы Qt не могут рекомендовать это, конечно, потому что в C ++ нет динамических назначений атрибутов. Есть несколько очень конкретных случаев, когда вам, возможно, придется иметь дело с QVariant и другими подобными глупостями (например, при работе с базами данных через QtSQL), но они довольно редки.