Reputation: 5411
My GUI (PyQt5, Python3.6) displays data from an SQLite database, mostly using QTableViews.
I'm unit-testing the application using defined input files, and I want to check whether everything is shown in the GUI at the right place. Now, all the data is in the model attached to the QTableView, not the QTableView itself. And I sometimes use QTableView.hideRow()
to hide some of the columns which are present in the raw data but not desired to be shown in this particular view.
How can I test that everything is displayed in the expected place in the QTableView?
Here's a mini example class I'd like to write unit tests for:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5 import QtSql
from PyQt5.QtWidgets import (QWidget, QTableView, QApplication, QHBoxLayout)
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.resize(400, 150)
self.createConnection()
self.fillTable()
self.createModel()
self.initUI()
def createConnection(self):
self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("test.db")
if not self.db.open():
print("Cannot establish a database connection")
return False
def fillTable(self):
self.db.transaction()
q = QtSql.QSqlQuery()
q.exec_("DROP TABLE IF EXISTS Cars;")
q.exec_("CREATE TABLE Cars (Company TEXT, Model TEXT, Year NUMBER);")
q.exec_("INSERT INTO Cars VALUES ('Honda', 'Civic', 2009);")
q.exec_("INSERT INTO Cars VALUES ('VW', 'Golf', 2013);")
q.exec_("INSERT INTO Cars VALUES ('VW', 'Polo', 1999);")
self.db.commit()
def createModel(self):
self.model = QtSql.QSqlTableModel()
self.model.setTable("Cars")
self.model.select()
def initUI(self):
layout = QHBoxLayout()
self.setLayout(layout)
view = QTableView()
layout.addWidget(view)
view.setModel(self.model)
view.hideRow(1)
def closeEvent(self, e):
if (self.db.open()):
self.db.close()
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I can test the data in the model, of course:
self.assertEqual(model.headerData(0, Qt.Horizontal, Qt.DisplayRole), "Company")
self.assertEqual(model.data(model.index(0, 0), Qt.DisplayRole), "Honda")
etc.
But the model contains 3 rows, whereas my QTableView only has 2 (as the VW Golf row is hidden).
So, is there a way to test the data as shown in the QTableView rather than the data in the model? (In the example class, I want tests to assert that the view only contains 2 rows, and that the Polo row is the second.)
Upvotes: 1
Views: 500
Reputation: 244301
If you want to verify if any index is visible this does not depend on the model because a model is the representation of the data, for example a model can be shared by several views so each view chooses what items to show, to know which index are visible in a QTableView
you must use the isIndexHidden()
method:
from PyQt5 import QtCore, QtWidgets, QtSql
import sys
class Example(QtWidgets.QWidget):
def __init__(self):
super().__init__()
...
def initUI(self):
layout = QtWidgets.QHBoxLayout()
self.setLayout(layout)
self.view = QtWidgets.QTableView()
layout.addWidget(self.view)
self.view.setModel(self.model)
self.view.hideRow(1)
self.items_visible()
def items_visible(self):
for i in range(self.model.rowCount()):
for j in range(self.model.columnCount()):
ix = self.model.index(i, j)
if not self.view.isIndexHidden(ix):
print("{}-{}: {}".format(ix.row(), ix.column(), ix.data()))
def main():
app = QtWidgets.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Upvotes: 1