[PySide] Form dialog subclassing QDialog

Jérôme jerome at jolimont.fr
Wed Mar 26 16:49:05 CET 2014


Hi Aaron and others.

In your example code, how do you get the value of the selected index,
for example to feed it to a remove or edit function ?

I do the following:

When remove, edit or copy button is pressed, I get the selected row
index, and it refers to the index of my item in the model's "items" list
attribute .

To illustrate this with your example, item is a Person, and the model
PersonTableModel lists its items in its self.persons attribute.

            # Get first selected row. If none, exit.
            # (In practice, I disable multiple selection so only 0 or 1
item selected)
            selected = self.tableView.selectedIndexes()
            if selected == []: 
                return
            index = selected[0].row()
            
            # Remove
            if action == 'Remove':
                self.model.remove(index)
                return
            
            # Edit or Copy
            # Get item from row index
            item = self.model.items[index]
            ...

This used to work, until I added a QSortFilterProxyModel. Now, the rows
can be moved about, but the index in self.persons does not change
accordingly, so the row index here is not necessarily the index in the
item list.

What I need is a way to get from the selection in the view not only to
the QStandardItem in the model, but to the corresponding item in the
source list.

I can obtain the QStandardItem

index = selected[0]
item = QStandardItemModel.itemFromIndex(index)

but I still need to associate this QStandardItem with an element of
self.persons.

This is how you proposed to create the items :

>         self.persons = persons
>         for i in xrange(len(self.persons)):
>             person = self.persons[i]
>             self.setItem(i, 0, QStandardItem(person.name))
>             self.setItem(i, 1, QStandardItem(str(person.age)))

Apparently, when sorting, the rows are modified and so the current row
is not the item's index in self.persons anymore.

Is the link from the row index to the source data (index in
self.persons) broken ?

Do I need to go through self.persons until I find an item (a person)
with the same "name" attribute ?

There may even be cases where two elements may have the same name. This
example is not great, but there are other cases where it could happen,
anyway, I'd rather not rely on this name field. So I'd need to create a
new unique ID column and hide that from the view. I can see how to do
that.

Another way could be to use setData to add a reference to the Person
item in a QStandardItem if the row, like this:

             item = QStandardItem(person.name)
             item.setData(person, role = something)
             self.setItem(i, 0, item)
             self.setItem(i, 1, QStandardItem(str(person.age)))

but this sounds totally twisted.

Thanks for any advice. The more I think of it, the mode it seems that
the only way is to add a (hidden or not) ID column.

Overall, I think my problems are due to the fact that I don't rely
solely on Qt's Model/View architecture: I keep the data in this
self.persons attribute list.

As we said in another message in this thread, these lists could be
removed and the data could be kept only in QStandardItem instances, but
then I'd need to be able to store everything in this form, even data
that I don't know how and don't want to display in views. My approach is
different, I store everything in python classes, and when I need a user
interaction, I set a model to display what I want to display, and this
only, and I trash that model when I'm done.

-- 
Jérôme




More information about the PySide mailing list