Qt Mdi Area get size not including scroll area - qt

I have some issue with Qt MdiArea where I created a sub-window which fit inside MdiArea, and then I check the size of MdiArea got correct result. But if I move the window to the end of MdiArea which will make scroll bar appear, and check the MdiArea size again, but getting the same size as window without scrollbar. I think the scroll area not considering while getting size, but only the viewport size returning.
How I can get the total size including scrollable area of the MdiArea.
Code:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation);
// Set Mdi Area as the central widget
setCentralWidget(ui->mdiArea);
QWidget *widget = new QWidget(ui->mdiArea);
QMdiSubWindow *w1 = ui->mdiArea->addSubWindow(widget);
w1->resize(320, 240);
// And show the widget
widget->show();
}
void MainWindow::wheelEvent(QWheelEvent *event)
{
qDebug()<<"mdiArea size: "<<ui->mdiArea->size();
}
Correct Result without scroll bar.
Wrong Result with scroll bar.

Related

How to expand layout in scrollarea with added content

I have a ScrollArea which contains a frame to hold a layout. By pressing a button (Plusbutton below) I add new Widgets to the layout in the ScrollArea.
After adding several Items the Widgets get smaller and cut off. I want the layout to get bigger with added Widgets and want be able to scroll further down to see the added content.
[Edit]
I have constructed those widgets in Qt designer so i cant provide that much code. But i hope this will help you understand my problem.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->scrollArea->setWidgetResizable(true);
ui->verticalLayout_6->insertWidget(0,ui->blueframe,Qt::AlignTop);
}
void MainWindow::on_addwidget_pressed()
{
ui->verticalLayout_6->insertWidget(2,new Toolbar);
}

Allignment of a QLabel and a QCheckBox in a BoxLayout gives unexpected result

when i add a QLabel and QCheckBoxs to either a QVBoxLayout or a QHBoxLayout i would expect them to be evenly distributed but the checkboxes will allign tight at the very bottom (in the above example) and the label will be centered on the resulting free space in the widget. How can i change this behaviour to distribute all 3 widgets evenly?
Many thanks.
This is the example code:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
QLabel* l = new QLabel("Hi");
QCheckBox* c = new QCheckBox("Label");
QCheckBox* c2 = new QCheckBox("Label");
l->setText("Hi");
QVBoxLayout* v = new QVBoxLayout;
v->addWidget(l);
v->addWidget(c);
v->addWidget(c2);
setLayout(v);
ui->setupUi(this);
}
And this is the result:
Take a look at QSizePolicy. You need to setSizePolicy for your QLabel and QCheckBoxes to be QSizePolicy::Preferred, from the docs:
The default policy is Preferred/Preferred, which means that the widget
can be freely resized, but prefers to be the size sizeHint() returns.
Button-like widgets set the size policy to specify that they may
stretch horizontally, but are fixed vertically. The same applies to
lineedit controls (such as QLineEdit, QSpinBox or an editable
QComboBox) and other horizontally orientated widgets (such as
QProgressBar).
Currently, your QLabel has preferred height, while both of the QCheckBoxes has fixed height. That means that the QLabel will be expanded automatically to take up any additional vertical space (that can't be taken by the QCheckBoxes.
So, In order to set all your widgets to Preferred height, you need to add the following to your constructor:
l->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
c->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
c2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
Another option, would be to add spacers around each one of the widgets, like this:
v->addStretch();
v->addWidget(l);
v->addStretch();
v->addWidget(c);
v->addStretch();
v->addWidget(c2);
v->addStretch();
setLayout(v);
This way QSpacerItems will take up all the additional space.

Resizing child widget with keeping aspect ratio when parent widget resized

I have four widgets in a QWidgets named FourWindowWidget I am trying to put these four widgets in FourWindowWidget as one at top and remaining under that while the top one should always have 70% of the size of FourWindowWidget. I tried following :
QSize size = ui->FourWindowWidget->size();
ui->View1->setFixedHeight(size.height()*0.70);
QHBoxLayout * lay = new QHBoxLayout();
lay->addWidget(ui->View2);
lay->addWidget(ui->View3);
lay->addWidget(ui->View4);
lay->setMargin(0);
lay->setContentsMargins(0,0,0,0);
QGridLayout * mainlay = new QGridLayout;
mainlay->addWidget(ui->View1,0,0);
mainlay->setContentsMargins(0,0,0,0);
mainlay->setHorizontalSpacing(0);
mainlay->setSpacing(0);
mainlay->setMargin(0);
mainlay->addLayout(lay,1,0);
delete ui->FourWindowWidget->layout();
ui->FourWindowWidget->setLayout(mainlay);
this->update();
Now the problem is now View1 have fixed size but size of FourWindowWidget is not fixed. It changes when I remove any other widget around it like closing dock widget. This resize is expected, or say I don't want to make it fixed. So when ever FourWindowWidget get resized its child widgets should be as per ratio set. But I am unable to do this cause
1. There is no any signal that inform resize so the height of internal widget will be calculated.
2. No other way I found to set 70% height of top widget rather than setFixedHeight in grid layout.
I have tried with setting QSizePolicy to setHieghtForWidth but iit is not a working solution.
Please suggest me to do this by any way.
The Question is kind of duplicat of Resizing Qt Widgets based on Window size but there nobody answered.
Setting the stretch factor for your layout should work. I'm not sure why you are using a grid layout for this, when you are adding everything in the same column, but here is an example that works:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
gridLayout = new QGridLayout;
this->centralWidget()->setLayout(gridLayout);
label1 = new QLabel("l1");
label2 = new QLabel("l2");
label3 = new QLabel("l3");
label4 = new QLabel("l4");
gridLayout->addWidget(label1, 0, 0);
gridLayout->addWidget(label2, 1, 0);
gridLayout->addWidget(label3, 2, 0);
gridLayout->addWidget(label4, 3, 0);
gridLayout->setRowStretch(0,7);
gridLayout->setRowStretch(1,1);
gridLayout->setRowStretch(2,1);
gridLayout->setRowStretch(3,1);
}
In this example label1 will take 70% of the available vertical space, while the other labels will take combined 30% of the available vertical space.

