Setting and getting “data” from PyQt widget items?

2020-06-18 09:58发布

This is not so much a question as it is a request for an explanation. I'm following Mark Summerfield's "Rapid GUI Programming with Python and Qt", and I must've missed something because I cannot make sense of the following mechanism to link together a real "instance_item" which I am using and is full of various types of data, and a "widget_item" which represents it in a QTreeWidget model for convenience.

Setting:

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

Getting

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

Stuff like toLongLong() doesn't seem "Pythonic" at all, and why are we invoking Qt.UserRole and QVariant? are the "setData" and "data" functions part of the Qt framework or is it a more general Python command?

2条回答
叼着烟拽天下
2楼-- · 2020-06-18 10:21

There are at least 2 better solutions. In order of increasing pythonicity:

1) You don't need quite so much data type packing

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

2) There is an alternate API to PyQt4 where QVariant is done away with, and the conversion to-from QVariant happens transparently. To enable it, you need to add the following lines before any PyQt4 import statements:

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

Then, your code looks like this:

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

Note that there is also an option sip.setapi('QString', 2) where QString is done away with, and you can use unicode instead.

查看更多
狗以群分
3楼-- · 2020-06-18 10:26

All of these methods -- setData(), data(), toLongLong() are all part of Qt and were originally intended to be used in C++, where they make a lot more sense. I'm not really sure what the author is trying to do here, but if you find yourself doing something terribly un-pythonic, there is probably a better way:

## The setter:
widget_item.instance_item = instance_item

## The getter:
instance_item = widget_item.instance_item

The Qt docs can't recommend this, of course, because there are no dynamic attribute assignments in C++. There are a few very specific instances when you may have to deal with QVariant and other such nonsense (for example, when dealing with databases via QtSQL), but they are quite rare.

查看更多
登录 后发表回答