您可以隐藏 QGroupBox 框架但保留其内容可见吗?
Can you hide a QGroupBox frame but preserve it's content visible?
我有一个QGroupBox
。根据上下文,它的标题可能是多余的(显示在 GUI 的另一个地方),所以我需要让 QGroupBox
好像不在这里....但我必须保持它的内容可见(所以我不想打电话QGroupBox::hide()
)!
我需要在运行时动态执行此操作,并希望避免 creating/destroying QGroupBox
+ 重新设置其内容....必须有更简单的方法来执行此操作。
到目前为止我尝试了什么:
QGroupBox
可见:
QGroupBox::setTitle("")
删除文本。
QGroupBox::setFlat(true)
使框架成为单行。
我最终得到这个:
还不错……但还有一行……有没有办法完全隐藏 QGroupBox
框架但保持其内容可见?
您可以从 QGroupBox
派生您自己的组框并重新实现 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);
}
您可以使用 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());
}
这是一个通过交换小部件和重新设置子项的父级来实现的示例。它适用于任何有直接子项的小部件,而不仅仅是 QGroupBox
。它需要对 QScrollArea
和 QMainWindow
等小部件进行特殊情况处理,这些小部件将子部件包装在一个特殊的子小部件中。
有关以编程方式推广小部件的相关讨论,请参阅 。
// https://github.com/KubaO/Whosebugn/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();
}
我的选择:
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;");
是的,您可以尝试一个替代方案。
您可以变形为 QFrame 以保持行为但使容器无边界
您只需右键单击 QDesigner 中的组框,然后 Select 将 'Morph Into' 选项从
更改为 select
我有一个QGroupBox
。根据上下文,它的标题可能是多余的(显示在 GUI 的另一个地方),所以我需要让 QGroupBox
好像不在这里....但我必须保持它的内容可见(所以我不想打电话QGroupBox::hide()
)!
我需要在运行时动态执行此操作,并希望避免 creating/destroying QGroupBox
+ 重新设置其内容....必须有更简单的方法来执行此操作。
到目前为止我尝试了什么:
QGroupBox
可见:
QGroupBox::setTitle("")
删除文本。QGroupBox::setFlat(true)
使框架成为单行。
我最终得到这个:
还不错……但还有一行……有没有办法完全隐藏 QGroupBox
框架但保持其内容可见?
您可以从 QGroupBox
派生您自己的组框并重新实现 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);
}
您可以使用 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());
}
这是一个通过交换小部件和重新设置子项的父级来实现的示例。它适用于任何有直接子项的小部件,而不仅仅是 QGroupBox
。它需要对 QScrollArea
和 QMainWindow
等小部件进行特殊情况处理,这些小部件将子部件包装在一个特殊的子小部件中。
有关以编程方式推广小部件的相关讨论,请参阅
// https://github.com/KubaO/Whosebugn/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();
}
我的选择:
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;");
是的,您可以尝试一个替代方案。
您可以变形为 QFrame 以保持行为但使容器无边界
您只需右键单击 QDesigner 中的组框,然后 Select 将 'Morph Into' 选项从
更改为 select