2016-06-30 32 views
1

以下是我可以用来呈现isuue的最小示例。使用衍生Qt小部件类时的父问题(?)

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代替QGropBox,那么它不会再显示那里。下面的代码产生下面的图像。

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: 

}; 

为什么组框中没有显示呢?如何使其显示?

+1

您正在添加一个空的小部件,所以没有什么可显示的。如果你想证明有或没有,请尝试从'QFrame'继承,并调用'setFrameStyle(QFrame :: Panel)',这样你就可以得到一个边框,该部件是 –

+1

这是用C++ 11标记的,但它只是C++ 98 :(Qt + C++ 11看起来比这更好,更不详细! –

+0

@KubaOber请感谢我的C++ 11的礼貌,http:// stackoverflow。COM /问题/ 38130827/quiloader-插件 - 未示出 - 如果加载式衍生基QWidget的。 – KcFnMi

回答

3

这就是为什么它没有出现:

class MyGroupBox : public QWidget 

你“组框”基本上是一个QWidget。改为继承QGroupBox

3

另外,最小的例子可能如下所示。没有一个声明/声明/表达式可以被删除。该按钮有助于可视化问题,所以应该留下来。使用失败触发器变量会确切地说明触发失败的条件:代码自成文件,而且几乎不需要叙述来解释它。这个问题可以像下面的测试案例一样简洁,还有一句话:“fail为真时,为什么组框边框不可见?”。最有可能的是,如果你完全通过最小化,你会意识到自己的问题是什么 - 它变得相当明显。当在另一个文件中声明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}} 
{} 
+0

很高兴看到使用自动存储的Qt程序员。 ;-)这是否变得习惯用语,随处可见指向大量过时示例代码的另一个例子,或者我可怜的搜索......或者在这个意义上你仍然是少数派?正如你之前评论的那样,过时的风格确实存在一个问题,而具有现代C++特性的Qt对我来说看起来更容易理解。我只是想知道指针是否遵循类似的模式。堆栈语义是我非常喜欢GTKmm的一个主要原因(在它的接口中;当然,底层的C都是动态的)。 –

+0

真的应该更喜欢'。QVBoxLayout布局{this}',然后'QVBoxLayout * vLayout = new QVBoxLayout(this)'.cpp?你介意为你的风格发布一个参考吗? – KcFnMi

+0

指向无处不在的另一个例子是大量过时示例代码。更糟糕的是,甚至在使用C++ 98编译器的情况下,即使在Qt 4中也没有理由进行编码。由于'QObject'或'QVector'是指向PIMPL的指针,因此通过指针保存Qt的容器和QObjects是一种双重间接方式,特别是'QObject'是'QScopedPointer '。在使用C++ 11编译时,可以对Qt 4和Qt 5源进行简单修改以使“QObject”和所有派生类型都可移动。 –