How to prevent QListView from acquiring all icons at startup? - c++

I'm using a QListView with a custom model derived from QStringListModel to display a large series of images, or, to be more specific, data curves. I used to use QListWidget, but I have so many of them that setting the icons (quite high res) for all of the items just takes all the memory, and cause a very long startup time. I thought that switching to QListView with a custom model would solve the problem (and it does solve the memory problem), but not the long startup time, as all the icons are requested by QListView at startup (I see that by just writing the names on the terminal).
Do you have any way to work around this ? The best I can think of for now is to have a thumbnailer thread that trashes its queue when it gets too large, but that seems very cumbersome.

It turns out that, in my case, it is rather simple:
list->setUniformItemSizes(true);
This way, the QListView doesn't have to look at all icons to know their size.

Related

wxWidgets splitted windows

I'm trying to create structure to draw many graphs in separate sub windows one below another, something that looks like that :
I need to change the size of these graph by dragging lines separating them.
I tried using panes in wxAUI but resizing one affects other, and it seems to be rather unstable. The main problem is that when I'm moving one sash to another it starts pushing it. Maybe there is some way to solve it?
I also tried using multiple wxSplitterWindow each nested in another, but this strategy also seems to fail because resizing one window affects all nested inside and their splitters are moving due to sizing even if I try to cach event EVT_SPLITTER_SASH_POS_CHANGED.
Do you have any ideas how to solve that?
I'm afraid there is indeed no out of the box solution doing what you need. wxSplitterWindow itself is implemented using wxWidgets API, so you could adapt its code to create your own window supporting multiple splitters, AFAICS it should be quite straightforward but, still, will require some work.

How to fast append to QTextEdit

I have an application that has some sort of log viewer, that needs to be able to render formatted log records that are inserted to it in real time.
I am writing this in Qt and so far I was using QTextEdit for rendering of the text, which was beautified using some html tags and later inserted either with setHtml or insertHtml.
The problem is however, that these functions are insanely CPU intensive and run for ages, hanging whole application.
A similar question was asked here: QTextEdit.insertHtml() is very slow
Apart it has no really useful answer, other than stating it's really slow, it actually asks a different thing. I don't need to speed up setHtml or insertHtml. I am willing to use entirely different technique if possible.
Is there any mechanism within Qt that would allow for really fast insertions of text? Or maybe even completely different component than QTextEdit?
Is there any way to append new line to QTextEdit which contains rich text (generated in any way) that is really fast?
I also noticed QTextBrowser but it seems to be just an extension of TextEdit, could it be faster?
You should give QPlainTextEdit a try. It uses the same technology as QTextEdit but is a lot faster. It is optimized for plain text handling but do not let that fool you, it still has some basic support for formatting using HTML. You can append HTML formatted text with appendHtml().
In my application, I also need to display a large log of the task, approximately 3500 lines. Some lines of the log should be colored. For this, I used HTML formatting. QTextEdit.setHtml with this amount of text, freezed my GUI.
I replaced QTextEdit with QListWidget, in which QListWidgetItem is created for each line of the log.
It began to work much faster, without friezes.
And I saved colored text, just simple by using the QListWidgetItem.setForeground.
[This post][1]
[1]: Performantly appending (rich) text to QTextEdit or QTextBrowser in Qt contains an answer to this problem. The gist: instead of simply appending an HTML snippet, manipulate the underlying document directly.
However, I suggest that if your display really is a list of single lines, you create a QAbstractListModel QAbstractTableModel derived class instead and show it in an item view.

Making a fancy looking window with messages stack

