Unsolved Move QScrollArea between QWidgets
-
As a follow-up of an old thread, I need to move a
QScrollArea
, that is a page ofQTabBar
, to aQDialog
. This code shows an empty dialog:void MainWindow::createTabs(QStringList names) { foreach (QString name, names) { QWidget widget = new QWidget(); QScrollArea *scrollArea = new QScrollArea(); scrollArea->setWidgetResizable(true); scrollArea->setWidget(widget); // [...] populate widget with items ui->tabView->addTab(scrollArea, name); } } void MainWindow::tabView_tabCloseRequested(int index) { QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); // "save" the tab's widget ui->tabView->removeTab(index); QDialog *dialog = new QDialog(this); QVBoxLayout *layoutDialog = new QVBoxLayout(); layoutDialog->addWidget(area); // "restore" the widget into the dialog dialog->setLayout(layoutDialog); dialog->show(); }
Instead, if I set the dialog's layout to
area->layout()
I get the contents but without theQScrollArea
.
Why adding theQScrollArea
itself to the new layout doesn't show the contents? -
@Mark81 said in Move QScrollArea between QWidgets:
QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); // "save" the tab's widget
ui->tabView->removeTab(index);You did not even check whether you actually succeeded in getting the scroll area. Also, it could be that after removeTab the scroll area is deleted. You should at least check whether area is a valid pointer and if it is set parent to null to prevent it from being deleted if its parent is deleted.
-
@jsulm said in Move QScrollArea between QWidgets:
You did not even check whether you actually succeeded in getting the scroll area. Also, it could be that after removeTab the scroll area is deleted. You should at least check whether area is a valid pointer
mmm... the docs says the page is not actually deleted after removing it:
Removes the tab at position index from this stack of widgets. The page widget itself is not deleted.
In my case the page widget is
QScrollArea
.
Anyway, now I've checked the validity ofarea
:QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); qDebug() << area; ui->tabView->removeTab(index); qDebug() << area;
QScrollArea(0x332d2b78)
QScrollArea(0x332d2b78)@jsulm said:
and if it is set parent to null to prevent it from being deleted if its parent is deleted.
assigning a
QWidget
to aQLayout
doesn't re-parent it?
Anyway:qDebug() << area->parent(); QVBoxLayout *layoutDialog = new QVBoxLayout(); layoutDialog->addWidget(area); qDebug() << area->parent(); dialog->setLayout(layoutDialog);
QStackedWidget(0x333eda38, name = "qt_tabwidget_stackedwidget")
QStackedWidget(0x333eda38, name = "qt_tabwidget_stackedwidget")So it seems not - I must remember it wrong.
I did this:qDebug() << area->parent(); QVBoxLayout *layoutDialog = new QVBoxLayout(); layoutDialog->addWidget(area); area->setParent(dialog); qDebug() << area->parent(); dialog->setLayout(layoutDialog);
QStackedWidget(0x3330da38, name = "qt_tabwidget_stackedwidget")
QDialog(0x34551b10)but still the dialog is empty.
-
@Mark81 Just an idea: call show() after adding it to the layout
layoutDialog->addWidget(area); area->show(); // area->setParent(dialog); <-- remove this
I didn't mean to call setParent() after adding to layout but before removing it from tabView.
-
@jsulm ok, the things begin to work:
void MainWindow::tabView_tabCloseRequested(int index) { QScrollArea *area = qobject_cast<QScrollArea *>(ui->tabView->widget(index)); ui->tabView->removeTab(index); QDialog *dialog = new QDialog(this); dialog->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); QLayout *layoutDialog = new QVBoxLayout(); layoutDialog->addWidget(area); area->show(); dialog->setLayout(layoutDialog); dialog->show(); }
the last (minor) issue is a warning about the geometry:
setGeometry: Unable to set geometry 116x30+860+469 on QWidgetWindow/'QDialogClassWindow'. Resulting geometry: 116x92+860+469 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 92x92, maximum size: 16777215x16777215).
The content is shown but it doesn't fit the initial size of the
QDialog
. Perhaps I have to manually set its size? -
@Mark81 said in Move QScrollArea between QWidgets:
dialog->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
does it fit without this line?
-
@jsulm no, the
QDialog
is very small. Of course I can set a size manually, but if I create such a dialog with the same items in Designer (instead of move widgets at run-time) the initial size is set according to the contents. -
@Mark81 You can try to call https://doc.qt.io/qt-5/qwidget.html#adjustSize on the dialog
-
@jsulm with
adjustSize()
I don't receive anymore the warning about "Unable to set geometry" but still the size of the dialog is the same. Another trial I've done is to create a newQScrollArea
and set its content, instead of move the wholeQScrollArea
from the other widget. Well, in this case the layout is shown correctly (i.e. the dialog's size fits the content) but I surely did it wrong because it add another "frame" or "widget" outside (you see it like a padding where it should not be).