Search code examples
databasepyqtpyqt5blobqtsql

PyQt load database in tableview


I have some issues with loading correctly databases in a tableview in my pyqt ui. The problem is that these specific databases have column that contains BLOB data and they are not displayed correctly in tableview. Opening the same database with sqlitebrowser for windows displays the items of the blob column as a text field with multiple values(double clicking it reveals all), while in my tableview it only displays the first letter of the the first item. tableview Any way to replicate the sqlitebrowser software and display the blob correctly and display items as a dropdown with full values? sqlitebrowser

this is the code I use for loading the database:

def loadevents(self, str):
        db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName(str)
        db.open()
        print('database is '+str)
        projectModel = QtSql.QSqlQueryModel()
        projectModel.setQuery("SELECT  * FROM tblEvents")
        self.tableWidget.setModel(projectModel)
        self.tableWidget.show()

As described I would like that the last column that is of BLOB type(detail) to be loaded correctly (all text) and if possibily to display allsub items of each items in detail column as a dropdown list. ex: in sqlitebrowser doubleclicking "Updated completed successfully..." reveals multiple values.

Thanks in advance.

LE: modified code:

        self.tableWidget = QtWidgets.QTableView(self.tab_3)
        self.tableWidget.setGeometry(QtCore.QRect(50, 13, 1000, 800))
        self.tableWidget.setMinimumSize(QtCore.QSize(1000, 800))
        self.tableWidget.setMaximumSize(QtCore.QSize(1000, 800))
        self.tableWidget.setObjectName("tableWidget")

is part of a function of a class called Ui_MainWindow(object) - basicaly the class we instantiate for the window

in the same class I have another function that populates the tableview:

def loadevents(self, str):
        db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName(str)
        db.open()
        self.tableWidget.horizontalHeader().setStretchLastSection(True)
        delegate = BlobDelegate(self.tableWidget)
        self.tableWidget.setItemDelegateForColumn(4, delegate)
        model = QtSql.QSqlQueryModel()
        model.setQuery("SELECT  * FROM tblTransEvents")
        self.tableWidget.setModel(model)
        self.tableWidget.show()

and it looks like this: newtableview


Solution

  • You must implement a delegate that decodes the Blob data:

    import os
    from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
    
    
    class BlobDelegate(QtWidgets.QStyledItemDelegate):
        def displayText(self, value, locale):
            if isinstance(value, QtCore.QByteArray):
                value = value.data().decode()
            return super(BlobDelegate, self).displayText(value, locale)
    
    
    def createConnection():
        db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
        file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "db.db")
        db.setDatabaseName(file)
        if not db.open():
            QtWidgets.QMessageBox.critical(
                None,
                QtWidgets.qApp.tr("Cannot open database"),
                QtWidgets.qApp.tr(
                    "Unable to establish a database connection.\n"
                    "This example needs SQLite support. Please read "
                    "the Qt SQL driver documentation for information "
                    "how to build it.\n\n"
                    "Click Cancel to exit."
                ),
                QtWidgets.QMessageBox.Cancel,
            )
            return False
        return True
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
    
        if not createConnection():
            sys.exit(-1)
    
        w = QtWidgets.QTableView()
        w.horizontalHeader().setStretchLastSection(True)
        w.setWordWrap(True)
        w.setTextElideMode(QtCore.Qt.ElideLeft)
        delegate = BlobDelegate(w)
        w.setItemDelegateForColumn(4, delegate)
        model = QtSql.QSqlQueryModel()
        model.setQuery("SELECT * FROM tblEvents")
        w.setModel(model)
        w.resize(640, 480)
        w.show()
    
        sys.exit(app.exec_())
    

    enter image description here