QWidget (a qlineedit) auto resize to content - c++

Below Code successfully auto-resizes QLineEdit field as needed (new width/height based on dynamic text). Now in order to make the resized QLineEdit fit the container widget, I do adjustsize() on the container widget.
Relevant elements in my code:
void theContainer::resize_to_content(QString text) {
{
// ...
lineedit.setFixedSize(calcualtedWidth, calculatedHigh);
theContainer::adjustSize();
}
the problem encountered is that even though both resizings of the QLineEdit and the parent widget work (to some extent), the limitation in this case is that the QlineEdit, after resizing, overlaps adjacent widgets!
It looks like that container widget -- when it adjusts -- seems to ignore other non manipulated children ...
Is there a systematic way to prevent such overlapping ?? not just a workaround I mean.
-- Widgets before adjustments
-- Widgets after text change and size adjustments:

I'm pretty sure using the classes Qt provides specifically for layout management will help.
See Qt documentation on layout
If it won't, I think you could resize the entire window to get more space instead of only the parent widget.

Related

Lay out an image on a Qt dialog

How to add an image to a dialog in Qt?
I know this has been often asked in the past and most answers come up with a QLabel and its setPixmap member. However, this usually is not what the user (me) intends:
A QLabel with a pixmap set does not participate in the surrounding QLayout. That is, it simply refuses to resize when the dialog is resized, like e.g., a QPushButton would do. Two QPushButtons next to each other in a QHorizontalLayout will (something like) equally divide the available horizontal space between them. A QLabe with a pixmap next to a QPushButton in the same layout will just stay fixed in size.
By default, a naked QLabel won't resize its contents when it's resized.
But when it does (QLabel::setResizeContents) it won't keep aspect ratio.
Is there any native way to have a pixmap shown on a dialog and have it reasonably participate in the layout?
Item resizing can be managed via sizePolicy property. From Qt documentation:
sizePolicy : QSizePolicy
This property holds the default layout behavior of the widget.
If there is a QLayout that manages this widget's children, the size
policy specified by that layout is used. If there is no such QLayout,
the result of this function is used.
The default policy is Preferred/Preferred, which means that the widget
can be freely resized, but prefers to be the size sizeHint() returns.
Button-like widgets set the size policy to specify that they may
stretch horizontally, but are fixed vertically. The same applies to
lineedit controls (such as QLineEdit, QSpinBox or an editable
QComboBox) and other horizontally orientated widgets (such as
QProgressBar). QToolButton's are normally square, so they allow growth
in both directions. Widgets that support different directions (such as
QSlider, QScrollBar or QHeader) specify stretching in the respective
direction only. Widgets that can provide scroll bars (usually
subclasses of QScrollArea) tend to specify that they can use
additional space, and that they can make do with less than sizeHint().
I think you are searching for QSizePolicy::Expanding size policy:
The sizeHint() is a sensible size, but the widget can be shrunk and
still be useful. The widget can make use of extra space, so it should
get as much space as possible (e.g. the horizontal direction of a
horizontal slider).
Set this for your QLabel and check how it will resize. Try other values from QSizePolicy::Policy enum.

Qt Widget automatically resize if it contains empty layout

I have been given a qt widget containing some elements and layouts.
I am trying to add an empty layout to this main widget (My plan is to populate it with a widget in the future). I am expecting the main widget to resize automatically if the layout is empty. How can I do that?
I tried to play on the size policies of the widget but I did not get much results so far .
In the end the idea is to get the main widget (which is not contained in a layout by the way) to resize automatically if it contains an empty layout in itself
I think, you can look for adjustSize method of QWidget.
When you add or remove any internal widget in layout, you can make something like this:
QTimer::singleShot(0, this, SLOT(slotAdjustSize()));
...
void YourWidget::slotAdjustSize()
{
adjustSize();
}
Size of your widget will be fit to its contents.

resize QMainWindow based on a child widget?

The child-parent hierarchy is the following: mainWindow -> centralWidget -> frame -> widget.
Widget is being resized during the application lifetime, however it is always set to a fixed size. I want the QMainWindow to resize based on that - to have a minimum size that is needed to display all the widgets.
To do that I currently have to do this.
widget->setFixedSize(x, y);
frame->setFixedSize(frame->sizeHint());
centralWidget->setFixedSize(centralWidget->sizeHint());
mainWindow->setFixedSize(mainWindow->sizeHint());
It doesn't work properly if I only resize the main window. All parents of widget need to be resized in order for this to work. Is there a more elegant way? Is it possible to make the main window call resize on all of it's children?
NOTE: All widgets except 'widget' have automatic layout management. So I find it strange that they don't resize themselves based on 'widget'.
It is the job of the layout to determine the size and position of the widgets. So if you explicitly resize a child widget which is inside a layout, you need to ensure that the new size is passed correctly through the layout system. This can be done by ensuring that the widget’s sizeHint() returns the new size. The value returned by the sizeHint() will be used when the layout calculates the new size. So after the sizeHint() has changed, simply call updateGeometry() [qt.nokia.com] that will notify the layout system that the widget has changed and may need to change geometry.
An alternative way to ensure that the parent widget is resized in response to its child being resized, is to call setFixedSize() on the child.
For more details check this...
http://qt-project.org/faq/answer/how_can_i_trigger_the_parent_widget_to_resize_when_its_child_widget_is_resi
You should let layout manage widgets size. As far as i am concerned there is 2 situations:
With layout when you are resizing a parent all children are resizing too regarding the size policy you provided to them. If you choose a fixed policy children will not be resized. So you have to resize them by hand... but it's quit weird.
When you are resizing a child like you are doing, parent is not automatically resized. You need to do it by hand. Fortunately there's a "magic function for that: AdjustSize. If you call it from QMainWindow all widget will be resized to their optimize size. It is possible (I can't test it here) that this does not work at runtime if size policy is set to fixed.
Hope that helps

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.

