如果在派生的QWidget中加载,则不显示QUiLoader小部件

时间:2016-06-30 18:35:25

标签: c++ qt c++11 qt5 qwidget

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

上面的代码生成上面的图像。但我想对刚加载的小部件做一些事情,这就是我从MyWidget派生QWidget的原因。而且似乎存在问题。

如果我将QWidget替换为MyWidget,则它不再显示在那里。下面的代码生成下面的图片。

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

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";
}

问题1:为什么窗口小部件(组合框)没有显示在那里?如何让它出现?

好的,问题1完成归功于@KubaOber。现在我想访问untitled.ui中的小部件,我试过:

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

}

但它什么也没有回报。相反,在loader.load(&file, vLayoutWidget))中传递父级会使untitled.ui小部件可用,但也会使vLayoutWidget的内容变为现实。我想问题是应该在loader.load())

中作为父母传递什么

1 个答案:

答案 0 :(得分:2)

您使用装载机的方式并不意味着使用MyWidget加载QUiLoader

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

您上面所做的是初始化MyWidget,其中包含所加载的任何加载器。然后,您通过将w添加到布局中来立即重新显示MyWidget,从而有效地丢弃加载器已加载的任何内容。

您需要告诉加载器要添加其加载的小部件的父级,当然要注意auto w = new MyWidget; loader.load(&file, w); 不需要动态分配:

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);
  }
};

以下是放在一起时的外观:

MyWidget

如果您的ui文件的顶级窗口小部件是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}; ... ,那么您需要让加载程序知道如何实例化它 - 有关详细信息,请参阅this answer。然后你会写如下:

{{1}}