multiple CComboBox sharing the same data - c++

I have a MFC dialog with 32 CComboBoxes on it that all have the same data in the listbox. Its taking a while to come up, and it looks like part of the delay is the time I need to spend using InsertString() to add all the data to the 32 controls. How can I subclass CComboBox so that the 32 instances share the same data?

Turn off window redrawing when filling the combos. e.g.:
m_wndCombo.SetRedraw(FALSE);
// Fill combo here
...
m_wndCombo.SetRedraw(TRUE);
m_wndCombo.Invalidate();
This might help.

The first thing I would try is calling "InitStorage" to preallocate the internal memory for the strings.
From MSDN:
// Initialize the storage of the combo box to be 256 strings with
// about 10 characters per string, performance improvement.
int n = pmyComboBox->InitStorage(256, 10);

In addition to what has already been said, you might also turn off sorting in your combo box and presort the data before you insert it.

One way along the lines of your request would be to go owner drawn - you will be writing a fair chunk of code, but you won't have to add the data to all of them.
"CComboBox::DrawItem"
Support.microsoft have this article on subclassing a Combo box which might also be of interest
"How to subclass CListBox and Cedit inside of CComboBox"
Really one has to ask if it is worth the effort, and alot of that depends things like
number of entries in the list
number of times the dialog will show
variability of the combo content
optomising elsewhere
not drawing until the screen is complete
only building the dialog once and re showing it.
using the one combo but showing it in different locations at different times

Related

Column-Packed RowColumn Class for Motif Library (C)?

I recently asked this question: Horizontally-Drawn RowColumn Class for Motif Library (C)?
In my previous question, I was having trouble getting the xmRowColumnWidgetClass to draw horizontally (row-by-row) instead of vertically (column-by-column). After playing around with it, figured out how to switch to horizontal drawing with the following snippet:
XmNorientation, XmHORIZONTAL,
So the code that creates the xmRowColumnWidgetClass instance now looks like this:
rowColumn = XtVaCreateManagedWidget("rowcolumn",
xmRowColumnWidgetClass,
parentWidget,
XmNnumColumns, 3,
XmNorientation, XmHORIZONTAL,
XmNpacking, XmPACK_COLUMN,
XmNspacing, 6,
NULL);
However, my new problem is that for some reason the XmNnumColumns field is now referring to the number of rows, rather than the actual number of columns. Before adding the XmNorientation, XmHORIZONTAL part, the xmRowColumnWidgetClass instance was drawing the objects from left-to-right but it stayed to 3 columns like it was supposed to. Now, it is staying to 3 rows, occasionally creating a horizontal scrollbar which I do not want. I only want vertical scrolling.
So I need the children of the xmRowColumnWidgetClass instance to be drawn horizontally from top to bottom, but I need it to only put a maximum of 3 per row and thus keep it confined within a certain width.
I tried playing around with the XmNnumColumns field, but things that worked with more children did not work for less children, and vice versa. Sometimes it made it 4 or 5 columns rather than 3, and sometimes it made it 2 columns with the 3rd column completely empty. I encountered many issues like this even when experimenting with things like using XmNpacking, XmPACK_TIGHT rather than XmNpacking, XmPACK_COLUMN and other stuff.
If someone is able to find the official documentation of the xmRowColumnWidgetClass and link it, that would be be greatly appreciated.
To anybody familiar with this library:
How do I create a xmRowColumnWidgetClass instance that draws horizontally (row-by-row) while keeping it to a certain number of columns?
It should be able to handle any number of children and add as many rows as it needs to in order to keep it as exactly 3 columns.
Another group of examples of this library:
https://github.com/spartrekus/Motif-C-Examples
https://github.com/spartrekus/Motif-C-Examples/blob/master/rowcol.c
XmRowColumn was designed to implement the top menubar and all the other menu classes... You are searching for a grid like widget, and so you have to use XmForm read the related question for that.
In short: try the WtTable widget
Longer explanation follows:
The behaviour of XmRowColumn regarding "columns" becoming "rows" when you choose a horizontal configuration is very unfortunate. The alternative of using XmForm instead of XmRowColumn for this purpose is feasible, but however it requires manually setting the children constraints, and even then, it's quite possible that you won't be able to achieve the automatic sizing implemented in XmRowColumn.
By searching today, I found the WtTable widget and it works fine for my purposes. It's "almost" as automatic as XmRowColumn and it doesn't require to set any constraints manually. I tried it in my Motif code, and works fine.
Note however that I said "almost" as automatic. The "almost" is because you need to specify the number of columns and rows, and you need to specify the column and row for each child widget. However, all of this can be automated: you can create a convenience function that internally manages counters for columns and rows, so that you pass a widget to such function and it puts it in the cell it belongs automatically: you can even make that function create a new row in the WtTable when it's needed.

Better way to get label from ListBox row?

I'm working with gtkmm (GTK+3), and I'm finding that there are surprisingly few tutorials for working with Gtk::ListBox. I need to be able to extract the label from a single ListBoxRow in ListBox.
Right now, this code works to print the first row's label text to the command line, but it really isn't terribly efficient.
vector<Gtk::Widget*> listChildren = lst_agents.get_children();
vector<Gtk::Widget*> rowChildren = static_cast<Gtk::ListBoxRow*>(listChildren[0])->get_children();
std::cout << static_cast<Gtk::Label*>(rowChildren[0])->get_label() << std::endl;
Is there a better way to do this, ideally without dynamic allocation entering the picture? I cannot imagine that every single Gtk::ListBox sort goes through all of this trouble on each sort, because the CPU overhead would be tremendous!
ENVIRONMENT: Ubuntu 15.04, GNU GCC, Code::Blocks, C+11
I don't think there's a better way, no. I see no great problem with it other than that you have to get a list of all child widgets just to get the first one.
A ListBox sort would involve implementing a set_sort_func() callback slot: https://developer.gnome.org/gtkmm/stable/classGtk_1_1ListBox.html#acec1d5f8d73d591fc3eb2772c4f0e480
and then you would already have the ListBoxRow:
https://developer.gnome.org/gtkmm/stable/classGtk_1_1ListBox.html#a931a0b125d6514e0191a071900bf57c0
so there wouldn't be much work to do. Anyway, ListBox isn't meant for showing huge numbers of items - for that you would want a container widget that reused the child widgets to present a data model - for instance, Gtk::TreeView.
You also have a typo in the second line of your code: You couldn't cast a ListBoxRow to a vector.

