1

I am trying to draw various shapes like rectangle, ellipse, text etc uisng QGraphicsView and QGraphicsScene. For that I am trying to create an interface where there will be a vertical layout and besides that there will be few buttons. On clicking those buttons, I can show various QGraphicsItem's on screen. I want to create this interface programatically but not using ui.
I tried and ended up this way.
enter image description here

I wanted buttons on the right side and verticalLayout on the left side and both should filled up the whole screen.
Here is my current implementation :

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QGraphicsScene* scene = new QGraphicsScene(this);

    QGraphicsView* view = new QGraphicsView(this);
    view->setScene(scene);

    QWidget* mainWidget = new QWidget(this);
    QHBoxLayout *mainLayout = new QHBoxLayout();

    QVBoxLayout *buttonLayout = new QVBoxLayout();
    QVBoxLayout *vlayout2 = new QVBoxLayout();

    vlayout2->addWidget(view);

    QPushButton *btn1 = new QPushButton("Rectangle");
    btn1->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
    
    QPushButton *btn2 = new QPushButton("Ellipse");
    btn2->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
    
    QPushButton *btn3 = new QPushButton("Text");
    btn3->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );

    buttonLayout->addWidget(btn1);
    buttonLayout->addWidget(btn2);
    buttonLayout->addWidget(btn3);
    buttonLayout->addStretch();

    mainLayout->addLayout(buttonLayout);
    mainLayout->addLayout(vlayout2);

    mainWidget->setLayout(mainLayout);
}    

Can anyone guide me ?

tushar
  • 313
  • 4
  • 10
  • What happens when you use `vlayout2->addWidget(view, 1);`? – Scheff's Cat Feb 24 '22 at 07:05
  • While I'm not fully sure regarding vertical growing of view, I'm quite sure that you can force horizontal growing of view with `mainLayout->addLayout(vlayout2, 1);`. I just confirmed that [QBoxLayout::addLayout()](https://doc.qt.io/qt-5/qboxlayout.html#addLayout) provides a 2nd argument `stretch` as well, and it's default value is `0`. (I already knew that about `QBoxLayout::addWidget()`.) – Scheff's Cat Feb 24 '22 at 07:08
  • @Scheff'sCat Thank you for your response. I tried what you suggested but it is not working. Output is same as above. – tushar Feb 24 '22 at 07:12
  • 1
    the reason buttons are on the left side is because you are adding them as first into Horizontal layout, unless you change [direction](https://doc.qt.io/qt-5/qboxlayout.html#setDirection) the default HBox layout is left to right and VBox top to bottom. – Octopussy Feb 24 '22 at 07:24
  • 2
    The problem why the mainWidget is not stretched is because you are essentially creating widget inside widget directly without any layout! either scrap the mainWidget or create the wrapper grid layout that is in `this` and contains `mainWidget` This is the exact reason why we are using forms for qt Widgets. Programmers keep telling me they hate forms but always small issues like this slip and causes unforeseen problems. – Octopussy Feb 24 '22 at 07:28
  • @Octopussy : I did what you said and it worked. Now buttons are on the right side and verticallayout is on the left side. But it is not getting stretched. – tushar Feb 24 '22 at 07:28
  • Please, provide a [mcve]. How is `Widget` used in `main()`? – Scheff's Cat Feb 24 '22 at 07:47
  • @Octopussy : Your suggestion worked. Thanks ! – tushar Feb 25 '22 at 04:01

1 Answers1

2

Actually, it should work with the hints given in my comments.

I made an MCVE to convince myself:

#include <QtWidgets>

int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QWidget qMain;
  qMain.setWindowTitle("Test Box Layout");
  qMain.resize(640, 320);
  QHBoxLayout qHBox;
  QVBoxLayout qVBoxBtns;
  QPushButton qBtnRect("Rectangle");
  qVBoxBtns.addWidget(&qBtnRect);
  QPushButton qBtnCirc("Circle");
  qVBoxBtns.addWidget(&qBtnCirc);
  QPushButton qBtnText("Text");
  qVBoxBtns.addWidget(&qBtnText);
  qVBoxBtns.addStretch();
  qHBox.addLayout(&qVBoxBtns);
  QVBoxLayout qVBoxView;
  QGraphicsView qView;
  qVBoxView.addWidget(&qView, 1);
  qHBox.addLayout(&qVBoxView, 1);
  qMain.setLayout(&qHBox);
  qMain.show();
  // runtime loop
  return app.exec();
}

Output: Snapshot of testQBoxLayout (GIF Animation)

Thus, there must be something else in OP's code…

Unfortunately, OP didn't expose an MCVE. Thus, it's not clear how OP's Widget is instanced. Is it the widget which becomes the main window? Is there another widget where the Widget's instance becomes child of?

It's just guessing but the latter would explain what OP described.


To confirm my guess, I modified the above code a bit:

  // setup GUI
  QWidget qMain0; // main window widget
  QWidget qMain(&qMain0); // child widget of main window widget

  qMain.setLayout(&qHBox);
  qMain0.show();
  // runtime loop
  return app.exec();

Please, note that qMain is now a child of qMain0 but there is no layout which adjusts the size of qMain when qMain0 is resized.

Hence, the size of view stays the initial size while the window is resized.

Snapshot of (now broken) testQBoxLayout (GIF Animation)

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56