QDockWidget sized wrong when docked on right side of Main Window

I am new to Qt and I am trying to create a DockWidget that docks on the right of the window. I set a maximum and minimum width for the dock (as you will see in the code below). This works if the dock widget is added with Qt::LeftDockWidgetArea, but when it is added with Qt::RightDockWidgetArea, The dock is "padded" out to the center of the window, like this:
I am probably not sizing the dock in the correct way.. Here is the code for this window:
int main(int argv, char** args)
{
QApplication app(argv, args);
QMainWindow window;
QDesktopWidget* desktop = QApplication::desktop();
//Docks
QDockWidget* propertyDock = new QDockWidget("",&window);
QWidget* propertyDockContents = new QWidget;
//This sets the window in the center of the screen.
int wWidth = 800; int wHeight = 600;
window.setGeometry(QRect( (desktop->width()-wWidth)/2 , (desktop->height()-wHeight)/2 ,wWidth,wHeight));
propertyDock->setAllowedAreas(Qt::RightDockWidgetArea);
propertyDockContents->setMaximumWidth(200);
propertyDockContents->setMinimumWidth(20);
propertyDock->setWidget(propertyDockContents);
window.addDockWidget(Qt::RightDockWidgetArea,propertyDock);
window.show();
return app.exec();
}
Is there a "correct" way to do this?
As stated in the documentation:
Note: Creating a main window without a central widget is not supported. You must have a central widget even if it is just a placeholder.
Yes! You can't creating a main window without a central widget, But you can set central widget's height to zero.
MainWindow.cpp
centralWidget()->setMaximumHeight(0);

Programmatically scroll QScrollArea

I have a Widget with QScrollArea in it and I want it to be scrolled down right after the widget containing it is shown. I tried:
scrollArea->ensureVisible(0,100, 20, 20);
It works only when invoked by user (pushing button for example). Putting it in widget contstructor or showEvent doesn't work. Can it be done automatically?
I believe you can scroll the QScrollArea content by setting positions to its horizontal and vertical scrollbars. Smth, like this:
scrollArea->verticalScrollBar()->setValue(scrollArea->verticalScrollBar()->value() + 10);
scrollArea->horizontalScrollBar()->setValue(scrollArea->horizontalScrollBar()->value() + 10);
code above should scroll contents of the scroll area 10 pixels down and 10 pixels right each time it gets called
hope this helps, regards
Edit0: extra code snippet showing how to scroll the area in the form's constructor:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QLabel *imageLabel = new QLabel;
QImage image("my_large_image_file.JPG");
imageLabel->setPixmap(QPixmap::fromImage(image));
ui->scrollArea->setBackgroundRole(QPalette::Dark);
ui->scrollArea->setWidget(imageLabel);
ui->scrollArea->horizontalScrollBar()->setValue(100);
ui->scrollArea->verticalScrollBar()->setValue(100);
}
I have spent some time with the debugger and find out that scriollArea has 0 sizes in the constructor, so it looks like it is possible to scroll something only when all the widgets are created and visible. Scrolling in the showEvent of window works fine.

Resources