Design custom QT Widget on top of QT Window - qt

I have a QT main window and on top of this I want to add a widget ( containing buttons), as similar to image below.
If I add a dock widget , it is added in separate row, but not added as overlay on existing main window.
Any inputs ?

The easiest is to set your overlay widget's parent to be the main window. But because it will not be in any layout you have to take care of its geometry yourself. In case you want to have multiple overlays, the last added will be the top most.
#include <QApplication>
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMainWindow *window = new QMainWindow();
QWidget *centralWiddget = new QWidget();
window->setCentralWidget(centralWiddget);
QVBoxLayout *layout = new QVBoxLayout(centralWiddget);
QPushButton *button = new QPushButton("Button in a layout");
layout->addWidget(button);
QPushButton *overlayButton = new QPushButton("Button overlay");
overlayButton->setParent(window);
overlayButton->setGeometry(40, 40, 120, 30)
window->show();
return app.exec();
}

You should look into using QStackedLayout to so this.

Related

How to avoid hidden QWidget height included in QStackedLayout?

I have this scenario with which I have been struggling for few hours:
I have a main widget, whose layout is set to main_layout, before which 3 layouts are added to the main_layout:
A QVBoxLayout (header_app_layout)
A second QVBoxLayout (header_loader_layout)
A QStackBoxLayout (content_layout)
The QStackBoxLayout (content_layout) has 2 child widgets added to it, of which only 1 is shown:
m_content1_widget (shown widget)
m_content2_widget
My problem is that, content_layout is taking into consideration the heights of the hidden child widgets in the widget: m_content1_widget, because of which the main_widget height is overflowing.
If I change content_layout from QStackedLayout to QVBoxLayout type, it all starts working fine.
So it seems to me that, QStackedLayout is respecting the height of the hidden widgets, which I don't want it to. Any ideas to overcome this ?
Here is the code:
main.cpp
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
main_widget w;
w.setFixedSize(400, 400);
w.show();
return app.exec();
}
main_widget.h
#include <QWidget>
#include <QLabel>
#include <QStackedLayout>
#include <QVBoxLayout>
#include <QPushButton>
class main_widget : public QWidget
{
Q_OBJECT
public:
main_widget();
};
main_widget.cpp
#include "main_widget.h"
main_widget::main_widget()
: QWidget(nullptr)
{
QVBoxLayout *header_app_layout = new QVBoxLayout();
QLabel *header_app_label = new QLabel();
header_app_label->setText(tr("Header"));
header_app_layout->addWidget(header_app_label);
QVBoxLayout* header_loader_layout = new QVBoxLayout();
QLabel* header_loader_label = new QLabel();
header_loader_label->setText(tr("Header Loader"));
header_loader_layout->addWidget(header_loader_label);
QWidget *m_content1_widget = new QWidget();
QVBoxLayout* content1_layout = new QVBoxLayout(m_content1_widget);
QPushButton* content1_button1 = new QPushButton(tr("content1_button1"));
content1_layout->addWidget(content1_button1);
QPushButton* content1_button2 = new QPushButton(tr("content1_button2"));
content1_layout->addWidget(content1_button2);
QPushButton* content1_button3 = new QPushButton(tr("content1_button3"));
content1_layout->addWidget(content1_button3);
content1_button2->hide(); //Hidden for now. But it's height is being included
content1_button3->hide();
QWidget* m_content2_widget = new QWidget();
QVBoxLayout* content2_layout = new QVBoxLayout(m_content2_widget);
QPushButton* content2_button1 = new QPushButton(tr("content2_button1"));
content2_layout->addWidget(content2_button1);
QPushButton* content2_button2 = new QPushButton(tr("content2_button2"));
content2_layout->addWidget(content2_button2);
QPushButton* content2_button3 = new QPushButton(tr("content2_button3"));
content2_layout->addWidget(content2_button3);
content2_button2->hide();
content2_button3->hide();
QStackedLayout* content_layout = new QStackedLayout(); //Doesn't work
//QVBoxLayout *content_layout = new QVBoxLayout(); //Works, but I need it to be of type `QStackedLayout` to show the 2 child widgets conditionally
content_layout->addWidget(m_content1_widget);
content_layout->addWidget(m_content2_widget);
content_layout->setStackingMode(QStackedLayout::StackingMode::StackOne);
content_layout->setCurrentIndex(0);
QVBoxLayout* main_layout = new QVBoxLayout;
main_layout->addLayout(header_app_layout); //Adding a QVBoxLayout
main_layout->addLayout(header_loader_layout); //Adding another QVBoxLayout
main_layout->addSpacing(32);
main_layout->addLayout(content_layout); //Adding the QStackedLayout
this->setLayout(main_layout);
}
I was able to resolve the issue by calling adjustSize on m_content2_widget, which removed the space occupied by the hidden controls inside m_content2_widget.
m_content2_widget->adjustSize();

QScrollArea Child Widget size set according to to Parents size change

