Virtual column in QTableView?

2024/10/2 14:21:31

I'm started to learning Qt4 Model/View Programming and I have beginner question.

I have simple application which show sqlite table in QTableView:

class Model(QtSql.QSqlTableModel):def __init__(self, parent=None):super(Model, self).__init__(parent)self.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)self.setTable("test")self.select()class App(QtGui.QMainWindow):def __init__(self, model):QtGui.QMainWindow.__init__(self)self.ui = Ui_MainWindow()self.ui.setupUi(self)self.ui.tableView.setModel(model)if __name__ == "__main__":myDb = QtSql.QSqlDatabase.addDatabase("QSQLITE")myDb.setDatabaseName("test.db")if not myDb.open():print 'FIXME'model = Model()app = QtGui.QApplication(sys.argv)window = App(model)window.show()sys.exit(app.exec_())

Here how database looks like:

sqlite> create table test (a INTEGER, b INTEGER, c STRING);
sqlite> insert into test VALUES(1, 2, "xxx");
sqlite> insert into test VALUES(6, 7, "yyy");

So I'm getting something like:

+---+---+-----+
| a | b |  c  |
+---+---+-----+
| 1 | 2 | xxx |
+---+---+-----+
| 6 | 7 | yyy |
+---+---+-----+

Is it possible to modify Model to have in QTableView something like virtual column? For example something like:

+---+---+-----+-----+
| a | b | sum |  c  |
+---+---+-----+-----+
| 1 | 2 |  3  | xxx |
+---+---+-----+-----+
| 6 | 7 | 13  | yyy |
+---+---+-----+-----+

Or maybe I should do it in some other way?

Answer

Yes, you can do that. Although @BrtH's answer is relevant, models are tricky and it's easy to get lost. So I thought a more case in point example would be better.

Personally, I'd use a proxy model derived from QAbstractProxyModel. But, in your case reimplementing QSqlTableModel is also feasible. Below is an implementation for your goal. Note that, it's essential for you to know basics of Model/View methodology so that you understand what each method does.

class Model(QtSql.QSqlTableModel):def __init__(self, parent=None):super(Model, self).__init__(parent)self.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)self.setTable("test")self.select()def columnCount(self, parent=QtCore.QModelIndex()):# this is probably obvious# since we are adding a virtual column, we need one more columnreturn super(Model, self).columnCount()+1def data(self, index, role=QtCore.Qt.DisplayRole):if role == QtCore.Qt.DisplayRole and index.column()==2:# 2nd column is our virtual column.# if we are there, we need to calculate and return the value# we take the first two columns, get the data, turn it to integer and sum them# [0] at the end is necessary because pyqt returns value and a bool# http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qvariant.html#toIntreturn sum(self.data(self.index(index.row(), i)).toInt()[0] for i in range(2))if index.column() > 2:# if we are past 2nd column, we need to shift it to left by one# to get the real valueindex = self.index(index.row(), index.column()-1)# get the value from base implementationreturn super(Model, self).data(index, role)def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):# this is similar to `data`if section==2 and orientation==QtCore.Qt.Horizontal and role==QtCore.Qt.DisplayRole:return 'Sum'if section > 2 and orientation==QtCore.Qt.Horizontal:section -= 1return super(Model, self).headerData(section, orientation, role)def flags(self, index):# since 2nd column is virtual, it doesn't make sense for it to be Editable# other columns can be Editable (default for QSqlTableModel)if index.column()==2:return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabledreturn QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditabledef setData(self, index, data, role):# similar to data.# we need to be careful when setting data (after edit)# if column is after 2, it is actually the column before thatif index.column() > 2:index = self.index(index.row(), index.column()-1)return super(Model, self).setData(index, data, role)
https://en.xdnf.cn/q/70842.html

Related Q&A

Python httplib2, AttributeError: set object has no attribute items

Im playing with the Python library httplib2. The following is my code. import urllib.parse import httplib2httplib2.debuglevel = 1http = httplib2.Http()url = "http://login.sina.com.cn/hd/signin.php…

Atom IDE autocomplete-python not working

I have just installed the Atom IDE and the package autocomplete-python (on Windows). But the package is not working. Do I have to make any setting changes? (I have disabled autocomplete-plus and autoc…

Multiple instances of a class being overwritten at the same time? (Python)

Heres a very simple code I made to demonstrate the problem Im encountering. Whats happening here is that Im creating two different instances of the same class but changing an attribute of one will cha…

how to store binary file recieved by Flask into postgres

I currently have a Flask route that reveives file content via POST, and that stores it on the file system, ex: @app.route(/upload, methods=[POST]) def upload_file():def allowed_file(f):return Truefile …

How can I kill a single shot QtCore.QTimer in PyQt4?

So, in my application, I create a single QtCore.QTimer object and then call the singleShot method on it to evoke a function after say 60 secs. Now, at any given point in time, if I would need to call t…

How to convert list of lists to a set in python so I can compare to other sets?

I have a list users_with_invites_ids_list, formed by loop where I append values to the list, in python that looks like this:...[ObjectId(55119e14bf2e4e010d8b48f2)], [ObjectId(54624128bf2e4e5e558b5a52)]…

How can I create an ODBC connection to SAS?

Im writing a program that needs to access SAS data. Ive downloaded the ODBC drivers for SAS and installed them, but I need to be able to create ODBC connections on the fly, programmatically. The foll…

How to extract links from a page using Beautiful soup

I have a HTML Page with multiple divs like:<div class="post-info-wrap"><h2 class="post-title"><a href="https://www.example.com/blog/111/this-is-1st-post/" t…

Verifying the integrity of PyPI Python packages

Recently there came some news about some Malicious Libraries that were uploaded into Python Package Index (PyPI), see:Malicious libraries on PyPI Malicious modules found into official Python repository…

How to get results from custom loss function in Keras?

I want to implement a custom loss function in Python and It should work like this pseudocode:aux = | Real - Prediction | / Prediction errors = [] if aux <= 0.1:errors.append(0) elif aux > 0.1 &am…