0

For convenience, I created a function that helps me add new objects, but the MainWindow function doesn't accept them. So how can the MainWindow function receive the newly created object?

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFrame>
#include <QVBoxLayout>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    void CreateNewObj(int row, int column, int rowSpan, int columnSpan);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    for (int i = 0; i < 10; i++)
    {
        MainWindow::CreateNewObj(i,0,1,1);
    }
    // HERE

    // this->ui->frame_1...   IN HERE   MainWindow function does not accept new object created by CreateNewObj function

    // HERE
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::CreateNewObj(int row, int column, int rowSpan, int columnSpan)
{
    QFrame *frame = new QFrame(this->ui->scrollAreaWidgetContents);
    QVBoxLayout *verticalLayout;
    verticalLayout = new QVBoxLayout(frame);
    verticalLayout->setObjectName(QString::fromUtf8("verticalLayout_") + QString::number(row));

    frame->setObjectName(QString::fromUtf8("frame_") + QString::number(row));
    frame->setMinimumSize(QSize(100, 100));
    frame->setMaximumSize(QSize(16777215, 50));
    frame->setStyleSheet(QString::fromUtf8("background-color: rgb(255, 170, 127);"));
    frame->setFrameShape(QFrame::StyledPanel);
    frame->setFrameShadow(QFrame::Raised);

    this->ui->gridLayout->addWidget(frame, row, column, rowSpan, columnSpan);
}

mainwindow.ui:

mainwindow.ui

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Marei
  • 21
  • 2
  • Do the frames appear in your application? The code doesn't look that bad (but I might've overlooked something). I don't get the message of your comment `// this->ui->frame_1... IN HERE MainWindow function does not accept new object created by CreateNewObj function`. What (literal code) did you intend to do between `// HERE` and `// HERE`? – Scheff's Cat Apr 25 '22 at 10:03
  • @Scheff'sCat Frames appear in the application, but they cannot be called in MainWindow. Image https://i.stack.imgur.com/rgB6r.png I'm very sorry. I don't know how to send pictures instead of links. – Marei Apr 25 '22 at 10:12
  • Concerning the pictures - not your fault. You have to earn a bit reputation until you are allowed to embed pictures. (This is intended to prevent ad-spamming.) – Scheff's Cat Apr 25 '22 at 10:26
  • If you programmatically add widgets to your hierarchy, it doesn't mean there appear magically new variables in your UI data. That's not possible. UI data is (internally) generated source code but your frames are added at run-time. Nevertheless, there are ways to address them afterwards. – Scheff's Cat Apr 25 '22 at 10:27
  • Either add your own member variables to your C++ class to store the pointers to the created frames somewhere or use the available Qt functions to retrieve the pointers to frames later. Concerning the latter: [QObject::children()](https://doc.qt.io/qt-5/qobject.html#children), [How do you get a widget's children in Qt?](https://stackoverflow.com/a/4311734/7478597) – Scheff's Cat Apr 25 '22 at 10:30
  • @Scheff'sCat I have tried many ways, but with no success. My knowledge is still poor. Can you explain to me better the word "parentWidget" in "QPushButton *button = parentWidget->findChild("button1");" About the link you sent: "How do you get a widget's children in Qt?" I tried and it shows an error. image: https://i.stack.imgur.com/OKdXj.png – Marei Apr 25 '22 at 11:35
  • The following should work (between `// HERE` and `// HERE`: `for (QFrame* frame : ui->scrollAreaWidgetContents->findChildren()) { /* do something with frame */ }`. Thereby, the object name is ignored but the type of the widget must match `QFrame` which should be sufficient in your case. Have a look at [QObject::findChildren()](https://doc.qt.io/qt-5/qobject.html#findChildren) for more options. – Scheff's Cat Apr 25 '22 at 12:19
  • @Scheff'sCat It works perfectly! Thank you for everything! How do I give you a good rating? External problems I'm not sure it will be optimal when the program has to run many searches. – Marei Apr 25 '22 at 13:28
  • The performance of this is a minor problem as long as there aren't children in your `QFrame`s. An alternative with better performance would be what I suggested in the beginning - to have a resp. member variable in your `MainWindow` class. However, in this case you have double book keeping (the member variable vs. the children of your `scrollAreaWidgetContents` instance) which has to be carefully handled as well. – Scheff's Cat Apr 25 '22 at 13:55
  • As long as performance impact isn't an issue I would ignore it. FYI: [Make It Work Make It Right Make It Fast](https://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast) ;-) – Scheff's Cat Apr 25 '22 at 13:58
  • @Scheff'sCat People like you are rare. Can I ask a few more questions? You can decline if you're busy or something. – Marei Apr 25 '22 at 14:14
  • There are definitely more people like me in the SO community. Keep on asking questions. Your first wasn't that bad - considering that you even didn't take the [tour] nor having read [ask]. – Scheff's Cat Apr 25 '22 at 14:17
  • @Scheff'sCat Can you give me some documentation on applying QPropertyAnimation to QPainter to animate it? There are numerous tutorials available, but they are all in Python. – Marei Apr 25 '22 at 14:26

1 Answers1

0

It should be something like:

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

QVBoxLayout *verticalLayout = new QVBoxLayout(ui->scrollAreaWidgetContents());
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));

for (int i = 0; i < 10; i++)
{
  QFrame *frame = new QFrame(ui->scrollAreaWidgetContents());
  frame->setObjectName(QString::fromUtf8("frame_") + QString::number(i));
  frame->setMinimumSize(QSize(100, 100));
  frame->setMaximumSize(QSize(16777215, 50));
  frame->setStyleSheet(QString::fromUtf8("background-color: rgb(255, 170, 127);"));
  frame->setFrameShape(QFrame::StyledPanel);
  frame->setFrameShadow(QFrame::Raised);

    verticalLayout->addWidget(frame, i, 0, 1, 1);
  }
}