【问题标题】:Can you hide a QGroupBox frame but preserve it's content visible?您可以隐藏 QGroupBox 框架但保留其内容可见吗?
【发布时间】:2016-04-13 15:27:36
【问题描述】:

我有一个QGroupBox。根据上下文,它的标题可能是多余的(显示在 GUI 的另一个位置),所以我需要让 QGroupBox 不在这里......但我必须保持它的内容可见(所以我不不想打电话给QGroupBox::hide())!

我需要在运行时动态执行此操作,并且希望避免创建/销毁 QGroupBox + 重新设置其内容....必须有更简单的方法来执行此操作。

到目前为止我尝试了什么:

QGroupBox可见:

  • QGroupBox::setTitle("") 删除文本。
  • QGroupBox::setFlat(true) 使框架成为单行。

我最终得到了这个:

还不错……但还有一行……有没有办法完全隐藏 QGroupBox 框架但保持其内容可见?

【问题讨论】:

  • 我遇到了类似的问题,我最终要做的是将内容放在 QTableWidget 中。使用 QTablewidget,我可以隐藏所有边框。
  • @MasterAler: QComboBox::setStyleSheet( "border: none" ); 工作得非常完美。如果您将此添加为答案,我很乐意接受。
  • @KubaOber:只是期待找到一些更琐碎的东西......就像 MasterAler 提出的那样。
  • @user3183610: QGroupBox 可以被破解,QTableWidget 不能......

标签: qt groupbox


【解决方案1】:

我的选择:

QGroupBox theBox;
theBox.setFlat(true);
//This removes the border from a QGroupBox named "theBox".
theBox.setStyleSheet("QGroupBox#theBox {border:0;}");
//This removes the border from the group box and all of its children
theBox.setStyleSheet("border:0;");

【讨论】:

  • 不错的选择。
【解决方案2】:

您可以从QGroupBox 派生您自己的Group Box,并重新实现paintEvent() 方法。应该很简单。原QGroupBox::paintEvent()是这样的:

void QGroupBox::paintEvent(QPaintEvent *)
{
    QStylePainter paint(this);
    QStyleOptionGroupBox option;
    initStyleOption(&option);
    paint.drawComplexControl(QStyle::CC_GroupBox, option);
}

您需要做的只是在绘制小部件之前修改样式选项:

void CMyGroupBox::paintEvent(QPaintEvent *)
{
    QStylePainter paint(this);
    QStyleOptionGroupBox option;
    initStyleOption(&option);

    // This should disable frame painting.
    option.features = QStyleOptionFrame::None;

    paint.drawComplexControl(QStyle::CC_GroupBox, option);
}

【讨论】:

  • 这是一个选项,但比应用 MasterAler 评论的样式表更难设置
  • 实际上,该解决方案的实现与MasterAlerprior solution 一样简单,但具有隐藏所有子窗口小部件的框架的显着优势。虽然简单,但设置样式表border:0 无条件地将该样式应用于所有子小部件。那很糟。虽然稍微不那么简单,但这个解决方案没有这样的严重缺陷。这很好。
  • 我将如何为 PyQt 版本执行此操作?我不确定如何更改方法,因为模块没有逻辑...def paintEvent(self, a0: QtGui.QPaintEvent) -> None: ...
【解决方案3】:

您可以使用QFrame + QGridLayout(或一些更复杂的布局组合)+ QSS 而不是QGroupBox

仅考虑 QGroupBox,通过 QSS 的简单解决方案可能是:

static const char kSavedTitle[] = "_savedTitle";
void hideBoxFrame(QGroupBox * box) {
  box->setProperty(kSavedTitle, box->title());
  box->setTitle(QString());
  box->setStyleSheet("border:none");
}
void showBoxFrame(QGroupBox * box) {
  box->setTitle(box->property(kSavedTitle).toString());
  box->setStyleSheet(QString());
}

【讨论】:

    【解决方案4】:

    这是一个示例,它通过交换小部件和重新设置子级来实现。它适用于任何具有直接子级的小部件,而不仅仅是QGroupBox。它需要对诸如QScrollAreaQMainWindow 之类的小部件进行特殊情况处理,这些小部件将子小部件包装在一个特殊的子小部件中。

    有关以编程方式推广小部件的相关讨论,请参阅 this question

    // https://github.com/KubaO/stackoverflown/tree/master/questions/group-reparent-36603051
    #include <QtWidgets>
    
    /// Replaces the visible widget with a hidden widget, preserving the layout of the
    /// children, and making the new widget visible.
    void swapWidgets(QWidget * a, QWidget * b)
    {
       auto src = a->isVisible() ? a : b;
       auto dst = a->isVisible() ? b : a;
       Q_ASSERT(dst->isHidden());
       /// Move the children to the destination
       dst->setLayout(src->layout());
       /// Replace source with destination in the parent
       auto layout = src->parentWidget()->layout();
       delete layout->replaceWidget(src, dst);
       /// Unparent the source, otherwise it won't be reinsertable into the parent.
       src->setParent(nullptr);
       /// Only the destination should be seen.
       src->hide();
       dst->show();
    }
    
    int main(int argc, char ** argv) {
       QApplication app{argc, argv};
       QWidget w;
       QGridLayout wLayout{&w};
       QPushButton swapBtn{"Swap"};
       wLayout.addWidget(&swapBtn);
    
       QWidget noBox;
       QGroupBox box{"Group"};
       wLayout.addWidget(&box);
       QGridLayout boxLayout{&box};
       for (int i = 0; i < 16; ++i)
          boxLayout.addWidget(new QLabel(QString("Tr%1").arg(i)), i/8, i%8);
    
       swapBtn.connect(&swapBtn, &QPushButton::clicked, [&] { swapWidgets(&box, &noBox); });
       w.show();
       return app.exec();
    }
    

    【讨论】:

      【解决方案5】:

      是的,您可以尝试另一种方法。

      你可以变形为一个 QFrame,它会保持行为但使容器无边界

      您只需在 QDesigner 中的 Group Box 上单击鼠标右键,然后选择“Morph Into”选项即可从中选择

      【讨论】:

      • 但是 QFrame 不允许您在栏上显示标题(我的屏幕截图中的“Emulator 0”)
      • 确实如此。但它看起来是使用标签最简单的方法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-01
      • 2017-09-05
      相关资源
      最近更新 更多