PyQt5: How to get the MainWindow layout? [duplicate] - qt

This question already has answers here:
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "", which already has a layout
(3 answers)
Closed 2 years ago.
So when I try to add a layout to the MainWindow
self.mainLayout = QtWidgets.QVBoxLayout(self.MainWindow)
I get this error:
QLayout: Attempting to add QLayout "" to QMainWindow "MainWindow", which already has a layout
How do I get the default layout? Is that possible?

A QMainWindow layout is quite custom and consists of a central widget and other dynamic parts (e.g. menu, statusbar, toolbars, dock areas). It does not make much sense replacing it as then you would simply start with a plain QWidget instead.
The layout you typically want to edit on a QMainWindow is the layout of its centralWidget. You can get/set that one and operate on it accordingly (including layout).

As answered by other(s), QMainWindow has its own layout.
But if at all you want to add a fixed size widget to the main windows's central widget, probably you can use, setFixedSize method of the widget, that you want to add to central widget.
example:
centralWidget = QtGui.QWidget(self)
layout = QtGui.QHBoxLayout(centralWidget)
#Set the fixed size
anotherWidgetOne.setFixedSize(20,20)
#Add other widgets to the central widget
layout.addWidget(self.anotherWidgetOne)
#Set the central widget
self.setCentralWidget(self.centralWidget)

Related

QDockWidget ignores layouts and size policy from the form

I'm subclassing from QDockWidget and I want my class to use form. I've made a form based on QWidget and included Ui class in my QDockWidget-based class. But the build result differs from the Qt Designer preview, because QDockWidget completely ignores all the preset size policies and layouts from the form, so most of the content just doesn't show up and the rest has nothing in common with the preset settings. My class looks fine if I subclass from QMainWindow or QWidget. How to use forms for QDockWidget?
This question could do with some sample code from the .ui files to clarify the question.
However one possible cause of this is that Qt form layouts QFormLayout by default don't expand to fill their parent widget. If the QFormLayout is embedded another top level layout such as a grid layout the contents of the QFormLayout will then expand to fill the available space.

How to prevent QTableWidget from occupying the whole window in a QHBoxLayout?

In my Qt program, I programmatically generate a modal QDialog. I want to show two widgets in this dialog window: A custom widget showing a camera output and a QTableWidget, showing the pixel coordinates of the corners found in the camera image. I generate a QHBoxLayout and add my custom widget and the QTableWidget into it. Then I set this QHBoxLayout as the Layout of the QDialog window. What I want to achieve is to share the available space in the QDialog's window area equally between my custom QWidget and the QTableWidget, horizontally, by using a QHBoxLayout. But I always end up with QTableWidget occupying the whole QDialog area, by overlapping my custom widget. How can I instruct these two widgets to exactly share the QDialog area?? Note that I first add my custom widget and then the QTableWidget into the QHBoxLayout.
Make sure on your custom widget you've specified a minimumSizeHint and a sizeHint, this instructs the QLayout manager that the widget requires a specific space. To have them split equally you'll be best off detecting the size of the QDialog and then specifying the width for both by removing the boundary sizes (spacing between widgets + space to QDialog edge) and dividing it up.

QT: two layouts add the same widget