How should I use a QGraphicsScene with layouts and widgets

I'm creating some graphic data displaying widget in Qt4 and I was tempted to use the QGraphicsScene for it, create QGraphicsItems for the data items etc.
However, I wanted to add some layer of controls (eg. scrollbars, zoom+other buttons - I want to make it in a similar style as eg. Google Maps, that is, the data would be displayed all over the widget, and the buttons would be shown atop of them) to the widget. So I thought it might be feasible to add them to the scene (perhaps as a child of a QGraphicsGroupItem that would be shown over the data). But I want them to move & resize when I resize the whole widget, so I should use a QGraphicsLayout for managing them. But at this point, I discovered things are pretty complicated.
The problem is that when using QGraphicsLayout, the following constraints hold:
Only a QGraphicsWidget can be managed by a layout
QGraphicsLayout can only be used to manage children of a QGraphicsWidget
Which means that I would have to create my controls as QGraphicsWidgets, add a top level QGraphicsWidget to the data widget, and manage the size of this top level widget myself.
So I want to ask:
Wouldn't a classic approach (ie. use plain old widgets for all controls, and use QGraphicsScene only for displaying the data) be more reasonable?
Is there any advantage in using QGraphicsScene in this case (performance or simplicity...)?
How should I use QGraphicsScene to exploit its strengths?
Since Qt 4.4 you can embed classic widgets in a QGraphicsScene by using QGraphicsProxyWidget :
QWidget *widget = new QWidget;
QGraphicsScene scene;
QGraphicsProxyWidget *proxy = scene.addWidget(widget);
If you think that QGraphicsScene (or whatever other widget you have) is appropriate for most of your display, use that. What we have done in the past for somewhat similar things is to make a custom widget that inherits (one way or another) from QWidget, and put the control widgets in a layout on top of that widget. This means that the whole widget is drawing whatever it is you want drawn, and the control widgets are on top of that, resizing as the whole widget is resized.
Alternatively, a couple of times we've had layouts that were just a bit too complicated for the layout widgets to easily handle. Rather than create a custom layout, we just positioned them with no layout, and moved them in code on the resize event. It works just as well.