[PySide] can a QStandardItem emit a signal?

Baz Walter bazwal at gmail.com
Thu Aug 4 17:30:19 CEST 2016


On 04/08/16 05:31, Frank Rueter | OHUfx wrote:
> Hi,
>
> I am writing a custom view for a simple data model and need to have a
> custom widget change it's background colour when it's associated
> QStandardItem has a certain attribute. I thought I'd simply subclass
> QStandardItem, give it the custom attribute, e.g. isSelected, then a
> method called setSelected() which sets the attribute's value and
> emits a selectionChanged signal, to which I can connect the
> associated widget's slot that changes the background colour. So this
> is what I have for the item:
>
> class ElemItem(QtGui.QStandardItem): selectionChanged =
> QtCore.Signal(bool)
>
> def __init__(self, elementData): super(ElemItem,
> self).__init__(elementData) self.isSelected = False self.filePath =
> elementData
>
> def setSelected(self, selected): self.isSelected = selected
> selectionChanged.emit(selected)
>
>
> However, since QStandardItem doesn't inherit QObject it doesn't seem
> to be able to emit a signal. When I try something like this in the
> widget: self.item.selectionChanged.connect(self.markAsSelected)
>
> I get this error: AttributeError: 'PySide.QtCore.Signal' object has
> no attribute 'connect'
>
>
> Is this the entirely wrong way of achieving what I'm after? I can
> achieve what I'm after in other ways but would like to understand
> this hiccup before moving on, so any input would be welcome.

Yes, it is the wrong way. There is already an API that *almost* does 
exactly what you want. If the item has been added to a model, its 
setData() method will emit the model's itemChanged signal whenever the 
value of the data changes. However, this signal is quite poorly 
designed, because although it sends the *item* that changed, it does not 
also send the *role* that changed. If it did the latter, you could just 
set your special attribute using a custom role, and then test for that 
role in a slot connected to the model's itemChanged signal.

It's really a shame that the existing API doesn't work as it should, but 
it shouldn't be too difficult to add a similar API of your own that does 
the right thing. The key is to use the QStandardItem.model() method to 
get access to the parent model (which would then allow you to emit a 
custom signal defined on that model).

--
Regards
Baz Walter



More information about the PySide mailing list