How to make Qt widgets resizeable? - qt

I want to create an application which consists of a QLineEdit and two QTableView widgets in vertical layout.
Sample code:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>401</width>
<height>301</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QTableView" name="tableView_2"/>
</item>
<item>
<widget class="QTableView" name="tableView"/>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>lineEdit</sender>
<signal>returnPressed()</signal>
<receiver>Dialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>200</x>
<y>14</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>
But these QTableView widgets are not resizable. I didn't found any property in Qt for this.
So how can I make these QTableView widgets resizable or auto expand and contract?
means if I reduce size of first QTableView widget then automatically size of second QTableView widget should increase means every widget should expand or contract automatically if I change size of any widget inside Vertical Layout at run time.
The sample code was designed in Qt4 Designer on Ubuntu 14.04.

Break the current layout, select the two widgets, click Layout Vertically in Splitter and finally select the form and click the layout vertically.

This is because you don't have a layout on your QDialog. What you did was you dragged a vertical layout on top of the dialog, now the dialog contains the layout which is absolute positioned and is not linked to the dialog. What you want to do is move the all the widgets from the vertical layout on top of a QSplitter, right click on the QDialog and at the Lay out context menu entry choose Lay Out Vertically, or alternatively click the QDialog and press Ctrl + 2. The result should be the following:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<height>305</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QLineEdit" name="lineEdit"/>
<widget class="QTableView" name="tableView_2"/>
<widget class="QTableView" name="tableView"/>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
What I recommend is reading the Qt Layout Management Documentation for more info on this topic.

Related

Minimize size of Qt widget

Following .ui file, created with Qt 5.7 Designer, shows a text box and a spacer:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="plainText">
<string>abc</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
For example, if the text field has "abc", it should be one line high; if it has two lines (say "abc\nabc"), OR one long line that requires two lines to display, then the text box should be two lines high.
Minimum height is 0. I tried changing the sizing policy of the text box so that the widget is as small as possible, but none do this.
Equivalent Python the code to do this is:
app=QApplication([])
widget = QWidget()
widget.setLayout(QVBoxLayout())
text_widget = QPlainTextEdit('abc')
# text_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding)
widget.layout().addWidget(text_widget)
spacer = QSpacerItem(20, 40, vPolicy=QSizePolicy.Expanding)
widget.layout().addSpacerItem(spacer)
widget.show()
app.exec_()

Nested structures with QRadioButtons

I would like to achieve something similar to this picture:
except that the top level ("Adress bar", "forms" and "User names...") should be radio buttons.
The idea is that the sublevels should get enabled or disabled depending on the state of the radiobuttons. And the sublevels should be shifted to the right as on the picture.
Can that be done Qt in an elegant way?
I would say a simple QVBoxLayout for the top level and each "sublevel" has a QHBoxLayout with a fixed sized spacer item as the first child and a QVBoxLayout containing the sub options.
Disabling all sub options can then simply be done by disabling the "sublevel" widget.
Just put those sub-items (like "Browsing history", "Favorites", ...) into a separated QWidget and connect that widget's QWidget::setEnabled() slot with the "Adress bar" radio-button's QAbstractButton::toggled() signal.
This is a Qt Designer's .ui file (with working signal-slot connection, try Ctrl+R in Designer) that demonstrates the idea:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>170</width>
<height>178</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="radioButton">
<property name="text">
<string>RadioButton</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_2">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_3">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_2">
<property name="text">
<string>RadioButton</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_3">
<property name="text">
<string>RadioButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>radioButton</sender>
<signal>toggled(bool)</signal>
<receiver>widget</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>84</x>
<y>17</y>
</hint>
<hint type="destinationlabel">
<x>84</x>
<y>77</y>
</hint>
</hints>
</connection>
</connections>
</ui>

Layout : How to make one widget 3x the rest in a vertical layout

I have 3 tables (A,B and C) in a vertical layout.The size policy (Horizontal and vertical) of these 3 are set to expanding. How can I make table-A 3 times the size of B and C and always have that ratio maintained. I am doing this through QT Designer.
Update:
In order to test the layout stretch method. I added four QlistWidgets inside a vertical layout to a form having a horizontal layout. Here is the XML for the form
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>formPracticeClass</class>
<widget class="QMainWindow" name="formPracticeClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>847</width>
<height>661</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>formPractice</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0,0,0">
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
<widget class="QListWidget" name="listWidget_3"/>
</item>
<item>
<widget class="QListWidget" name="listWidget_2"/>
</item>
<item>
<widget class="QListWidget" name="listWidget_4"/>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="formpractice.qrc"/>
</resources>
<connections/>
</ui>
The vertical layout with the 4 widgets has a stretch layout of 1,0,0,0. The height of the topmost widget looks smaller to the others. I want the topmost widget to be 2 times bigger than the others
On the layout that contains the 3 tables, set the layoutStretch property to 3,1,1 in Qt Designer. This specifies that the first element in the layout should have 3 times the space as the other two elements in the layout.
Update:
For your updated example .ui file, you can make the topmost widget to be 2 times larger than the others by setting the layoutStretch to 2,1,1,1:
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="2,1,1,1">
Note that the stretch property specifies ratios between the different elements of the layout. In other words, you won't get the desired results if you set one of the elements in the layoutStretch property to 0.

Widget with maximum size does not follow AlignHCenter

I have a vertical layout with a label and a QGraphicsView. I have set the maximum size of the QGraphicsView, and set the horizontal alignment to AlignHCenter, but it still seems to appear on the left rather than cenetered? Here is a demo ui file:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
If I change the Horizontal alignment of the label, it behaves as I'd expect (Left moves it to the left and AlignHCenter moves it to the center), but the QGraphicsView does not follow that behavior - it is always on the left.
How would I centered this fixed size QGraphicsView?
If you wrap the QGraphicsView in a QHBoxLayout as shown then it will appear centered like you expect. You can insert a horizontal spacer on the left or right if you want it aligned to either side.
The alignment property controls its behavior when the QGraphicsView has a scrollbar, not its relative position in the QLayout.
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGraphicsView" name="graphicsView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
</widget>
</item>
</layout>
</item>

How to make QDockWidget to expand when the window is resized?

I have a simple form: QDockWidget on the right side, QGroupBox on the left side of QMainWindow. QGroupBox is layed out using vertical layout.
I want QDockWidget to be expanded and occupy all the free space when the main window is enlarged or maximized.
How do I do it?
Bellow is the source code of my .ui file.
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>653</width>
<height>381</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QDockWidget" name="dockWidget">
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents"/>
</widget>
</widget>
<resources/>
<connections/>
</ui>
You will need to reimplement QWidget::changeEvent (or a resizeEvent for resizing) to react to QEvent::WindowStateChange. If one of those events occurs, get the QWidget::windowState and resize your dock to whatever you want.

Resources