I want to fit (child) widget into the parent widget size. So if the parent window is too small to display all the elements of the child widget the QScrollArea should appear otherwise it should be invisible.
I have attached the pictures for a better understanding.
The black box is where I want my scroll to appear. Since when we reduce the size of the window, sometimes you can't see the scroll bar (as displayed in the below picture) it doesn't look elegant enough for big projects.
Please help me with the same, thanks in advance.
Here's the sample code that I used for example:
int main(int argc, char *argv[]){
QApplication a(argc, argv);
QScrollPractice w;
QDialog * dlg = new QDialog();
//dlg->setGeometry(100, 100, 260, 260);
dlg->setMinimumSize(150, 200);
QScrollArea *scrollArea = new QScrollArea(dlg);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setWidgetResizable(true);
//scrollArea->setGeometry(10, 10, 200, 200);
//scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
//QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
scrollArea->setSizePolicy(sizePolicy);
QWidget *widget = new QWidget(scrollArea);
scrollArea->setWidget(widget);
QVBoxLayout *layout = new QVBoxLayout(widget);
widget->setLayout(layout);
for (int i = 0; i < 10; i++)
{
QPushButton *button = new QPushButton(QString("%1").arg(i));
layout->addWidget(button);
}
dlg->show();
return a.exec();
}
Your Dialog is missing a layout as well. Thats the reason the scrollArea Widget isnt spread out across the dialog.
#include <QApplication>
#include <QDialog>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QPushButton>
int main(int argc, char* argv[]){
QApplication a(argc, argv);
QDialog* dlg = new QDialog();
dlg->setMinimumSize(150, 200);
QScrollArea* scrollArea = new QScrollArea(dlg);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scrollArea->setWidgetResizable(true);
QWidget* widget = new QWidget(scrollArea);
scrollArea->setWidget(widget);
QVBoxLayout* dlgLayout = new QVBoxLayout();
dlg->setLayout( dlgLayout );
dlgLayout->addWidget( scrollArea );
QVBoxLayout* layout = new QVBoxLayout(widget);
widget->setLayout(layout);
for (int i = 0; i < 10; i++)
{
QPushButton* button = new QPushButton(QString("%1").arg(i));
layout->addWidget(button);
}
dlg->show();
return a.exec();
}
I modified your code to make it run and compileable, also I added antoher QVBoxLayout and added it to the dialog. Then the scrollArea gets added to that Layout. Hope this helps.

remove extra widget/window in Qt

probably a simple question: I just created a new project in Qt creator and I set it to use QWidget when I created it, now how do I get rid of the window that it automatically creates when I run it? I also created my own QWidget window which I want to be the only window.
#include "widget.h"
#include <QtGui>
Widget::Widget()
{
QWidget* window = new QWidget;
addBtn = new QPushButton("Add Module");
text = new QTextEdit();
text->setReadOnly(true);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(addBtn,5);
layout->addWidget(text);
window->setLayout(layout);
window->show();
}
Widget::~Widget()
{
}
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
change it like this
Widget::Widget()
{
addBtn = new QPushButton("Add Module");
text = new QTextEdit();
text->setReadOnly(true);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(addBtn,5);
layout->addWidget(text);
this->setLayout(layout);
}
and try to have some time on look and try some of Qt Example (you can find it in Qt Creator)
and there is about 100 short video to learn quickly basic stuff on Qt
Qt is fun, enjoy it.

QBoxLayout screws up QFormLayout?

Following simplified code snippet:
#include <QtGui>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget *window = new QWidget();
QFormLayout *form = new QFormLayout();
// first row
form->addRow("First row:", new QLineEdit());
// second row
QWidget *hbox_widget = new QWidget();
QBoxLayout *hbox = new QHBoxLayout();
hbox->addWidget(new QLineEdit());
hbox_widget->setLayout(hbox);
form->addRow("Second row:", hbox_widget);
window->setLayout(form);
window->show();
return app.exec();
}
Here, I create a QFormLayout with two rows: the first is a classic example of label+input widget, the second one is almost the same, with the exception that the input widget is "boxed" in a QHBoxLayout(+containing widget).
For some reason, this seems to screw up the "vertical centering" of the input widget (in the 2nd row). How can I add a widget which contains others in a hboxlayout to a formlayout, and still have them all centered vertically?
Set the contents margins of the QHBoxLayout to 0:
QBoxLayout *hbox = new QHBoxLayout();
hbox->setContentsMargins(0, 0, 0, 0);

how to create window that opened when close main window?

Iam a absolute Beginner in QT..
i am trying to create window that has only text and one push button when you press it, you will get another window that has menu for program ..
but Unfortunately, i didn't know how can i create new window and connect it with main window!
so, i need to helping you
Here is a sample of main.cpp that do exactly that (you will have to modify the new window though).
#include <QtGui>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QWidget *firstWindow = new QWidget();
QLabel *text = new QLabel("Here is some text one the first window.");
QPushButton *button = new QPushButton("Button on the first window that display the other window");
QBoxLayout *layout = new QVBoxLayout();
layout->addWidget(text);
layout->addWidget(button);
firstWindow->setLayout(layout);
QWidget *secondWindow = new QWidget();
// add some things on the second window
// on button click, close the first window and show the second one
connect(button, SIGNAL(clicked(bool)), secondWindow, SLOT(show()));
connect(button, SIGNAL(clicked(bool)), firstWindow, SLOT(close()));
// display the first window at the start of the application.
firstWindow->show();
return app.exec();
}

Resources