Unsolved Clear QTableView Data
-
Hello,
I'm buidling an app that parses data from XML file and show data in a QTableView. The Table is connected to a
QAbstractTableModel
and aQSortFilterProxyModel.
My app as far works well, I press a pushButton, I select an xml file, it gets parsed and the table gets filled with data. I want to be able to import a second file without getting to relaunch the app.
I implemented a
resetData()
in my TableModel() class which does set theself._items
to an empty list, as the below code shows. However, I get errors from the LessThan() ProxyModel method saying thatTypeError: '<' not supported between instances of 'str' and 'NoneType'
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, mlist=None): super(MainWindow, self).__init__() self.Table = QtWidgets.QTableView self.model = TableModel() #QAbstractTableModel subclass self.proxyModel = ProxyModel() #QSortFilterProxyModel subclass self.proxyModel.setsourceModel(self.model) self.Table.setModel(self.proxyModel) self.empty = True def LoadData(self): if not self.empty: self.Table.model().sourceModel().resetData() self.empty = False """ parsing xml and filling Model Data code lines... """ class TableModel(QtCore.QAbstractTableModel): def __init__(self, mlist=None): super(TableModel, self).__init__() self._items = [] if mlist == None else mlist def resetData(self): self._items = []
-
@hachbani
You are causing a sort to comparestr
s againstNone
s. (Because items no longer exist.)In
resetData()
, withself._items = []
you must inform the model/proxies/views that the source model data has been changed. SeeQAbstractItemModel::beginResetModel()
,QAbstractItemModel::endResetModel()
,QAbstractItemModel::modelReset()
. -
I modified my LoadData() method so it looks like this now:
def LoadData(self): if not self.empty: self.Table.model().sourceModel().beginResetModel() self.Table.model().sourceModel().resetData() self.Table.model().sourceModel().endResetModel() self.empty = False
I don't get the ProxyModel errors anymore, but it's been 5minutes that it's runnig (normal execution time is 30 seconds)
-
@hachbani said in Clear QTableView Data:
I don't get the ProxyModel errors anymore
Well that's a start!
I would have put the
beginResetModel()
insidedef resetData(self)
as that's where it belongs when you derive fromQAbstractTableModel
.Is what you show all your code for
class TableModel(QtCore.QAbstractTableModel)
? You must do more than this! See https://doc.qt.io/qt-5/qabstracttablemodel.html#subclassing,rowCount()
etc.? And what is the original "30 seconds" anyway, never mind the "5 minutes", do you have billions of rows??Otherwise, not sure, but you can disable proxy model sorting etc. while you change the underlying model data for speed. But I don't see that's relevant if you are clearing all data.
-
No I have rowCount, columnCount, data, setData, flags and other methods as well in my TableModel class, I've only put the relevant one to my question here.
about the 5 minutes, in other words, It's taking forever for LoadData to run again, it doesn't work. I don' know what he problem is neither how to debug it
-
@hachbani
Well I don't know what the rest of your code. I don't know how your XML parsing goes, and so on.You didn't answer a simple question: how many rows does your model have? If it's not in the billions, I would expect 30 seconds let alone 5+ minutes! Nor do I know why what you have changed would impose a much higher time.
The 5 lines you show in
LoadData()
can hardly take 0.5/5 minutes! So I assume it;s parsing the data and/or putting the lines into your model? One thing --- though I don't think it would be this order of time --- I think it says somewhere it's not good to be populating a model a row at a time if you're doing sorting proxy. See https://doc.qt.io/qt-5/qsortfilterproxymodel.html#dynamicSortFilter-prop.Break your code down. Can't you test without the sorting/filtering? Put in some judicious print outs of time elapsed, you should be able to identify where most of this time is being spent.
-
I have about 1500 rows at my table. I'll try do my best debugging this.
And yes, I'm adding data to my table row by row, is that a bad approach ? I'll document more on this and try to come up with a more clean way to do this.thanks,
-
@hachbani
Nothing in "1,500 rows" should take 30 seconds, let alone 5 minutes. I know that's a broad statement, but you know what i mean! 1,500 lines/nodes of XML is nothing, computers do that in their sleep :)The "adding row by row" potential-slowness is to do with the sorting proxy, as per the link I gave you. (Though like I said I'd be surprised if that had anything near 5 minute overhead.)
You seem to be a reasonable programmer! So don't despair, the time should be east to track down. Find out where it is. For example, comment out adding the lines into the model, just time the XML parsing to start with. Then comment out placing a
QSortFilterProxyModel
on the source model. And so on.I cannot see why clearing out the model data or calling
beginResetModel()
would cause some great degradation in speed.