In Qt: I create a widget-ui class, and I want to make the widget appear in two different layouts in two separate base widget(or window). So I want to:
widget_based_class* inside = new widget_based_class(base_widget1);
QHBoxLayout *lay1=new QHBoxLayout(base_widget1);
base_widget->setLayout(lay1);
lay1->addWidget(inside);
base_widget1.show();
-------------------------------
base_widget1.hide();
QHBoxLayout *lay2=new QHBoxLayout(base_widget2);
base_widget->setLayout(lay2);
lay2->addWidget(inside);
base_widget2.show();
How cound I achieve this? (My program is more complicated, and I didn't see the code work.)
Tank you.
A QWidget has only one parent widget and only one geometry (position and size) in that parent. Every call of QLayout::addWidget() will reparent that widget to the widget, the layout is installed on.
Your second call of setLayout won't work as expected, because you have to delete the the existing layout manager before setting the new one:
delete base_widget->layout();
base_widget->setLayout(lay2);
If base_widget hasn't already got a layout manager, the layout manager lay2 would simply be reparented.
If the widget will never be displayed twice on the screen, I don't see why you can't reparent it by addWidget/removeWidget.
In the OP, the parent widget/window is always hidden before the other one is shown. addWidget is called on the fly. We should also call removeWidget on the fly. It should be possible to move the widget around.
widget_based_class* inside = new widget_based_class(base_widget1);
QHBoxLayout *lay1=new QHBoxLayout(base_widget1);
base_widget->setLayout(lay1);
lay2->removeWidget(inside); // remove widget from other layout
lay1->addWidget(inside); // add widget to this layout
base_widget1.show();
-------------------------------
base_widget1.hide();
QHBoxLayout *lay2=new QHBoxLayout(base_widget2);
base_widget->setLayout(lay2);
lay1->removeWidget(inside); //remove widget from other layout
lay2->addWidget(inside); // add widget to this layout
base_widget2.show();
Make one widget and use a pointer in each layout?

Resizing a QDialog after adding components to a child widget

I'm a bit new to QT but have to work on existing code. Here's the case:
I have a class extending QDialog. the constructor sets a QGridLayout then adding three other widgets to it. One of the widgets is a QScrollArea containing a QGroupBox. this QGroupBox has a QVBoxLayout and there I'm adding a list of widgets at runtime. The size of the scroll area should grow until a given limit is reached before showing the scrollbars so that they are only used when the dialog would grow too high. I've found that the sizeHint of the outer layout doesn't update when the sizeHint of the scroll area updates. How can I refresh this, or is there a better way to resize the parent dialog?
What about using widgetResizable property of QScrollArea? It should try to resize view to avoid using scorllbars.

How does QWidget size when used as a window?

Several examples on trolltech use QWidget rather than a QMainWindow as the main window for simple Qt applications.
Now I need just a simple window with a single content widget (QGlWidget) that covers the entire client area.
However, when I show a QWidget window with a single content window it automatically resizes itself to be tiny.
If I create the QWidget parent window without a child It is a nice large default size.
I don't want to resort to using Layouts for a single child window :/
What I understand is that you use a QWidget to display your QGIWidget. Try calling the show method of your QGIWidget directly (if your QGIWidget class inherits QWidget), Qt will create the window decoration for you.
Otherwise if you really need your widget to be inside one another, and fit its size, you'll have to use a layout.
Either follow gregseth's advice or you can simply resize the widget yourself.
(though this way you'll loose nice auto-resizing which is provided by Qt when you use layouts)
In your case you can basically do something like:
QGlWidget* myWidget = new QGlWidget;
myWidget->resize(QApplication::desktopWidget()->availableGeometry().size());
// or maybe instead of resizing show it in fullscreen:
myWidget->showFullScreen();
(actually I don't remember if showFullScreen() will do resizing for you, maybe you'll need both resize+showFullScreen :))
Cheers :)
P.S. Using layout is actually an option. It's not expensive and it's flexible. All it gets: "layout = new QVBoxLayout(myWidget); layout->addWidget(myWidget);" and you're done :)
Not always.
I've found that a QMainWindow will not work as the parent widget when using the QVBoxLayout and QHBoxLayout to arrange child widgets.
If you create a QWidget and use that in place of the QMainWindow then the layouts will work correctly.
QWidget* centralWidget = new QWidget( MainWindow );
MainWindow->setCentralWidget( centralWidget );
If you use QtCreator and look at the code it creates you can see it creating a 'hidden' widget if you try to use the layouts directly at the top level.
It's not obvious, intuitive, or documented anywhere that I've found.

Resources