QPushButton не отображается во втором макете

#c #qt #qt5 #qpushbutton #qlayout

#c #qt #qt5 #qpushbutton #qlayout

Вопрос:

Кто-то уже задавал аналогичный вопрос, но этот человек работал с PyQt5 и дизайнером, поэтому я не смог найти ответ, поскольку я пишу «с нуля» и на C .

Я новичок в Qt и пытаюсь добавить две QPushButtons в окно в определенном макете. Сначала я попытался просто добавить их в окно к уже существующему QVBoxLayout, как показано ниже (это window, а textBrowser это QTextBrowser. Кнопки уже правильно инициализированы).

В этом случае кнопки работают отлично:

 auto content = new QWidget(this);
auto windowLayout = new QVBoxLayout(content);
windowLayout->addWidget(textBrowser);

windowLayout->addWidget(button1, 0, Qt::AlignLeft);
windowLayout->addWidget(button2, 0, Qt::AlignRight);

setCentralWidget(content);
  

Однако кнопки расположены вертикально. Я бы хотел, чтобы они располагались горизонтально рядом друг с другом, поэтому я попытался добавить кнопки в QHBoxLayout, который затем добавляется к существующему QVBoxLayout:

 auto content = new QWidget(this);
auto windowLayout = new QVBoxLayout(content);
windowLayout->addWidget(textBrowser);

auto buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(button1, 0, Qt::AlignRight);
buttonLayout->addWidget(button2, 0, Qt::AlignLeft);

windowLayout->addItem(buttonLayout);

setCentralWidget(content);
  

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

Почему это происходит? Моя теория заключалась в том, что макет может закрывать кнопки, поэтому я попытался сначала добавить QHBoxLayout в QVBoxLayout, а затем добавить кнопки, но ничего не изменилось.

Любая помощь или информация приветствуются.

Комментарии:

1. Вы пробовали использовать addLayout() вместо addItem() ?

2. @NgocMinhNguyen Большое вам спасибо!! Это решило мою проблему! Знаете ли вы, почему addItem() это имеет такой эффект?

3.Из документа: QLayout::addItem эта функция обычно не вызывается в коде приложения. Чтобы добавить виджет в макет, используйте функцию addWidget() ; чтобы добавить дочерний макет, используйте функцию addLayout(), предоставляемую соответствующим подклассом QLayout .

Ответ №1:

Взято из QLayout::addItem() документации:

Функция addItem() обычно не вызывается в коде приложения. Чтобы добавить виджет в макет, используйте addWidget() функцию; чтобы добавить дочерний макет, используйте addLayout() функцию, предоставляемую соответствующим QLayout подклассом.

Итак, замена addItem() на addLayout() решит вашу проблему.

Чтобы ответить, почему addItem() это имеет такой эффект, вы можете взглянуть на исходный код Qt:

 void QBoxLayout::addLayout(QLayout *layout, int stretch)
{
    insertLayout(-1, layout, stretch);
}

void QBoxLayout::insertLayout(int index, QLayout *layout, int stretch)
{
    Q_D(QBoxLayout);
    if (!d->checkLayout(layout))
        return;
    if (!adoptLayout(layout))
        return;
    if (index < 0)                                // append
        index = d->list.count();
    QBoxLayoutItem *it = new QBoxLayoutItem(layout, stretch);
    d->list.insert(index, it);
    invalidate();
}

void QBoxLayout::addItem(QLayoutItem *item)
{
    Q_D(QBoxLayout);
    QBoxLayoutItem *it = new QBoxLayoutItem(item);
    d->list.append(it);
    invalidate();
}
  

Сравнение с addItem() , addLayout() вызывает adoptLayout() , который переставляет виджеты в макете, который нужно добавить. Это позволяет родительскому макету управлять размером виджетов и определять события, которые должны быть направлены на виджеты (событие наведения курсора мыши, событие нажатия мыши и т. Д.)

Комментарии:

1. Спасибо за это подробное объяснение. Это мне очень помогло, поскольку Qt для меня новый.

2. Рад, что могу помочь!

3. Очень хороший ответ!