Widget inside another widget Qt - c++

I am trying to achieve this layout:
where Widget1 is some widget (central widget of QMainWindow) and I want to add second widget Widget2 over it but it should be in left bottom corner of Widget1.
EDIT: my previous description wasn't very useful so I will try to describe it in more details.
I am inheriting QWidget class (class MyClass : public QWidget) and creating my own widget where I in void MyClass ::paintEvent(QPaintEvent *event) draw something on screen.
MyClass is then centralWidget of my QMainWindow.
Now on top of that I want to add smaller widget (Widget2 in image) where I would display some video (here I am not asking how to display video only how to add this Widget2 to my view).
Main thing here is that Widget2 is inside (floating in) Widget1.
EDIT2: Previous code I posted is rubbish.

Use QGridLayout to set the position of the widget:
QGridLayout* layout = new QGridLayout(this);
// 2x2 layout
QWidget* green = new QWidget(this);
green->setStyleSheet("background:green;");
QWidget* yellow = new QWidget(this);
yellow->setStyleSheet("background:yellow;");
QWidget* red = new QWidget(this);
red->setStyleSheet("background:red;");
QWidget* blue = new QWidget(this);
blue->setStyleSheet("background:blue;");
layout->addWidget(green, 0, 0); // Top-Left
layout->addWidget(yellow, 0, 1); // Top-Right
layout->addWidget(red, 1, 0); // Bottom-Left
layout->addWidget(blue, 1, 1); // Bottom-Right
ui->centralWidget->setLayout(layout);
Will give you something like that:
So, custom your own widget using QGridLayout and set the position of your widget inside it.
Set another widget as parent with black background:
QGridLayout* layout = new QGridLayout(this);
// 2x2 layout
QWidget* green = new QWidget(this);
green->setStyleSheet("background:green;");
QWidget* yellow = new QWidget(this);
yellow->setStyleSheet("background:yellow;");
QWidget* red = new QWidget(this);
red->setStyleSheet("background:red;");
QWidget* blue = new QWidget(this);
blue->setStyleSheet("background:blue;");
layout->addWidget(green, 0, 0); // Top-Left
layout->addWidget(yellow, 0, 1); // Top-Right
layout->addWidget(red, 1, 0); // Bottom-Left
layout->addWidget(blue, 1, 1); // Bottom-Right
QWidget* mainWidget = new QWidget(this);
mainWidget->setStyleSheet("background:black;");
mainWidget->setLayout(layout);
QHBoxLayout* centralLayout = new QHBoxLayout(this);
centralLayout->addWidget(mainWidget);
ui->centralWidget->setLayout(centralLayout);

Related

Is possible to have a widget that doesnt scroll in a QScrollArea?

Given this example:
Suppose A and B are QWidgets
Is it possible to keep everything starting from B static when the QScrollArea widget is scrolled?
The QScrollArea occupies the entire GUI, B is inside it to let the vertical ScrollBar closer to the right border of the GUI, or it would look like this:
What I can do in this case?
It is possible. You have to make use of the scrollbar being a widget of its own.
Here is the method:
Change your window in Qt Designer to be: spacer, QScrollArea (that will contain widget A), spacer, widget B, spacer; everything is in a QGridLayout (or QHBoxLayout but please read until the end).It is because widget B is outside the scroll area that it will not move during scrolling.
In your widget constructor, after ui->setupUi(); reparent and move the vertical scrollbar of your QScrollArea with these lines of code:
scrollArea->verticalScrollBar()->setParent(w);
layout->addWidget(sa->verticalScrollBar()); //Adds the scrollbar to the right of the layout.
Note about the margins:Obviously, you can easily push the scrollbar to the very right of your window by setting the layout right margin to 0.
If you also want it to cover the entire height of your window, while keeping some space between the other widgets and the window's border, that is where a QHBoxLayout will not suffice and you need a QGridLayout instead, set its top and bottom margin to 0 and add spacers (fixed size) to obtain the same visual result.
The C++ code for such a window would be:
QWidget* widget = new QWidget();
QGridLayout* layout = new QGridLayout(widget);
layout->setSpacing(0);
layout->setContentsMargins(9, 0, 0, 0);
widget->setLayout(layout);
QScrollArea* scrollArea = new QScrollArea(widget);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
QWidget* widgetB = new QLabel("Widget B", widget);
//Creates the spacer that will "simulate" the top and bottom margins
QSpacerItem* topSpacer = new QSpacerItem(0, 9, QSizePolicy::Minimum, QSizePolicy::Fixed),
* bottomSpacer = new QSpacerItem(0, 9, QSizePolicy::Minimum, QSizePolicy::Fixed);
layout->addItem(topSpacer, 0, 0);
layout->addWidget(scrollArea, 1, 0);
layout->addItem(bottomSpacer, 2, 0);
layout->addWidget(widgetB, 1, 1);
//Moves the scrollbar outside the scroll area
scrollArea->verticalScrollBar()->setParent(widget);
layout->addWidget(scrollArea->verticalScrollBar(), 0, 2, 3, 1);
QLabel* innerLabel = new QLabel("Some big label to force the scrolling");
scrollArea->setWidget(innerLabel);
innerLabel->setMinimumHeight(500);
widget->show();

