Swap widgets in place, without destroying them in layout.
-
Hey,
Is it possible to swap two or more widgets in place inside a layout, any layout?
For example I have a vertical layout, with 2 widgets, I need to swap their places. If there wasn't a layout, I would just moved those widgets in each other coordinates. widget1->move(x,y);
Is there a similar "move" command for layouts, where I can move widgets by rows and not by coordinates?
Kind Regards
Raivis -
There is an "example using QML.":http://labs.qt.nokia.com/2010/01/27/upcoming-qtcreator-support-for-qml-or-what-is-bauhaus/
-
I've not done it before, but I think it is possible.
Just curious, why do you want that ? Can you explain some more about what your program is supposed to do? What kind of widgets do you want to use?I'll test it out tomorrow. Now it's time to get some sleep.
-
I have two Video embedded plain QWidgets.
And a vertical layout, which expands according to the size of Main window.
Each widget is different size. To be more precise I need to swap those QWidget places, and one of them to reduce size, and the other to enlarge.I think it will be easier to show it with picture.
!http://morf.lv/swap.jpg(SWAP)!
The red border represents, the layout
And those gray squares - QWidgets, which I want to swap, after click on a button, or the widget itself.I just want to remind once more, I don't want to delete them or hide them. I just want to simply move them.
Thank you, sleep well, I'm off to bed as well.
-
Haven't tackled the resizing issue, but with only two items, swapping the items may be as simple as calling setDirection() on your layout.
For example (pardon my rough code. I just threw this together):
widget.h
@
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QHBoxLayout>
#include <QLabel>class Widget : public QWidget
{
Q_OBJECTpublic:
Widget(QWidget *parent = 0);protected slots:
void doSwap();private:
QHBoxLayout *swapLayout;
QLabel *item1;
QLabel *item2;
};#endif // WIDGET_H
@widget.cpp:
@
#include "widget.h"#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>Widget::Widget(QWidget *parent) : QWidget(parent)
{
QVBoxLayout *vlayout = new QVBoxLayout(this);
vlayout->setSpacing(10);swapLayout = new QHBoxLayout();
swapLayout->setSpacing(10);item1 = new QLabel();
item1->setStyleSheet("background: red");
item1->setText("Item 1");
item1->setAlignment(Qt::AlignCenter);swapLayout->addWidget(item1);
item2 = new QLabel();
item2->setStyleSheet("background: yellow");
item2->setText("Item 2");
item2->setAlignment(Qt::AlignCenter);
swapLayout->addWidget(item2);vlayout->addLayout(swapLayout);
QPushButton *swapbutton = new QPushButton();
swapbutton->setText("Swap");vlayout->addWidget(swapbutton);
connect(swapbutton, SIGNAL(clicked()), this, SLOT(doSwap()));
}void Widget::doSwap()
{
if (swapLayout->direction() == QBoxLayout::LeftToRight) {
swapLayout->setDirection(QBoxLayout::RightToLeft);
} else {
swapLayout->setDirection(QBoxLayout::LeftToRight);
}
}
@and a standard-issue main.cpp:
@
#include <QApplication>
#include "widget.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.resize(300,300);
w.show();return a.exec();
}
@ -
Nice work, mlong!
Seems there is Qt coding happening all around the clock. ;)
About the sizes: with mlong's solution, you could play with maximum sizes in the if then else block.
Is there anything else in the white zone on the right? If there is this could complicate things.
-
Exactly, I'm manually resizing them, but I don't want to remove those widgets and re-add, that's why I'm asking for another solution.
I have a video player embedded in those widgets from a LAN camera, I don't want to stop and start the stream.
If it's impossible I'll just start thinking of algorithm which aligns those widgets in main window, without using layouts, but pure coordinates.
But it would be nice, if it were possible to just swap them in layout.
-
[quote author="Eddy" date="1311913479"]Nice work, mlong!
Seems there is Qt coding happening all around the clock. ;)
[/quote]Wasn't any big deal... you guys are the slackers that went to bed mid-afternoon! ;-)
Anyway...
Speaking of removing items from layouts, I was looking at that myself. I've never had to do that, actually, and could use some clarification on the proper way to do so.
Do you have to use takeAt() for that? If so, I see it returns a QLayoutItem*. That's where I get a little confused. Does the original widget have to be wrapped in a layout item to begin with, or does it just return this object from which you can extract the original widget? I haven't seen any good concrete examples of this in use, outside the descriptions in the docs.
-
[quote author="mlong" date="1311946567"]
Speaking of removing items from layouts, I was looking at that myself. I've never had to do that, actually, and could use some clarification on the proper way to do so.
Do you have to use takeAt() for that? If so, I see it returns a QLayoutItem*. That's where I get a little confused. Does the original widget have to be wrapped in a layout item to begin with, or does it just return this object from which you can extract the original widget? I haven't seen any good concrete examples of this in use, outside the descriptions in the docs.
[/quote]Yes. Use
QLayout::count + itemAt to get the i-th item in a layout;
QLayoutItem::widget to know 1) if it's a widget 2) which widget is that item wrapping
QLayout::takeAt to remove the item from the layout
an addItem overload (depending on the layout you're using) to readd it back in another position.
You could also delete the QLayoutItem and create another one (remember that they don't own the widget they wrap).