Зарезервировать место для изначально скрытого виджета в QVBoxLayout в QScrollArea - PullRequest
3 голосов
/ 27 апреля 2010

Я использую QVBoxLayout для организации вертикального стека виджетов. QVBoxLayout содержится в QScrollArea. Я хочу, чтобы некоторые виджеты были изначально скрыты и показывались только при установленном флажке. Вот пример кода, который я использую.

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
    QVBoxLayout *layout = new QVBoxLayout(this);

    QLabel *labelLogTypes = new QLabel(tr("Log Types"));

    m_checkBoxCsv = new QCheckBox(tr("&Delimited File (CSV)"));
    m_labelDelimiter = new QLabel(tr("Delimiter:"));
    m_lineEditDelimiter = new QLineEdit(",");
    checkBoxCsv_Toggled(m_checkBoxCsv->isChecked());
    connect(m_checkBoxCsv, SIGNAL(toggled(bool)), SLOT(checkBoxCsv_Toggled(bool)));

    QHBoxLayout *layoutDelimitedChar = new QHBoxLayout();
    layoutDelimitedChar->addWidget(m_labelDelimiter);
    layoutDelimitedChar->addWidget(m_lineEditDelimiter);


    m_checkBoxXml = new QCheckBox(tr("&XML File"));
    m_checkBoxText = new QCheckBox(tr("Plain &Text File"));


    // Now that everything is constructed, put it all together
    // in the main layout.
    layout->addWidget(labelLogTypes);

    layout->addWidget(m_checkBoxCsv);
    layout->addLayout(layoutDelimitedChar);

    layout->addWidget(m_checkBoxXml);
    layout->addWidget(m_checkBoxText);

    layout->addStretch();
}


MyWidget::checkBoxCsv_Toggled(bool checked)
{
    m_labelDelimiter->setVisible(checked);
    m_lineEditDelimiter->setVisible(checked);
}

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

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

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

Если я не помещу этот виджет в QScrollArea, то этот код работает именно так, как я хочу. Как обстоят дела с QScrollArea?

Ответы [ 3 ]

5 голосов
/ 27 апреля 2010

Есть несколько способов сделать это.

1) Добавьте свои изначально невидимые виджеты в другой виджет и поместите этот другой виджет в место, где вам нужно место. У внешнего виджета должен быть тот же размер, что и у внутреннего. Когда вы скрываете / отображаете внутренний виджет, он не влияет на размер внешнего виджета и, следовательно, не приводит к изменению размера макета.

2) Добавьте еще один виджет рядом с теми, которые вы хотите иметь невидимыми, того же размера. Всякий раз, когда вы показываете невидимый виджет, вы скрываете соответствующий видимый. Это эффективно поменяет два виджета одинакового размера, поэтому не должно вызывать смещения макета (хотя он будет пересчитан).

3) Поместите сложенный виджет туда, где вы хотите, чтобы невидимые были, и поместите невидимый виджет на одной странице, без виджетов на другой странице. Определите размер сложенного виджета соответствующим образом. Затем вы можете изменить страницу сложенного виджета в зависимости от того, хотите ли вы видеть внутренний виджет или нет. Обратите внимание, что это более обременительно только для одного отображаемого / скрытого виджета, но если у вас есть три или более взаимоисключающих параметра для отображения, это становится более осуществимым.

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

4 голосов
/ 28 апреля 2010

Я прошу прощения за то, что не совсем ясно в моем первоначальном вопросе Оказывается, проблема, похоже, связана с тем, что этот виджет содержится в QScrollArea Когда я позвонил scrollArea->setWidgetResizable(true), все стало отлично работать.

Спасибо за ваши предложения, Серж и Калеб.

1 голос
/ 27 апреля 2010

Вы можете попробовать добавить элемент spacer в макет layoutDelimitedChar с предопределенной максимальной высотой, что-то вроде этого:

QHBoxLayout *layoutDelimitedChar = new QHBoxLayout();

layoutDelimitedChar->addSpacerItem(new QSpacerItem(0, 33, QSizePolicy::Maximum, QSizePolicy::Maximum));

layoutDelimitedChar->addWidget(m_labelDelimiter);
layoutDelimitedChar->addWidget(m_lineEditDelimiter);

надеюсь, это поможет, с уважением

...