I try to make fancy looking messages viewer, where messages divided by formatting, other background of smth. similar. They need to looks like this - http://pastebin.com/GU1Lq087. What I found in wxWidgets to solve this problem, and why I can't use it:
wxHtmlWindow
Supports minimal HTML (a few tags). But big problem with this - html representation doesnt fill parent window. So element with width=100% will have 100% width only on standard window size. And even p tag doesnt have word wrapping (long long paragraph goes in one line with vertical scroolbar).
wxWebWiew
I need to have the ability to set generated HTML to it, but IE must to load some page first and I can rely only on IE background. It has some time to load page, even if I set HTML-string.
wxRichText
Most suitable for me. But I can't draw line like HTML's hr, or change background for the entire message block (to distinguish it from common background)
I need to show messages like this. But i didn't know how and which tool is better.
One way of achieving this would be using wxWebView with WebKit backend but I am afraid that Windows can only use IE's engine. However, there is project which allows you to use Gecko engine. I use WebKit for rendering chat in my application and it works really good (although I am using Qt). (http://www.kirix.com/labs/wxwebconnect.html)
You can always do it regular way - just create separate widget (I think it is called "frame" in wxWidgets) for single message. This way you get almost infinite possibilities. E.g. you can make "AbstractMessage" with virtual methods and then things like "AdministratorMessage", "MOTD" etc. will be a breeze.
wxRichText Most suitable for me. But I can't draw line like HTML's hr
Really? Have you looked at the docs?
( http://docs.wxwidgets.org/trunk/overview_richtextctrl.html )
Here's a couple simple ideas:
a. Write a line of blanks, underlined.
http://docs.wxwidgets.org/trunk/classwx_rich_text_ctrl.html#a333b2e675617ed2299cf91e7c0dbd0d8
b. Create an image of a horizontal line, display it using WriteImage
http://docs.wxwidgets.org/trunk/classwx_rich_text_ctrl.html#a1315611c0741d03e852ee26eba3a9d94
The funny thing is that what you want can be done using any of the 3 controls you mention. With wxHtmlWindow you just need to set its size correctly, with wxWebView I don't understand what your problem with it is at all and with wxRichTextCtrl you could just use separate controls for the areas with different backgrounds (you could almost certainly use a single control with different styles but using several controls seems simpler).

Qt - Dynamic list stuff

I'm fairly new to Qt4.5, and I'm unsure of the approach I should take to the following problem.
I'm trying to create a QListWidget style widget, that can dynamically expand to an arbitrary length, probably no more than 300 elements. I tried to use the QListWidget, but I need to store three QStrings per line, and QListWidget is fairly limited in that regard. I need to be able to add, edit and delete lines. Sorting is not necessary.
I tried to use QTableWidget, but it's not fitting the bill either. I could make it work, but it would be an ugly hack.
I've tried to 'roll my own' version of QListWidget, but with three QStrings, rather than one, but it's a tedious procedure. Doable though.
My Question is this, should I go with the last option, or is there a better approach? I've been browsing through Trolltech's documentation, but there's a lot there, and the stuff I've done so for has been unsuccessful (obviously).
Any recommendations? Thanks in advance!
That sounds like a table. 300 rows and 3 columns. If that indeed is the case you should retry using the QTableWidget. (Preferably without any hacks.)
If you're trying to do something else, (Can't quite imagine what.) you should try QTableView combined with a QAbstractTableModel that you subclass to provide the content.

How do I append a large amount of rich content (images, formatting) quickly to a control without using tons of CPU?

I am using wxWidgets and Visual C++ to create functionality similar to using Unix "tail -f" with rich formatting (colors, fonts, images) in a GUI. I am targeting both wxMSW and wxMAC.
The obvious answer is to use wxTextCtrl with wxTE_RICH, using calls to wxTextCtrl::SetDefaultStyle() and wxTextCtrl::WriteText().
However, on my 3ghz workstation, compiled in release mode, I am unable to keep tailing a log that grows on average of 1 ms per line, eventually falling behind. For each line, I am incurring:
Two calls to SetDefaultStyle()
Two calls two WriteText()
A call to Freeze() and Thaw() the widget
When running this, my CPU goes to 100% on one core using wxMSW after filling up roughly 20,000 lines. The program is visibly slower once it reaches a certain threshold, falling further behind.
I am open to using other controls (wxListCtrl, wxRichTextCtrl, etc).
Have you considered limiting the amount of lines in the view? When we had a similar issue, we just made sure never more than 10,000 lines are in the view. If more lines come in at the bottom we remove lines at the top. This was not using WxWidgets, it was using a native Cocoa UI on Mac, but the issue is the same. If a styled text view (with colors, formatting and pretty printing) grows to large, appending more data at the bottom becomes pretty slow.
Sounds like the control you are using is simply not built for the amount of data you are throwing at it. I would consider building a custom control. Here's some things you could take into account:
When a new line comes in, you don't need to re-render the previous lines... they don't change and the layout won't change due to the new data.
Try to only keep the visible portion plus a few screens of look-back in memory at a time. This would make it a little lighter... but you will have to do your own scroll management if you want the user to be able to scroll back further than your look-back and make it all appear to be seamless.
Don't necessarily update one line at a time. When there is new data, grab it all and update. If you get 10 lines really quickly, and you update the screen all at once, you might save on some of the overhead of doing it line by line.
Hope this helps.
Derive from wxVListBox. From the docs:
wxVListBox is a listbox-like control with the following two main differences from a regular listbox: it can have an arbitrarily huge number of items because it doesn't store them itself but uses OnDrawItem() callback to draw them (so it is a Virtual listbox) and its items can have variable height as determined by OnMeasureItem() (so it is also a listbox with the lines of Variable height).