Keep widget central forever after inserting an spaceritem

I want to customize a titlebar:
class TitlebarWidget : public QWidget {
Q_OBJECT
public:
TitlebarWidget(QWidget* parent = nullptr): QWidget(parent) {
setupUi();
}
virtual ~TitlebarWidget();
private:
void setupUi(){
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
// layout->addSpacerItem(new QSpacerItem(width(), height(),
QSizePolicy::Fixed, QSizePolicy::Fixed));
m_homeButton = new QPushButton(this);
m_homeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_homeButton->setMinimumWidth(50);
m_homeButton->setMaximumWidth(50);
m_homeButton->setText(tr("Home"));
layout->addWidget(m_homeButton);
QLabel* label = new QLabel(this);
label->setText("Titlebar");
layout->addWidget(label, 0, Qt::AlignCenter);
m_synButton = new QPushButton(this);
m_synButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_synButton->setMinimumWidth(100);
m_synButton->setMaximumWidth(100);
m_homeButton->setText(tr("Sync"));
}
QPushButton* m_synButton;
QPushButton* m_homeButton;
QPushButton* m_settingButton;
QRCodeWidget* m_synPhoneWidget;
};
The titlebar is as follows:
Home button is covered by the three circles at top-left corner, so I insert an spacer-item at the beginning:
layout->addSpacerItem(new QSpacerItem(width(), height(), QSizePolicy::Fixed, QSizePolicy::Fixed));
And the titlebar is like:
I found the text 'Titlebar' was obviously deviated from the center, but I want keep it central. who can help me with a workaround or a better alternative?
Use layout->addSpacing() instead and addStretch works for me.

I want to add a label in new widget using the Qt framework

This is my code :
void maquette::on_btn_edit_clicked()
{
QWidget* wdg = new QWidget;
wdg->resize(320, 340);
wdg->setWindowTitle("Modiffier");
QLabel label1("matricule", wdg);
label1.setGeometry(100, 100, 100, 100);
wdg->show();
}
the window shows up but the label didn't show
void maquette::on_btn_edit_clicked()
{
QWidget *wdg = new QWidget;
wdg->resize(320,340);
wdg->setWindowTitle("Modiffier");
QLabel *label1 = new QLabel("matricule",wdg);
label1->setGeometry(100, 100, 100, 100);
wdg->show();
}
You can either add the QLabel using parenting. as mentioned before.
QLabel *label1 = new QLabel("matricule",wdg);
or
QLabel *label1 = new QLabel("matricule");
label1->setParent(wdg);
This will make the widget float inside its parent.
You can also add the QLabel to a layout that has been assigned to the QWidget.
QVBoxLayout* layout = new QVBoxLayout();
wdg->setLayout(layout);
QLabel *label1 = new QLabel("matricule");
layout->addWidget(label1);
This will add the widget to the layout.
The layout will control how the child widgets are laid out.

Qt:Unable to directly add scrollbar to a widget with children

