Пишу программу на Qt, не работает QGridLayout

116
10 ноября 2019, 13:20

Пытаюсь разместить в диалоговом окне виджет с вкладками и виджет с кнопкой. Использую для этого QGridLayout:

ProcInfo::ProcInfo(QWidget *parent) :
QDialog(parent),
ui(new Ui::ProcInfo)
{
    ui->setupUi(this);
    setWindowTitle("Process info");
    tabWidget = new QTabWidget();
    generalTab = new QTableWidget();
    securityTab = new QTableWidget();
    tabWidget->addTab(generalTab, "General");
    tabWidget->addTab(securityTab, "Security");
    okButtonWidget = new QWidget();
    okButton = new QPushButton(okButtonWidget);
    okButton->setText(tr("OK"));
    mainWidget = new QWidget(this);
    mainLayout = new QGridLayout();
    mainLayout->addWidget(okButtonWidget, 0, 0);
    mainLayout->addWidget(tabWidget, 1, 0);
    mainWidget->setLayout(mainLayout);
    mainWidget->show();
    ...
    generalTab->setVisible(true);
    okButton->setVisible(true);
}

Заголовочный файл:

    class ProcInfo : public QDialog
{
    Q_OBJECT
public:
    explicit ProcInfo(QWidget *parent = nullptr);
    ~ProcInfo();
private slots:
    void on_okButton_clicked();
private:
    Ui::ProcInfo *ui;
    QTabWidget *tabWidget;
    QTableWidget *generalTab;
    QTableWidget *securityTab;
    QStringList generalHeader;
    QGridLayout *mainLayout;
    QPushButton *okButton;
    QWidget *okButtonWidget;
    QWidget *mainWidget;
};

Проблема в том, что какие бы координаты в addWidget я не указывал, диалоговое окно выглядит одинаково и расположение виджетов в нём не соответствует действительности. Не понимаю, что я делаю не так.

Answer 1

Несколько моментов, которые, по моему мнению, следует исправить:

1. При создании виджетов вы не указываете родителей этих виджетов.

tabWidget = new QTabWidget();
generalTab = new QTableWidget();
securityTab = new QTableWidget();
...

Из-за отсутствия родительских элементов могут возникать различные ошибки (например, утечки памяти или некорректное отображение на форме). Поэтому родительские элементы лучше все таки задавать, причем задавать так, чтобы соблюдать семантику их вложенности.

2. При создании кнопки Вы создаёте отдельный виджет для неё.

okButtonWidget = new QWidget();
okButton = new QPushButton(okButtonWidget);

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

3. Вы создаете отдельный "родительский" виджет mainWidget.

mainWidget = new QWidget(this);

Этот виджет избыточен, т.к. при создании проекта по умолчанию создается ui->centralWidget, исключающий меню, тулбар и статусбар. Для распределения элементов в layout лучше использовать его (или иметь еще одно место потенциальной путанницы).

В итоге получаем более упрощенный код:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    tabWidget(new QTabWidget(this)),
    generalTab(new QTableWidget(tabWidget)),
    securityTab(new QTableWidget(tabWidget)),
    okButton(new QPushButton(this))
{
    ui->setupUi(this);
    tabWidget->addTab(generalTab, "General");
    tabWidget->addTab(securityTab, "Security");
    okButton->setText(tr("OK"));
    // указатель на layout можно не хранить, поэтому создаем его локально
    QGridLayout *mainLayout = new QGridLayout();
    mainLayout->addWidget(tabWidget, 0, 0);
    mainLayout->addWidget(okButton, 1, 0);
    ui->centralWidget->setLayout(mainLayout);
}

Получаем такое окно:

P.S. В конструкторе класса я выделил создание объектов в список инициализации, т.к. считаю, что такой подход более удобен для чтения кода (создание объектов в одном, логичном для этого месте).

Answer 2

Зачем вы создаете mainWidget?

У вас текущий виджет ProcInfo уже имеет возможность размещать в себе виджеты и поддерживает компоновщики (layouts)

Уберите mainWindow и просто используйте:

setLayout(mainLayout);

Тогда компоновщик с таблицей и кнопкой разместятся на диалоге.

PS. в текущем виде проще использовать QVBoxLayout

READ ALSO
Задача на рекурсию про лесенку из кубиков [закрыт]

Задача на рекурсию про лесенку из кубиков [закрыт]

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

128
Не считывает файл до конца? [закрыт]

Не считывает файл до конца? [закрыт]

Необходимая инфа(файл) для работы проги messagetxt

103
Создание очереди из структур

Создание очереди из структур

Есть у меня база данных, я считал с этой базы данные, занес их в Persone(500 раз) и теперь мне надо поместить их в очередь, но что-то у меня не получается...

123
Чтение и запись членов union

Чтение и запись членов union

Никак не могу найти однозначный ответ на следующий вопрос

109