2016-06-30 35 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」和所有派生類型都可移動。 –