[Qt-interest] Widget to use on Model/View
Sean Harmer
sean.harmer at maps-technology.com
Thu Aug 20 10:17:05 CEST 2009
Hi,
On Thursday 20 Aug 2009 06:03:26 João Mesquita wrote:
> Hello guys, this is my first post so I am sorry if there is something
> obvious I am missing.
>
> I am developing an application that has a console like interface and I
> thought of using QListView to represent this console. Each line on the
> console would be an item that is then appended to the QListView model. The
> advantage of using such a widget is that the console log messages can be
> sorted easily. I could easily make checkboxes to hide certain messages that
> do not belong to certain log levels or apply Regex or even filters using a
> custom QSortProxyModel. If anyone is familiar with Wireshark, that is
> exactly the same behavior I am trying to achieve.
Sounds fine. You may wish to consider a table view if you have several columns
of data though.
> Problem here is performance. When sorting, not a problem, but when
> inserting a large number of lines per second, I make the UI unresponsive
> and even unusable. Should I change the widget, the model or not possible at
> all?
>
> Here is the code I am using (modified batch append code of QListWidget).
>
> void ConsoleTabWidget::timerEvent(QTimerEvent *e)
>
> {
>
> bool scroll = false;
>
> if (e->timerId() == scrollTimer->timerId())
>
> {
>
> if (m_ui->consoleListView->verticalScrollBar()->value() ==
> m_ui->consoleListView->verticalScrollBar()->maximum())
>
> scroll = true;
>
> int inserted_items = 0;
>
> while( !_list_items.isEmpty() && inserted_items < batch)
>
> {
>
> sourceModel->appendRow(_list_items.takeFirst());
>
> inserted_items++;
>
> }
>
> if (scroll)
>
> m_ui->consoleListView->scrollToBottom();
>
> }
>
> }
>
> Any help would be wonderful!
I think the problem is that each time you call sourceModel->appendRow() the
model emits a signal that tells any attached views that the model has changed
and that they should update. This of course will be quite expensive.
A better way is to give your model a function that takes a list of items to
append to the model. At the start of this function call
QAbstractItemModel::beginInsertRows(), then append your data to your model's
internal data structure, then finally call
QAbstractItemModel::endInsertRows(). This way you can insert any number of
rows and only trigger a single update of the attached views. Something like
this (not tested):
void MyModel::append( const QList<MyItem>& items )
{
// Assuming sub-class of QAbstractListModel so no parent index
// Let the views know we are about to change
beginInsertRows( QModelIndex(), m_items.size(), m_items.size() + items.size()
);
// Copy the data
m_items.append( items );
// Let the views know we are done with the update
endInsertRows();
}
Good luck,
Sean
More information about the Qt-interest-old
mailing list