PDA

View Full Version : Large number of rows for QTableView and QAbstractTableModel



omit02
3rd December 2016, 08:28
I'm fairly new to Qt. Initially I was using QTableWidget with 10000 rows, and had a bunch of signal/slots per row, and the performance was terrible.

But now, I have a QTableView working using a subclassed QAbstractTableModel. I'm looking at the documentation but am confused as to how the memory management works for large amounts of data.

How are rows "de-allocated" and do I need to "disconnect" the signal/slots for scrolled-off rows to keep the total active signal/slots low?

anda_skoa
3rd December 2016, 12:06
The table view does not "allocated" for rows that are being displayed.
It basically determines which rows need to be draw, draws the grid and then delegates drawing of the cells to its item delegates, passing info on the cell to the delegate as it goes through the visible cells.

There are also no per-cell or per-row signals, just signals of the view which in turn contain information about the cell for which an even happened.

Cheers,
_

omit02
3rd December 2016, 16:44
Okay, thanks. I plan on adding checkboxes in some columns which I essentially want to modify the sourcing database. After scrolling through my 10,000 rows, will performance not go down because I might have 4 x 10,000 signals I am connecting? I did get QTableWidget working, and after clicking a checkbox, it took a few seconds for the checkbox to respond.

anda_skoa
3rd December 2016, 21:45
Instead of checkboxes, make these columns user checkable by returning the respective flag from your model's flags() method and returning the on/off value for the CheckStateRole in data().

Cheers,
_

NameRakes
27th December 2016, 06:26
@anda_skoa, I have a similar situation with large datasets, but no check boxes, thankfully. Am I to infer based on your comment "no-per-row-signal" that QTableView is a good enough design for large datasets?

Comment/additional question: To get started I have subclassed QAbstractTableModel, and was surprised to find the view asking for data() per row, per column. I was expecting the view to ask for data only of the visible rows. Clicking on a menu "Table1" invokes QTableView::show() - should I call something else?

anda_skoa
27th December 2016, 11:47
The view might ask for more data than it can show at the moment, but usually not much more.

It should be able to handle really large datasets.

If the table is part of a widget then you don't need to call show() at all, unless the parent had already been shown at the time the table get created.

Cheers,
_

NameRakes
27th December 2016, 15:38
Ok, it makes sense that the view is asking for more data than it can show.

You're absolutely right about not calling show(), but my table view is part of a QSplitter sharing space with other widgets, and so toggle it based on what is being browsed Tables or Other collections. Personally, I would like to use QGridLayout for multiple widgets, but I haven't yet figured out how to create the resizable "splitter handles" between the layouts.

d_stranz
27th December 2016, 18:14
QGridLayout is a layout engine that positions and sizes the widgets contained within it. It is not a QWidget-based class, and has no visual representation on-screen. Therefore, it doesn't support dynamic interactive resizablilty using handles.


Personally, I would like to use QGridLayout for multiple widgets

Not really sure what your goals are. Do you want a dynamically resizable grid where the widgets in the grid can be rezised like the rows and columns in a table, expanding to fill their new rectangles? You can do that with nested QSplitters (horizontal within vertical or vice-versa).

You might find something in the inqlude archive (https://inqlude.org/) that does this with a cleaner UI than bulky splitters.

NameRakes
27th December 2016, 23:19
Being new to Qt, I am sure I misunderstood the connection between layout and the widgets positioned within. Thanks for straightening me out (seriously, the forum/archive has been extremely helpful).

I am already using QSplitter (including the nested ones), but don't know if I am using it effectively. Let's say we have a horizontal QSplitter with two widgets like [H1 | H2], where I want to use the space H2 for many widgets, but one at a time - could be a table or a small list of QLineEdits, but not both at the same time. I manage the state of H2 as (table->hide, lineEdits->show) or vice-versa. Don't know if there is a better way to do this, since there is no "removeWidget" method in QSplitter.

Thanks also for point out inqlude!

d_stranz
28th December 2016, 00:10
Don't know if there is a better way to do this

Make H2 a QStackedWidget (or use QStackedLayout), where your table, set of line edits (as a compound widget), etc. are pages within the stack. QStackedWidget is probably more appropriate for what you want to do. The setCurrentIndex() method manages the hide / show state of the widgets in the stack.

NameRakes
28th December 2016, 03:35
Much better now with QStackedWidget! Got rid of QGridLayout even though this is a prototype. Didn't try QStackedLayout since QSplitter doc says adding layouts is not allowed. Thanks a bunch.