Qt - QScrollArea - align added widgets to top - c++

I have a 150x450 QScrollArea with a VBoxLayout in it. I have to dynamically (while a video is being played, frame by frame) add an unspecified amount of QLabels, ranging from none to hundreds.
When I start adding, QLabels start appearing exactly in the middle. Then when another appears, they shift so the middle is exactly between them. So on and so on.
How can I make them appear from the very top and just go down? Without shifting positions and wiggling?

Having hundreds of labels in the application and layouting them in your scroll area will cost you much memory and performance. From the other hand Qt has the number of dedicated classes to handle multiple items in a scroll area such as: QTableWidget, QListWidget, QTableView etc. All these classes designed to handle rows of items and have all related functionality. Using them will free you from taking care about layouts, scrolling and so on.

Related

How to collapse Gtkmm notebook tabs?

So I am making a Gtkmm application using a Gtk::notebook and during run-time I'm adding new tabs to the notebook. But when I add more tabs than there is space on my screen it just keeps going moving out of the screen.
Now I know most Gtk widgets have a lot of properties that can be configured, so I'am wondering is there such a property for notebook that automatically collapses tabs or scales them in some way to make it fit inside the widget/screen.
If not it would be great if you could give me some pointers to how to implement this functionality myself.
set_scrollable() is your best bet. It will add scrolling arrows on the sides of the tab labels at the top when there isn't enough room to show them all.
Note that GtkNotebook will always ask for enough space to show the contents of all tabs, not just the one that's currently visible. If one of your tab pages is really big (say, contains a 10x10 grid of 100x100 buttons), you won't be able to resize the GtkNotebook smaller than that tab page (in that case, 1000x1000 + the height of the label area), even if the current tab page is just an empty container. All set_scrollable() will do is let you resize smaller than the width needed to show all tab labels at the top.
Put this in your .xml GUI file in the GtkNotebook object:
<property name="scrollable">True</property>
This causes the tabs that go out of screen to be horizontal scrollable by adding arrows beside the last tab at the right and the most left tab at the left.

Qt GUI: Select multiple QLabels with mouse

I would like to enable mouse-selection of the text of several QLabels arranged in a grid layout in a Qt GUI.
A QLabel has textInteractionFlags like TextSelectableByMouse which enables this behaviour for one object, but a selection across several QLabel widgets does not seem to work.
Is there a way around this that does not require a lot of mouse "tracking" or reimplementing a layout?
I fear there's no simple method to get what you want. The first problem would be what you'd expect to find in the paste buffer after selecting some rectangular section of your table. How should the label texts be delimited, should they be organized by row or colum?
You may say that you want them row-wise, columns separated by blanks and rows ending with a \n, but that doesn't need to be what the next person needs.
You may want to spend some time considering QTableView or QTableWidget.

Qt splitter layout resize behaviour using Qt Designer

I have an issue with size in my view made in Qt with drag and drop.
Let me start with an image to help me explain
This is the mainwindow for my form.
What happens is:
We have 4 tab widgets. the left tab widget has a horizontal splitter to the 2 mid widgets.
The 2 mid widgets have a vertical splitter, and a horizontal splitter on the left and right side.
The right widget has a vertical splitter on its left hand.
So all views are connected using splitters.
Lastly the mainform sticks every thing together in a resizable way using horizontal layout.
The problem is, the width of the leftmost and rightmost widgets are fixed (in designer).
I want them to be smaller in width. Something similar to:
You can see the widgets are resized. I was able to do this running the application, and manually adjusting the splitters. Is there a way in QtDesigner to do this? I tried playing with policies. I didn't really get any further however. Does this indicate a lack of knowledge of my part about policies? Perhaps layouts in general?
What options should I use to achieve the desired layout using QtDesigner. I want to avoid using code.
Hope I will be able to solve this soon. It must be overlooking something simple..
You can play with the "Horizontal Stretch" and "Vertical Stretch" properties to change the position of the split.
For example with both the vertical stretch of the top central QTabWidget and the horizontal stretch of the central QSplitter at 1 and all the other values kept at 0, you'll get the result you want.
When you have multiple non-zero stretch values, the result of the ratio (e.g.: vertical strech at 2 and 1 for the 2 central QTabWidgets => 2/3 and 1/3) is not visible in the designer but seems to be working when you run the application.
PS: You can also achieve the same result with tabbified QDockWidgets but the dock tabbification is not possible through the designer only.
I set start position that:
QList<int> list= ui->splitter->sizes();
list.replace(0,this->height()/0.3);
list.replace(1,this->height()/0.7);
ui->splitter->setSizes(list);
and remember to minimum size child widget

