使用派生的Qt窗口小部件类时的父问题(?)

时间:2016-06-30 16:46:50

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

以下是我可以用来呈现isuue的最小例子。

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QVBoxLayout *vLayout = new QVBoxLayout(this);

    QGroupBox *gb = new QGroupBox;
//    MyGroupBox *gb = new MyGroupBox;
    vLayout->addWidget(gb);

    QPushButton *btB = new QPushButton;
    vLayout->addWidget(btB);
}

enter image description here

上面的代码生成上面的图片,它只是一个组框和一个垂直布局的按钮。

如果我将QGropBox替换为MyGroupBox,那么它就不会显示在那里了。下面的代码生成下面的图片。

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QVBoxLayout *vLayout = new QVBoxLayout(this);

//    QGroupBox *gb = new QGroupBox;
    MyGroupBox *gb = new MyGroupBox;
    vLayout->addWidget(gb);

    QPushButton *btB = new QPushButton;
    vLayout->addWidget(btB);
}

enter image description here

mygroupbox.h(构造函数体在.cpp文件中为空):

#include <QWidget>

class MyGroupBox : public QWidget
{
    Q_OBJECT
public:
    explicit MyGroupBox(QWidget *parent = 0);

signals:

public slots:

};

为什么群组框没有显示?如何让它出现?

2 个答案:

答案 0 :(得分:3)

这就是它没有出现的原因:

class MyGroupBox : public QWidget

您的&#34;组框&#34;基本上只是QWidget。继承自QGroupBox

答案 1 :(得分:3)

顺便说一句,最小的例子可能如下所示。不能删除单个声明/语句/表达式。按钮有助于可视化问题,因此应将其保留。使用故障触发变量突出显示触发故障的条件:代码自我文档,您几乎不需要叙述来解释它。问题可能与下面的测试用例和一句话一样简洁&#34;当fail为真时,为什么组框的边界不可见?&#34;。最有可能的是,如果你完全遵循最小化,你就会意识到自己的问题是什么 - 它变得相当明显。当MyGroupBox在另一个文件中声明时,情况并非如此!

在发现问题时将所有内容放入单个main.cpp文件的技术严重:所有代码在物理上彼此相邻,从而更容易发现错误!当你最小化时,通常首先要做的就是单独的文件:将它们全部塞进一个文件中,然后无情地删除在复制问题时不需要的所有内容。

#include <QtWidgets>

struct MyGroupBox : public QWidget {};

int main(int argc, char ** argv) {
   bool fail = true;
   QApplication app{argc, argv};
   QWidget widget;
   QVBoxLayout layout{&widget};
   QGroupBox groupBox;
   MyGroupBox myGroupBox;
   QPushButton button;
   layout.addWidget(fail ? static_cast<QWidget*>(&myGroupBox) : &groupBox);
   layout.addWidget(&button);
   widget.show();
   return app.exec();
}

这种简洁的风格不仅适用于琐碎的测试用例。在您的真实代码中,Widget的标头和实现可能如下所示:

// Widget.h
#include <QtWidgets>
#include "MyGroupBox.h"

class Widget : public QWidget {
  Q_OBJECT
  QVBoxLayout layout{this};
  MyGroupBox groupBox;
  QPushButton button{tr("Click Me!")};
public:
  explicit Widget(QWidget * parent = nullptr);
};

// Widget.cpp
#include "Widget.h"

Widget::Widget(QWidget * parent) :
  QWidget{parent} {
  layout.addWidget(&groupBox);
  layout.addWidget(&button);
}

如果您坚持要保护界面不受实施细节的影响,请不要使用指向小部件等的指针,请使用PIMPL

// Widget.h
#include <QWidget>

class WidgetPrivate;
class Widget : public QWidget {
   Q_OBJECT
   Q_DECLARE_PRIVATE(Widget)
   QScopedPointer<WidgetPrivate> const d_ptr;
public:
   explicit Widget(QWidget * parent = nullptr);
};

// Widget.cpp
#include "Widget.h" // should always come first!
#include "MyGroupBox.h"

class WidgetPrivate {
   Q_DECLARE_PUBLIC(Widget)
   Widget * const q_ptr;
public:
   QVBoxLayout layout{q_func()};
   QGroupBox groupBox;
   MyGroupBox myGroupBox;
   QPushButton button{"Click Me!"};
   WidgetPrivate(Widget * q) : q_ptr(q) {
      layout.addWidget(&groupBox);
      layout.addWidget(&button);
   }
};

Widget::Widget(QWidget * parent) :
   QWidget{parent}, d_ptr{new WidgetPrivate{this}}
{}