2016-06-30 2 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

Код выше создает изображение выше, это просто коробка группы и кнопка в вертикальной компоновке.

Если я заменил 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: 

}; 

Почему коробка группа не показывает там? Как это сделать?

+1

Вы добавляете пустой виджет, так что ничего не видно. Если вы хотите доказать, что есть что-то там или нет, попробуйте наследовать от 'QFrame' и называть' setFrameStyle (QFrame :: Panel) 'на нем, чтобы вы получили границу, где виджет –

+1

. Это помечено C++ 11, но это просто C++ 98 :(Qt + C++ 11 выглядит намного лучше и менее многословно! –

+0

@KubaOber, пожалуйста, оцените мою вежливость C++ 11 в http: // stackoverflow.ком/вопросы/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 «s может выглядеть следующим образом:

// 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 с использованием автоматического хранилища. ;-) Это становится идиоматичным, с тенденцией к указателям повсюду просто еще один пример огромного количества устаревшего кода примера или мой плохой поиск ... или вы все еще меньшинство в этом смысле? Конечно, проблема с устаревшим стилем, как вы уже прокомментировали, и Qt с современными функциями C++ выглядит намного более терпимым для меня. Мне просто интересно, следуют ли указатели аналогичной схеме. Семантика стека - главная причина, по которой мне очень нравится GTKmm (в интерфейсе, конечно, лежащий в основе C динамический). –

+0

Действительно ли я предпочитаю 'QVBoxLayout layout {this}' на .h, затем 'QVBoxLayout * vLayout = новый QVBoxLayout (this)' в .cpp? Не могли бы вы опубликовать ссылку на свой стиль? – KcFnMi

+0

Тенденция к указателям Везде просто еще один пример обширного тела устаревшего кода примера. Хуже того, не было никаких оснований указывать этот способ даже в Qt 4, даже используя компилятор C++ 98. Удержание контейнеров Qt и QObjects с помощью указателя является двойной косвенностью, поскольку 'QObject' или' QVector' является указателем на PIMPL ... В частности, 'QObject' является' QScopedPointer '. Оба источника Qt 4 и Qt 5 могут быть тривиально модифицированы, чтобы сделать QObject и все производные типы подвижными при компиляции с C++ 11. –

Смежные вопросы