Qt: scrolling complex content. Web-Browser engine. Selecting a text

Just curious about scrolling complicated content inside web browser - like application. Lets assume i am using Qt and C++. This is not "how to" question, but more like "how does it work"? Completely derived from my curiosity irrational questions.
I did small experiment.
Created large QWidget 800x60000 px.
Added 300 QWidgets 800x200 px that are painting themselves using QPainter. Each widget prints its unique name to console when paintEvent() is called.
Added (1.) to a QScrollArea 800x800.
When scrolling, i notice redrawing only widgets that are not fully displayed on the screen. It is only 1 widget at a time (scene: http://savepic.ru/2670640.jpg).
So QScrollArea (or QWidget? Who deside what widget to repaint?) is smart - we do not have CPU loaded redrawing all the 300 widgets all the time or memory consumption storing 800x60000 pixmap (-;
Lets assume i want to use mouse to select text and other elements on my "webpage". So i want to be able to mark them (by changing background). How would i implement that? How different web browsers do that? Selecting pictures, text, tables... Should i think about tracking the mouse and drawing gray/blue/pink background boxes behind elements and my custom widgets?
I have another experiment - displaying stack of messages. The scheme is the same, except QPainter is not used here - only QLabels, QTextExits, QPushButtons (scene: http://savepic.ru/2632728.jpg). I can set a flag SelectableByMouse for QLabel, but how do i select more than 1 message?
You could suggest me to use some Qt HTML renderer, but this is not the answer for 'how does it work".

QListWidget that resizes instead of scrolls

How do you change the behavior of a QListWidget so that it resizes its height instead of choosing a (seemingly arbitrary) height and adding scrollbars? See screenshot:
The QListView's should fill up as much space horizontally as they can (creating as many "columns," if you will.) Then they wrap and make as many rows as necessary to fit all the items. These calculations should be adjusted as the window is resized. This is all working fine.
However, what I want to happen is that instead of the height staying the same, the QListView should grow or shrink vertically and never need any scrollbars. The scrolling, if necessary, will be handled on the parent QWidget that hosts all of the labels and lists. It seems like once the height of the QListWidget is established (not sure where its default is coming from), it never changes. It is too big in some cases (see second "Test" list above) and too small in others (see first "blank maps" list above.)
The layout above is nothing surprising: two QLabel's and two QListWidget's in a QVBoxLayout. Here are the properties I have set on the QListWidget's:
setMovement(QListView::Static);
setResizeMode(QListView::Adjust);
setViewMode(QListView::IconMode);
setIconSize(QSize(128, 128));
(I already tried setting the horizontal and vertical scrollbar policies, but that just turns the scrollbars off, clipping the content. Not what I want.)
Maybe you could this without using QListWidget. The Qt's examples contain a new layout class, QFlowLayout, which could be useful. With the following kind of widget hierarchy you could get multiple groups with labels and they all would be inside one QScrollArea.
QScrollBox
QVBoxLayout
QLabel "Blank maps"
QWidget
QFlowLayout
your own widgets showing map images and labels
QLabel "Text"
QWidget
QFlowLayout
your own widgets
The problem is that this kind of solution would create much more widgets than QListWidget based solution. So if you have hundreds of items in your list, this might not be the best solution.
There is a protected member function called contentsSize() in QListView. It is used to calculate the required minimum(), maximum(), and pageStep() for the scrollbars (as mentioned here).
Can you subclass the QListView class and make use of that information? I suggest you recalculate the size of your widget in the same function where you add contents to it. While somewhat lacking elegance, this appears to be a pretty reliable solution.