0
Widget::Widget(QWidget *parent) : QWidget(parent) {
    file.open(QFile::ReadOnly);
    QWidget *w = loader.load(&file);
//    MyWidget *w = new MyWidget(loader.load(&file));
    vLayout.addWidget(w);
    file.close();        
    vLayout.addWidget(&bt);
}

enter image description here

The code above produces the image above. But I would like to do something with the widget just loaded, that's why I derived MyWidget from QWidget. And there seems to be the problem.

If I replace QWidget by MyWidget then it doesn't show there anymore. The code below produces the image below.

Widget::Widget(QWidget *parent) : QWidget(parent) {
    file.open(QFile::ReadOnly);
//    QWidget *w = loader.load(&file);
    MyWidget *w = new MyWidget(loader.load(&file));
    vLayout.addWidget(w);
    file.close();        
    vLayout.addWidget(&bt);
}

enter image description here

Where MyWidget:

// mywidget.h
#include <QWidget>

class MyWidget : public QWidget {
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = nullptr);
};

// mywidget.cpp
#include "mywidget.h"    
#include <QDebug>

MyWidget::MyWidget(QWidget *parent) : QWidget(parent) {
    qDebug() << "do something here";
}

Question 1: Why the widget (group box) isn't showing there? How to make it appear?

Ok, question 1 completed thanks to @KubaOber. Now I would like to access the widgets inside untitled.ui, I tried:

MyWidget::MyWidget(QWidget *parent) : QWidget(parent) {
    foreach (QLabel *label, parent->findChildren<QLabel*>())
        if(label->objectName().contains("Value"))
            qDebug() << "label" << label;

}

But it returns nothing. Instead, passing a parent in loader.load(&file, vLayoutWidget)) makes the untitled.ui widgets available but also craps the contents of vLayoutWidget. I guess the question is what should be passed in as parent in the loader.load())?

KcFnMi
  • 5,516
  • 10
  • 62
  • 136
  • 1
    Ideally you'd create a self-contained test case in the style of [this one](http://stackoverflow.com/a/37797117/1329652). – Kuba hasn't forgotten Monica Jun 30 '16 at 20:34
  • Please post a new question instead of editing into an old one. – jonspaceharper Jul 01 '16 at 12:00
  • Which old one are you referring to? – KcFnMi Jul 01 '16 at 12:02
  • 1
    You can't iterate anything in `MyWidget`'s constructor, because it has no children yet at that point. And again, please absolutely post **complete** test cases. I'm can't but assume how the rest of your code looks. You're also making your life much harder by not having a simple piece of code to experiment on without messing up your main project. Learn how to quickly create test projects using Qt Creator. You can use [my simple qmake project template](https://github.com/KubaO/stackoverflown/tree/master/qtcreator-templates) to aid in that. – Kuba hasn't forgotten Monica Jul 01 '16 at 15:34

1 Answers1

2

The way you use the loader doesn't mean "load a MyWidget using QUiLoader:

MyWidget *w = new MyWidget(loader.load(&file));

What you're doing above is initializing a MyWidget that has whatever the loader has loaded as a parent. And then you're promptly reparenting w by adding it to a layout, effectively discarding whatever the loader has loaded.

You need to tell the loader what parent to add the widgets it has loaded to, of course noting that MyWidget doesn't need to be dynamically allocated:

auto w = new MyWidget;
loader.load(&file, w);

Here's how it might look when put together:

class Widget : public QWidget {
  Q_OBJECT
  QVBoxLayout m_layout{this};
  MyWidget m_myWidget;
  QVBoxLayout m_myLayout{&m_myWidget};
public:
  explicit Widget(QIODevice * source, QWidget * parent = nullptr) : 
    QWidget{parent}
  {
    auto loaded = QUiLoader{}.load(source, &m_myWidget);
    m_layout.addWidget(&m_myWidget);
    m_myLayout.addWidget(loaded);
  }
};

If your ui file's top-level widget is a MyWidget, then you'll need to let the loader know how to instantiate it - see this answer for details. And then you would write it as follows:

class Widget : public QWidget {
  Q_OBJECT
  QVBoxLayout m_layout{this};
  MyWidget * m_myWidget;
public:
  explicit Widget(QWidget * loaded, QWidget * parent = nullptr) : 
    QWidget{parent},
    m_myWidget{qobject_cast<MyWidget*>(loaded)}
  {
    m_layout.addWidget(m_myWidget);
  }
};

...
MyUiLoader loader{}
auto loaded = loader.load(...);
Widget widget{loaded};
...
Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313