In Pyside2, when I subclass QSqlTableModel how do I write the data method without generating maximum recursion depth errors?

24 views Asked by At

I have a working application in Pyside2 that displays a QSqlTableModel in a QSqlTableView. Three of the fields display raw seconds, like "6282" meaning six thousand and some seconds into a video. I want to change the appearance of those fields in the displayed table, and in the Word document I extract from them to be in the form "h:mm:ss".

I concluded I had to subclass QSqlTableModel, in particular, the data function in it, to do this. But I'm stuck. See code, with comments noting the place where I'm stuck.

class myQSqlTableModel(PySide2.QtSql.QSqlTableModel):
    def __init__(self, db: QSqlDatabase):
        super().__init__()
        self.DB = db

    def data(self, index, role):
        if not index.isValid():
            return None
        # ********** Stuck right here ***************
        # Below attempts generate maximum recursion depth errors as they eventually call this function over and over
        # self.selectRow(index.row())
        # val = self.record(index.row()).value(index.column())
        # val = index.sibling(index.row(), index.column())
        # item = self.itemData(index)
        # for key in item:
        #     print(f"key is {key}, value is {item[key].ToString()}")

        # The examples for QAbstractTableModel do this by calling an internal function like "_items"
        # which references a two-dimensional list (a list of lists, where the inner list is a list of field values.
        # See https://www.pythonguis.com/faq/remove-and-insertrow-for-martin-fitzpatricks-example/
        # But how do I do that sort of thing with a QSqlTableModel??
        # Or should I be subclassing QSqlTableModel at all, instead of something else?
        # *********** End of Stuck Comment ***********

        if role==Qt.ItemDataRole.DisplayRole:
            # Changing this to format raw seconds as h:mm:ss for some fields
            col_name = self.headerData(index.column(), Qt.Horizontal, Qt.ItemDataRole.DisplayRole)
            if col_name in ['start', 'end', 'duration']:
                x = val
                s = x % 60
                m = (x // 60) % 60
                h = x // 3600
                print("%01d:%02d:%02d" % (h, m, s))
                return "%01d:%02d:%02d" % (h, m, s)
            else:
                return val
        return None

class Ui_ExportWindow(QMainWindow, Ui_ExportWindow):
    def __init__(self, DB):
        super().__init__()
        self.setupUi(self)
        # self.dbFile = settings['dbFile']
        #
        # # Get a valid database setup
        # self.DB = QSqlDatabase.addDatabase("QSQLITE")  # loads the driver for Sqlite
        # self.DB.setDatabaseName(self.dbFile)  # the actual physical file
        # self.DB.open()  # open the DB

        self.DB = DB
        self.dbFile = settings['dbFile']
        self.doc_folder = settings['export_folder']

# Skip a bunch of irrelevant stuff

       # Configure the QtableView for Utterances
        self.umodel = myQSqlTableModel(self.DB)  # Edit triggers are turned off in designer

The application has been working well in production for a year, I'm just trying to add this feature request, which has me very puzzled. I'd really appreciate any advice on where I might be going wrong in this approach.

I researched the web for two days looking at all sorts of posts about customizing displays -- most of which seemed to be about highlighting, and fonts and that sort of thing, rather than transforming the input of an integer into output of a formatted string.

I tried three different ways of accessing the values of the record in the QSqlTableModel, all of which generated recursion errors, and all of which are shown in the sample code.

Thanks in advance!

0

There are 0 answers