Retrieve underlying data object from QAbstractTableModel

Heads up! You've already completed this tutorial.

Paul_B_Hermans | 2020-11-12 03:09:01 UTC | #1

I am struggling with pyqt5 and hoping someone can guide me a bit. I have a class called Student. I want to display a few QTableView (read only) with only 3 columns that shows first_name, last_name and section.

Then, when the user selects 1 or more rows in the tableview and presses a button, I want to get the Student object that was used to create that row, and then use some of its other properties to do stuff.

My problem is that I can't figure out how to get back to the actual Student object that was used to build the table. Here is some snippets of code I have.....hoping someone can clue me in.

python
class Student:
    def __init__(self, section, last_name, first_name, email, sn_folder):
        self.section = section
        self.last_name = last_name
        self.first_name = first_name
        self.email = email
        self.SN_Folder = sn_folder

    def __str__(self):
        return self.full_name()

    def __repr__(self):
        return self.__str__()

    def full_name(self):
        return self.last_name + ", " + self.first_name


class StudentTableModel(QtCore.QAbstractTableModel):

    # students is a list of Student objects.
    def __init__(self, students=None, parent=None):
        super().__init__(parent)

        if students is None:
            self.students = []
        else:
            self.students = students

    def rowCount(self, index=QtCore.QModelIndex()):
        """ Returns the number of rows the model holds. """
        return len(self.students)

    def columnCount(self, index=QtCore.QModelIndex()):
        """ Returns the number of columns the model holds. """
        return 5

    def data(self, index, role=QtCore.Qt.DisplayRole):
        """ Depending on the index and role given, return data. If not
            returning data, return None (PySide equivalent of QT's
            "invalid QVariant").
        """
        if not index.isValid():
            return None

        if not 0 <= index.row() < len(self.students):
            return None

        if role == QtCore.Qt.DisplayRole:
            last_name = self.students[index.row()].last_name
            first_name = self.students[index.row()].first_name
            section = self.students[index.row()].section
            email = self.students[index.row()].email
            sn_folder = self.students[index.row()].SN_Folder

            if index.column() == 0:
                return last_name
            elif index.column() == 1:
                return first_name
            elif index.column() == 2:
                return section
            elif index.column() == 3:
                return email
            elif index.column() == 4:
                return sn_folder
        return None

then in my mainwindow I have a method for the button being clicked:

python
    def go_clicked(self):
        # Get a list of Student Objects ( was used to build the table)
        students = self.selected_course().students

        # Get selected row indices from the tableview
        row_indexes=[]
        for row in self.tblStudents2.selectionModel().selectedRows():
            row_indexes.append(row.row())

        # Attempt to retrieve the actual Student Object that corresponds to the row in the table
        # - this is wrong but it illustrates the idea. It works if I don't allow table to be sorted.
        for index in row_indexes:
            student = students[index]
            print(student)

Thanks in advance for any help you can provide!


Packaging Python Applications with PyInstaller by Martin Fitzpatrick — This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.

More info Get the book

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Retrieve underlying data object from QAbstractTableModel was written by Martin Fitzpatrick .

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt.