In Qt I have removed the central widget in an xml editor and replaced it with a QScrollArea, this works when I preview it in QtDesigner:
but when I run the program it looks like this:
Are you not meant to remove the central widget or is there a sizePolicy I have to change?
Here is the 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>179</width>
<height>191</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>224</width>
<height>628</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>75</pointsize>
</font>
</property>
<property name="midLineWidth">
<number>2</number>
</property>
<property name="text">
<string>label
</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>179</width>
<height>19</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="1.qrc"/>
</resources>
<connections/>
</ui>
Check your ui_mainwindow.h. See if there is a line like:
MainWindow->setCentralWidget(scrollArea);
You can use QMainWindow::setCentralWidget function in your mainwindow.cpp to set a central widget to your main window:
setCentralWidget(myScrollArea);
I don't think there is any way of changing the central widget from the designer.
I am getting proper window when I ran the program with your ui file content. I don't know why it is not creating problem like you have.
I would recommend you to use Qt designer inbuilt in Qt Creator which I felt easier to use.
Also, I think the problem can be one of these:
Generally central widget is good as it provides a base on which you can place all your layouts. So, it is good to have it in your UI.
Here, take care that after inserting widgets into layouts you don't simply break those layouts. The designer will reset the widget width and height. So you have to set them again.
Next, this may have occured if the ui file loaded in designer is not up-to-date while it is changed on disk.
Keep track of all the layouts, the geometry and sizePolicy of widgets.
I won't be able to answer in code since when I used the ui file content which you have given, it doesn't cause problem here.
Create a layout on your mainwindow in which you would put your QScrollArea. This would expand it according to the layout.
P.S. : I open it in Qt Creator.
So please give some more info whether it is fixed when you set the geometry of scrollarea manually.
Related
I use QGridLayout very often, and there's a requirement I don't know how to or if I can achieve with this kind of layouts.
My question: Imagine I have two normal widgets (derived from QWidget) on the left and right (on something like QHBoxLayout or QGridLayout), and I would like to have the line separating them movable by the user. Is that possible?
More information:
To give an example, imagine the default Windows registry editor. You have the part on the left, where there are keys and paths, and on the right, where there are values to be edited.
I would like to emphasize that I'm not asking for an explorer view. What I have basically is a plot widget on the right, and a QTableView widget on the left, and I would like the user to be able to conveniently scale with his mouse, which widget should be horizontally bigger.
Is there some kind of Layout that is scalable by mouse?
Please ask for more information of you require it.
I think you should use a QSplitter.
According to the documentation:
A splitter lets the user control the size of child widgets by dragging
the boundary between the children. Any number of widgets may be
controlled by a single splitter.
For example, using Qt Creator, if we have two QGridLayout with a QPushButton on each one, we can select both QGridLayout and use the Lay Out Horizontally in Splitter option.
After that, we could move the boundary between them to control the size of child widgets:
I made an example. Here you have the code for the 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>435</width>
<height>105</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QSplitter" name="splitter">
<property name="geometry">
<rect>
<x>9</x>
<y>10</y>
<width>411</width>
<height>71</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="gridLayoutWidget_2">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
In my project I display a QMenu with several QAction objects. I want the QAction icon to change when the user hovers over it.
Here is my current code:
QPixmap icons(":/icons/platformIcons.png");
QIcon icon;
icon.addPixmap(icons.copy(0, 0, 16, 16), QIcon::Selected, QIcon::On);
icon.addPixmap(icons.copy(0, 16, 16, 16), QIcon::Selected, QIcon::Off);
ui->actionOpen->setIcon(icon);
However the icon doesn't change when the user hovers over the QAction. I've tried modes Normal and Active and the result is the same. If I switch the states, the icon is reversed, but still doesn't change on a hover (or click for that matter).
Thanks for your time.
Support for hovering normal/active icons in menus and toolbars seems to depend on the platform style, and is not supported with native Mac styling in particular, even when disabling usage of the native menu bar (ie. having the menus show at the top of the desktop rather than within the application window).
I've made a quick try with a Qt Designer form on a Mac to replicate your use case (basically ends up as the same C++ code using QIcon::addPixmap()):
?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>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>22</height>
</rect>
</property>
<property name="nativeMenuBar">
<bool>false</bool>
</property>
<widget class="QMenu" name="menuYo">
<property name="title">
<string>Yo</string>
</property>
<addaction name="actionFoo"/>
<addaction name="actionBar"/>
</widget>
<addaction name="menuYo"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionFoo"/>
<addaction name="actionBar"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionFoo">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset>
<normaloff>../red-circle.png</normaloff>
<normalon>../greeb-circle.png</normalon>
<activeoff>../red-square.png</activeoff>
<activeon>../green-square.png</activeon>../red-circle.png</iconset>
</property>
<property name="text">
<string>Foo</string>
</property>
</action>
<action name="actionBar">
<property name="text">
<string>Bar</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
When using the default Mac styling, I only get the red/green circle icon in the menu and the toolbar, even when hovering the mouse. However if I force another style with e.g. ui->menuYo->setStyle(QStyleFactory::create("fusion")); then the hovering works, but the menu doesn't look native anymore...
I am doing my first larger project using the QT framework and as my menu begins to scale more I feel like I need either the ability to swap out multiple central widgets, or have a new form all together but without opening another window. I cannot seem to figure out how to go about this.
Essentially I would want the user to click say the "settings" button, and for all the widgets to either hide themselves, and for the new ones to show themselves, without opening another window and sticking to just 1 window. Here is the cat output to 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>800</width>
<height>600</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>520</y>
<width>781</width>
<height>71</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="joinGamePushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Join Game</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="settingsPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Settings</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="aboutPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>About DMUX</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="exitPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Exit</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections>
<connection>
<sender>exitPushButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>692</x>
<y>555</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
</connections>
</ui>
What exactly is the best approach here? Should I use several central widgets and somehow drop them in as needed, or use multiple formed and load them when a button is clicked? I am using QT Creator for this project at the moment, so it would be preferred that I use it's generation of code instead of writing a solution myself.
I am doing my first larger project using the QT framework and as my
menu begins to scale more I feel like I need either the ability to
swap out multiple central widgets, or have a new form all together but
without opening another window. I cannot seem to figure out how to go
about this.
Either QMainWindow::setCentralWidget for inserting new widget as 'central' or make a permanent 'central' QStackedWidget for just flipping between stacked widgets.
Which one is better? Both would require to refactor your template and separate widgets you would like to embed depending on user selection as separate .ui pieces or maybe just fully programmatically created ones.
setCentralWidget would need you to take care of disposing previous widget when inserting new one (simpler) or using some type of container to keep already created 'detached' widgets in there (more complex: prone to bugs).
QStackedWidget as selector-viewport would need you to precreate widgets or possibly create and stack new ones on demand.
I have a simple qt ui that contains
|- central widget
|- label
|- button
I would like to manually place and resize the label and button freely (using the mouse), and I just can't seem to be able to do that.
I can only resize the entire window, and the label/button stretch with it. I tried all combinations of size policies
Thanks!
<?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>326</width>
<height>254</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Bla</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="startButton">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
try to remove
<layout class="QVBoxLayout" name="verticalLayout">
and
</layout>
but if you are working under qt creator or qt designer,
you can easily do this thing. You need to choose centralWidget and click to button Break Layout that placed under menu bar.
Check this documentation. This should be helpful to utilize Qt Designer components. It is quite possible that you don't have to do lot of work. I never used this so my help ends here.
Attached is an example of the QT Designer with my issue. My goal is to get any content inside (in particular the lineEdit) to expand to the far right of QTabWidget its within.
If you notice I have the tab selected in the picture and it says there is no layout currently (as indicated by the red no smoking looking symbol on it). When I try to add a layout to it using the buttons above the tabs (for horizontal, vertical, grid, form, etc...), no matter what I do it doesn't change the tabs layout but changes the very top level widgets layout instead which I don't want because that is giving the QTabWidget its ability to take on whatever the size of the window is.
I tried giving a horizontal and vertical layout to the elements within the tab thinking that might work but it didn't work either as my next attached image shows. My hunch is because the tab has no layout, any layouts within will not be honored.
Any help is appreciated. I've spent hours and can't figure it out for the life of me...!
Below is the UI XML:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>xMarket</class>
<widget class="QWidget" name="xMarket">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>737</width>
<height>421</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTabWidget" name="xMarketTabWidget">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>240</x>
<y>30</y>
<width>113</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>150</x>
<y>30</y>
<width>59</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Search:</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
To set the layout on a tab, you first need to select its parent tab-widget.
You can do this either by selecting it by name in the Object Inspector (i.e. by clicking on xMarketTabWidget in your example), or by simply clicking on an appropriate tab in its tab-bar. The parent tab-widget must have a selection rectangle around it before you can set a layout on one of its tabs.
Once you've done that, you can click the Lay Out Horizontally or Lay Out in a Grid button on the Designer toolbar to set an appropriate layout for your tab. But note that a tab must have at least one child widget before you can set a layout on it - the layout buttons will all be disabled for empty tabs.