您可以隐藏 QGroupBox 框架但保留其内容可见吗?

Posted

技术标签:

【中文标题】您可以隐藏 QGroupBox 框架但保留其内容可见吗?【英文标题】:Can you hide a QGroupBox frame but preserve it's content visible? 【发布时间】: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 不能...... 【参考方案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 评论的样式表更难设置 实际上,该解决方案的实现与MasterAler 的prior 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/***n/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 appargc, 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”) 确实如此。但它看起来是使用标签最简单的方法

以上是关于您可以隐藏 QGroupBox 框架但保留其内容可见吗?的主要内容,如果未能解决你的问题,请参考以下文章

Photon我如何从客户端隐藏开始游戏按钮但为主机保留它

7.1 QGroupBox组合框

有没有办法保留状态栏(iOS 7)但隐藏信号?

隐藏文件夹内容但保持文件可访问

更改 QGroupBox 的内容背景

QML:在 StackView 中,水平可滑动的视觉效果会持续存在