Im new to Qt programming and I want to add a scrollbar to a widget which is having child widgets within it.I have seen several questions/posts about this like:
1.How to add a scrollbar to parent QWidget
2.Insert a scrollbar in a qt widget using qtcreator
3.Adding scroll bar to a Qwidget
4.QScrollArea missing Scrollbar
But most of the answers set a layout to the widget for which we add the scrollbar.
My Problem:
The widget for which I need scrollbar has many child widgets within it.But I haven't added any layout to it.The geometry of the child widgets are modifiable and so I haven't added any layout to the parent widget.
Below is my code:
class Absolute : public QWidget {
public:
Absolute(QWidget *parent = 0);
};
Absolute::Absolute(QWidget *parent)
: QWidget(parent) {
QTextEdit *ledit = new QTextEdit(this);
ledit->setGeometry(5, 5, 500, 550);
QTextEdit *lledit = new QTextEdit(this);
lledit->setGeometry(510, 5, 250, 550);
/*QScrollArea* sa = new QScrollArea();
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
auto *widget = new QWidget(this);
sa->setWidget(widget);
auto *l = new QVBoxLayout(this);
l->setMargin(0);
l->addWidget(sa);*/
}
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Absolute window;
window.setWindowTitle("Absolute");
window.setGeometry(500,500,1500,1000);
window.show();
return app.exec();
}
However without the scrollbar code(commented portion),the UI has those textedits in the given position as set in the setGeometry.
All I need is to bring a scrollbar if the 2nd textedits width is more.
So I tried adding the scrollbar(the commented portion).However I can see only the scrollbar and not the textedits.
Any suggestion/inputs will be really helpful.Thanks in advance!!
Cause
The way you set the parents when you create the widgets and layouts is not correct.
Solution
Create the correct parent/child hierarchy and set the desired size of the QScrollArea's widget. There is no need to set a layout to this widget.
Example
Here is an example I have prepared for you in order to demonstrate how you could fix Absolute:
class Absolute : public QWidget {
public:
Absolute::Absolute(QWidget *parent = nullptr)
: QWidget(parent)
{
auto *sa = new QScrollArea(this);
auto *l = new QVBoxLayout(this);
auto *widget = new QWidget();
auto *ledit = new QTextEdit(widget);
auto *lledit = new QTextEdit(widget);
sa->setWidgetResizable(true);
sa->setWidget(widget);
sa->setAlignment(Qt::AlignLeft | Qt::AlignTop);
ledit->setGeometry(5, 5, 500, 550);
lledit->setGeometry(510, 5, 250, 550);
widget->setFixedSize(lledit->geometry().right(), lledit->geometry().bottom());
l->setMargin(0);
l->addWidget(sa);
}
};
Note: For demonstration purposes the size of widget is set to (lledit->geometry().right(), lledit->geometry().bottom()). You might consider adjusting it according to your specific needs.

Center children widget in parent widget(parent widget was added in layout)

I created a layout contain a parent widget. In that parent widget i created another widget.
My code is similarly to this:
QGridLayout *layout = new QGridLayout();
QWidget *parentWidget = new QWidget();
layout->addWidget(parentWidget );
QWidget *childWidget = new QWidget(parentWidget);
How can i center the child widget in parent widget ?
The problem is we cannot get the true size of parent widget because it's in a layout.
Move the child inside the parent's showeEvent. You can use a bool flag to do it only when the parent is shown for the first time.
void Parent::showEvent(QShowEvent *)
{
if(_first_show)
{
_first_show = false;
_child->move(this->rect().center() - _child->rect().center());
}
}
Proof that it works (red is the parent, and blue is the child):
You can do this by setting fixed size of child widget and placing it inside grid layout of parent widget.
QGridLayout *layout = new QGridLayout();
QWidget *parentWidget = new QWidget();
layout->addWidget(parentWidget );
QWidget *childWidget = new QWidget(parentWidget);
QGridLayout *parentLayout = new QGridLayout();
parentWidget->setLayout(parentLayout);
parentLayout->addWidget(childWidget);
childWidget->setFixedSize(/*some fixed size for child widget*/);