which widget to use to show hard disk sectors as hexadecimal?

I want to know about the utilities like winHex , which are the disk editor
. they access the hard disk & represent the data in hexadecimal of a whole harddisk of about 2TB .
How do they achieve this in a single scroll area & also provide the undo functionality in that....
which widget should be used to display such a huge amount of data.????
I want to make this application in QT.
How do they achieve this in a single scroll area
It is not a "single scroll area" containing the entire disk. It is a scrollbar and dynamically generated content for whatever disk content you are showing at the time.
Simply calculate the position based on the scroll location (unless your screen is 10000's of pixels tall, however, you will not be able to place the cursor EXACTLY on the disk sector you want).
also provide the undo functionality in that....
Undo functionality, I expect (I haven't looked at the code) is done by holding "address changed, old value" in some sort of container. Pretty much the same way you'd do undo information for any other large dataset.
which widget should be used to display such a huge amount of data.????
One which shows text and allows you to intercept the redraw and provide your own data on each redraw operation. I'm afraid I don't know QT very well, so can't advice on the details.
Obviously, one factor you haven't covered is "how do you open/mount the whole disk in read-write mode when it is already mounted" - I'm not sure if it allows this, but if it does, I expect there is a disk filter driver involved that has "sideways" interfaces to allow updates behind the scenes of the filesystem.
Edit: In answer to the question in the comment:
There are two options, either write to disk whenever the data is changed. In which case the code needs to remember all the original values, and restore them when the user does the undo operation. The alternative, which is approximately the same effort is to store all the edits, ("change value at 1000 to 05"), and then when asked to display some content, process any edits within the displayed range before the actual display operation.
Obviously, if someone decides to play "monkey on keyboard" for many many hours (weeks, months) to fill the ENTIRE disk with rather random content, then that would be a problem to "remember" all that without running out of memory, so you probably need a "I've run out of memory to store undo-information, do you want to save what you have done so far?" type option.
One could also consider a "same value stored in a large section" type compression (e.g. if you have a "fill from A to B with value X", you store simply that "from A to B we have filled with X", rather than store, potentially, many megabytes of "A = X, A+1 = X, A+2 = X ... B-1=X, B=X").

GTK TextView - creating a static display format

I am trying to simulate a piece of hardware, and this hardware has a static ribbon display.
to do this, I'd like to use a TextView. My display has 10 rows, with 25 columns. So I figured that a TextView should be easy enough.
basically, I would like to be able to say "insert/replace string S at row X, starting at column Y". i may need to only update a specific row, or even a single column within a row.
I have not been successful at getting this to work though. the best I have been able to do is to fill the TextView with 10 lines of 25 spaces when i create it, and then use the get_iter_at_line_offset to get the iterator of a line, and then push the new text onto that line.
but this will start appending text to the line, rather than replacing the existing one.
I need both row and column control (i.e. need to be able to set text at a specific (X,Y) coordinate).
I'm assuming this is somehow possible using marks.
Can anyone give me a quick example of how i can do this? Unfortunately, there isn't a whole lot of documentation on this sort of thing.
You'll have to get an iter at a specific line, row X, and then use the iterator's forward_chars() method to move forward Y characters. Then delete the number of characters you are replacing, and finally insert the text you want to insert. You can do it all with iterators, I think - iterators are invalidated when you change the buffer, but when you delete text, one of your iterators is revalidated to point to the place where the text was.
If you're targetting GTK+ 3.x, you should really look into using Cairo. Since you don't actually need a text buffer, it seems like overkill and a bit of a mis-alignment to use the GtkTextView.
Look at the very basic introduction on how to draw with Cairo in GTK+. Then look at the text-rendering Cairo APIs, that should be enough to get you started.

QListWidget::addItem() gives flickering when i call it 40 times per second

What is the choise better than QListWidget to display a lot of log lines in GUI that are coming from backend at average speed 40 lines per second?
QListWidget gives a flickering and even white box instead of a widget for a long time when a lot of strings are already placed into ListWidget.
Is there any better solution to dynamically display log lines to a user?
update:
Changed architecture. Adding new QStrings to std::deque< QString* >. Using QTimer i add that strings every 1/10 of second to QPlainTextEdit, deleting from deque. boost::mutex is used to protect std::deque (log lines are coming from different threads).
Would be nice to have a time to implement my own QListView and keep strings in big chunks of pre-allocated memory.
Are you sure you need the functionalities of a QListWidget? If you just want to display log lines, I think a simple read-only QPlainTextEdit would be more appropriate.
You might try to use QListView and you own implementation of QAbstractItemModel. Then you can store your lines as you wish and append new lines in big groups (about every second should be ok). Then view is not refreshed at adding every line but only in groups, which should highly improve performace.
I would suggest setting a refresh rate and append all gathered items at once. You will avoid repaint of widget every line you append.
Long story short:
QTimer with refresh rate (~1-3 seconds would be enough), QListWidget::addItems instead of QListWidget::addItem