Qt GUI: Select multiple QLabels with mouse - c++

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.

Related

Qt - QScrollArea - align added widgets to top

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.

QGridLayouts within a QGridLayout

Is it possible to have QGridLayouts within another QGridLayout? I have been trying to do this using the UI designer, so that I can resize all QGridLayouts uniformly.
This is for an Ultimate-Tic-Tac-Toe game I am creating for fun.
Here, I have nine QGridlayouts. I want to group them together. If I want to expand the boxes, I have to go through each one and expand them. Or I have to copy/paste the first box and make sure they are all aligned again.
I tried selecting all of them and clicking Lay Out in a Grid , but that messes up how they are displayed. Especially the lines that separate the layouts. Am I not doing this correctly?
This just looks weird:
Yes, there is no any problems inserting QGridLayout into another QGridLayout. Here is a demonstration how it can be done in the designer.
Pay attention that there are no any lines when you open the widget in the Preview: they are visible only for design purposes.
Buttons are added to the layouts just to see how they are places in the Preview.

QT C++ QTableWidget(Item) partially italicize (emphasize) text

Problem
I'm using QTableWidget(Item) for presentation of some data. For that i need to italicize or set bold some parts of text. Problem: I don't want to italicize the whole cell/box, just parts of text in a cell.
Ideas
: Using the QTableWidgetItem refering to the correspondent cell and trying to modify the style (e.g. setFont(font)). But this operations always seem to alter the whole cell?
I also found this which doesn't help me for my QTableWidget problem.
Wanted
: To Have a QTableWidget with e.g. 2 rows and collumns containing cells like:
Exa mple Cell Text
(Nice Notation like Exa<b>mple</b> Cell <i>Text</i> is only a secondary aspect)
Note: Example should be one word.
Solved
I didn't see the wood for the trees. Thanks to Salvatore Avanzo, he is totally right.
All Item Widget classes provide functionality to render/paint something custom in each cell.
QTableWidget provides setCellWidget(.. QWidget..); QListWidget and QTreeWidget provide setItemWidget(..QWidget..). Therefore you can use any Subclass of QWidget (base of all ui objects) to paint something custom. For my aim i needed the capability to set a custom partially emphasized/italicized text. The Refering Subclass of QWidget for painting texts is QLabel (It itself is also a subclass of QPainDevice). A QWidget/Subclass of QWidget is drawed when paintEvent(..) is invoked (QLabel reimplemented that). QLabel also supports RichText functionality (flag is used by default), e.g. you can use <b>foo</b> to get foo.
So that's perfectly fits my problem and i will now use this solution.
Forecast for better structured solution
The unattractive aspect of the above mentioned solution is, that design and data get totally mixed. Editing Text in a QLabel is possible if you set the refering Interaction tags. But then you always need to use QLabel to get the text. When additionally setting an QTableWidgetItem in the Cell which also uses QLabel, they overlay ugly. So one could use QTableView. Here is a link.

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.

Change resize behavior in Qt layouts

I want my custom widgets to gain extra space when the dialog is resized. This was working when I only had a handful of widgets, but after adding several more columns of these same widgets and putting them in a QGridLayout, the extra space merely goes in as padding between the widgets.
I've had trouble with this in the past and here are some of the things I've found:
First make sure all the widgets you want to expand have sizePolicy set to "Expanding".
Make sure the widgets that make up your custom widgets are in a layout that allows for expanding. You can check this by just adding one of your custom widgets to the window and seeing that it expands as expected.
Make sure any widgets on the form that you do not want to expand have a fixed (minimum=maximum) size in the dimension you want them to stay static.
Sometimes the grid layout causes some weird spacing issues because rows are resized based on the largest widget in the entire row and similarly for columns. For some layouts, it is better to use a vertical layout that contains horizontal layouts or vica versa to create a grid-like effect. Only this way, each sub-layout is spaced independently of the other rows or columns.
Controlling grid expansion programatically
I've found that you can easily control which columns/rows expand and which columns/rows stay fixed in width by using QGridLayout::setColumnStretch() and QGridLayout::setRowStretch(). You'll need to provide weights to the specific columns (0 for no stretch).
For example, if you want column 0 to not take up any room and column 1 to take the rest of the window's room, do this:
QGridLayout* layout ;
// Set up the layout
layout->setColumnStretch( 0, 0 ) ; // Give column 0 no stretch ability
layout->setColumnStretch( 1, 1 ) ; // Give column 1 stretch ability of ratio 1
Controlling grid expansion using Qt Designer
You can do what I described above if you're using Designer. Just look for the widget properties layoutRowStretch and layoutColumnStretch. It'll contain a comma-separated list of integers.
Another option is inside of QT Creator, to specify in the top level layout widget of the section you want fixed size a layoutSizeConstraint of "SetFixedSize". You must also remove all spacers from beneath that widget. In my case, I had a dialog with a TreeWidget, a Table, and some color selection stuff. I wanted the color selection controls to remain the same size horizontally, so they were in a VerticalLayout. I imagine you can do the same with a HorizontalLayout too if you want things to stay the same height. IF you really need spacers inside the layout, you can probably use blank labels with fixed size.