I can't figure out how creating a toolbar with two rows of widgets. I'm working on a Python3/Qt4 project.
My guess :
add a widget to the toolbar widget
add a vertical layout (or a QGridLayout, it doesn't matter) to the widget
add the toolbar's buttons to the layout
But all I get is a tiny and empty toolbar : do I need to somehow 'stretch' the widget ?
My Python3 code, trying to insert vertically two buttons in the toolbar :
self.main_toolbar = self.addToolBar('MyToolBar')
self.toolbar_widget = QtGui.QWidget(self.main_toolbar)
self.toolbar_layout = QtGui.QVBoxLayout()
self.toolbar_widget.setLayout(self.toolbar_layout)
button1 = QtGui.QPushButton(self)
button1.setText("button1")
self.toolbar_layout.addWidget( button1 )
button2 = QtGui.QPushButton(self)
button2.setText("button2")
self.toolbar_layout.addWidget( button2 )
The code you posted is fine, it's just that you forgot to add your widget to the toolbar.
You can do this using QToolBar.addWidget:
self.main_toolbar.addWidget(self.toolbar_widget)
It's simple: you really need two toolbars, one under another.
You can't merely add child widgets to a toolbar. Your main_toolbar is presumably of the QToolBar class. You can't simply add a toolbar_widget to it!
Neither you can change the layout of a QToolBar. The toolbar manages the layout of its children itself, you're not supposed to mess with it - it's not designed that way.
The only way of adding widgets to a toolbar is via the addWidget method of the toolbar, not of the layout!
Your code is wrong. What you can do, and all that you can do with a toolbar is:
self.main_toolbar = self.addToolBar('MyToolBar')
button1 = QtGui.QPushButton(self)
button1.setText("button1")
self.main_toolbar.addWidget( button1 )
button2 = QtGui.QPushButton(self)
button2.setText("button2")
self.main_toolbar.addWidget( button2 )
What you want to do is simply not supported by the toolbar. The toolbar may, perhaps, arrange its items in more than one row if they don't all fit. It probably depends on the style. You're free to insert "tall" toolbar widgets that have an internal layout and two sub-buttons inside, but it'll look very ugly.
Related
I started Qt Designer to create a window for the Maya tool.
I'm making the same GUI as Snap of Blender. How do I make the display change like this?
What is it called in Qt to show a different one for each button?
Two options I can think of
1. Use a StackedWidget (left)
A StackedWidget is a container that contains multiple widgets, but shows only one at a time. You can set which one is visible with .setCurrentIndex(int index) and .setCurrentWidget(QWidget*).
This is basically what you want to do, except by default it is going stay as tall as the tallest widget, even with a spacer (as visible on the screenshot).
This can be forced manually, or you can even create your own widget to do that (https://www.qtcentre.org/threads/28514-How-can-i-achieve-an-auto-resizing-QStackedWidget), but it defeats a bit its ease of use.
2. Widgets, hide/show, spacer (right)
The second option, really basic, is to create different Widgets that will act as containers, and that you will toggle (.show()/.hide) whenever a button is pressed. This can even be done from the Designer of QtCreator if you are looking for the easiest way to achieve it.
Make your buttons checkable, and exclusive (as you probably did)
Connect to the clicked(bool checked) or toggled(bool checked) signal
Call show/hide on the container widgets to show only one. Et voila!
MyWidget:MyWidget(...)
{
connect(ui->vertexButton, &QPushButton::clicked, this, &MyWidget::onButtonClicked);
}
void MyWidget::onButtonClicked(bool checked) {
button = sender();
if (button == ui->vertexButton) {
ui->vertexContent->show();
ui->edgeContent->hide();
} else if ...
}
Disclaimer: I haven't tried to compile the code above
Currently I have a set of buttons in a QVBoxLayout which is inside a QHBoxLayout.
Is there a way to move these according to where my mouse is?
My current code is like this:
self.button1 = QPushButton()
self.button1.setText("button A")
self.button2 = QPushButton()
self.button2.setText("button B")
vbox = QVBoxLayout(self.canvas)
vbox.addStretch(1)
vbox.addWidget(self.button1)
vbox.addWidget(self.button2)
hbox = QHBoxLayout(self.window)
hbox.addStretch(1)
hbox.addLayout(vbox)"
The prototype for moving some button widget would be:
vbox.removeWidget(self.button) // that only needs the reference to your button item
vbox.insertWidget(newPos, self.button) // mind the difference in target position when you remove one item
That does not cover event processing. With two buttons you can either do that twice for each or maybe altogether, mind the target positions.
Or you can move an entire layout within another layout for the group of buttons in a very similar fashion. That'd be moving layout item. As long as you don't imply those buttons cannot be moved separately the example is for individual buttons. Oh, there is some Qt C++ discussion about that.
To keep the question as simple as possible, I prepared a simple Qt designer form below
There is a Tab Widget on the left side and empty QWidget on the right side, the QWidget as a GroupBox. The Groupbox has a radio and pusbuttons (you can see them on Object inspector window on the photo as well ). The tab widget has a line edit. The central widget has a gridlayout and horizontal qsplitter is used.
My issue is that when I enlarge the window, all items (lineedit, radiobutton, pushbutton) are on the fix position. Here is an example what I mean:
What I want is that when the window is enlarged the items should be placed on the bottom of the window, or if they are in the middle, then they should stay in the middle. ( I don't want size of the buttons/lineedits to be changed).
How can I do it?
The items you want to move dynamically, with window resizing must be in a layout.
So, in the example you've posted, you need two layouts; one inside the tab widget, for the QLineEdit and at least one in the GroupBox for the radio button and push button.
If you want the radio and push button to be aligned horizontally, you can start by placing them in a horizontal layout, before placing that layout in another, which all reside in the group box.
When you start to add items to layouts, such as push buttons, you'll start to notice that they can get stretched, so you may need to set the size policies of the widgets.
If you want the line edit to be centered horizontally, you will have to place two horizontal spacers on each side of the line edit and select the three together and set "Lay out Horizontally". This can found at the top toolbar in Qt Designer.
To always have it at the bottom of the tab widget, put a vertical spacer above the line edit in your tab widget. Then select the option "Lay out vertically" for the tab widget.
The same goes for your radio button and push button. Keep them in a horizontal layout, with horizontal spacers if required and put a vertical spacer into the group box and set the layout property for the group box as "Lay out Vertically".
Most important of all, I suggest you go through some basic tutorials before you continue. Here is a link to a good channel on youtube.
https://www.youtube.com/playlist?list=PL2D1942A4688E9D63
If you don't have a layout in your tabWidget or GroupBox:
You must set a layout (for example QVBoxLayout) inside your tab widget and a group box.
It can be done using QtDesigner. It also can be done in code like this:
QWidget *window = new QWidget;
QPushButton *button1 = new QPushButton("One");
QPushButton *button2 = new QPushButton("Two");
QPushButton *button3 = new QPushButton("Three");
QPushButton *button4 = new QPushButton("Four");
QPushButton *button5 = new QPushButton("Five");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
layout->addWidget(button5);
window->setLayout(layout);
But if you do, and then you want your buttons to stay at the bottom:
Then you have to try setRowStretch method http://qt-project.org/doc/qt-4.8/qgridlayout.html#setRowStretch or take a look at QSpacerItem.
I am using Qt Designer, and I would like to move a couple of top-level widgets into a horizontal layout.
I have dragged a "Horizontal Layout" object into the form. I am now attempting to drag the desired widgets into the layout.
Unfortunately, the new Horizontal Layout widget is infinitely thin:
... and I cannot drag my "Import Progress" label widget or my progress bar widget into the new horizontal layout widget.
Note that when I attempt to drag the desired widgets over the new horizontal layout widget, Qt Designer does not do anything useful for me in terms of expanding the drop region to make the horizontal widget available as a drop target. So I'm stuck.
How do I add widgets to an infinitely-thin layout widget in Qt Designer?
Select the layout, and then drop the widget onto the corresponding selected item in the Object Inspector pane. If you find it tricky to select the layout on the actual form, you can also select it via the Object Inspector pane.
One way (that I usually do as a workaround for not having to show the structure panel) is to select the layout, setting the top or bottom margins to any value (10, whatever) and then dragging the component into the layout. Yeah, that is just for the pure pleasure of dropping the component in the layout, i know, but is a way.
My small trick:
Select layout
Change temporary "layoutTopMargin"
Drop into layout required widgets
Restore layoutTopMargin to default 0
I've been using Qt for some times, but I'm quite new to layouts. I would like to create a dialog with a QTextEdit inside, and the QTextEdit would resize to fill the whole dialog. How can I use layouts to do that? Or is there some other technique that I'm missing?
I have tried adding a layout to the dialog, then put the QTextEdit inside. However, I cannot find any property to make the layout fit the whole dialog.
After adding the text edit to your form, right click on the form and you will see a "Lay out" menu item at the bottom of the context menu, select that and then the layout type you want to use. The designer will create a top level layout of that type for your form and the text edit should now expand to fill the form.