背景:
当前有一个需求场景,需要复用某个设置界面用于显示之前设置好的参数。正常情况下将所有的子控件setEnabled(false)即可,但是其中有一个QTextBrowser控件,此控件是QGroupBox的子控件,为了方便用户复制和使用滚动条查看内容,需要将其设置为enable。经过测试发现,在QGroupBox的enable属性设置为false之后,其子控件无法在实现setEnabled(true)操作。
废话不多说,直接看代码:
#include <QThread>
#include <QApplication>
#include <QWidget>
#include <QGroupBox>
#include <QLineEdit>
#include <QTextBrowser>
#include <QString>
#include <QVBoxLayout>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 创建 QWidget 作为主窗口
QWidget window;
QVBoxLayout* layout = new QVBoxLayout(&window);
// 创建 QGroupBox 及其子控件
QGroupBox* groupBox = new QGroupBox("My Group Box", &window);
QLineEdit* lineEdit = new QLineEdit("Text", groupBox);
QTextBrowser* textBrowser = new QTextBrowser(groupBox);
// 在 QTextBrowser 中显示 10 行文字
for (int i = 0; i < 10; ++i) {
textBrowser->append("Line " + QString::number(i + 1));
}
// 设置 QGroupBox 的布局并添加到主窗口的布局中
QVBoxLayout* groupBoxLayout = new QVBoxLayout(groupBox);
groupBoxLayout->addWidget(lineEdit);
groupBoxLayout->addWidget(textBrowser);
layout->addWidget(groupBox);
// 设置 QGroupBox 的禁用属性
// groupBox->setAttribute(Qt::WA_Disabled);
// 禁用并启用子控件
QList<QWidget*> childWidgets = groupBox->findChildren<QWidget*>();
foreach (QWidget* child, childWidgets) {
child->setEnabled(false);
}
lineEdit->setEnabled(true);
textBrowser->setEnabled(true);
lineEdit->setText(QString("%1 %2").arg(lineEdit->isEnabled()).arg(textBrowser->isEnabled()));
window.show();
return app.exec();
}
设置 QGroupBox 的禁用属性后的运行结果:
未设置 QGroupBox 的禁用属性后的运行结果:
可以看出来, QGroupBox禁用后子控件setEnable(true)是不生效的。
因为这个问题折腾的很久,分享出来供大家参考。
最终代码的解决方案是,遍历QGroupBox其他类型的子控件(非QTextBrowser)进行disable:
gboxCodeData->setAttribute(Qt::WA_Disabled);
Q_FOREACH(QLineEdit* child, gboxCodeData->findChildren<QLineEdit*>()) {
child->setEnabled(false);
}
Q_FOREACH(QPushButton* child, gboxCodeData->findChildren<QPushButton*>()) {
child->setEnabled(false);
}
Q_FOREACH(QRadioButton* child, gboxCodeData->findChildren<QRadioButton*>()) {
child->setEnabled(false);
}
Q_FOREACH(QComboBox* child, gboxCodeData->findChildren<QComboBox*>()) {
child->setEnabled(false);
}
Q_FOREACH(QLabel* child, gboxCodeData->findChildren<QLabel*>()) {
child->setEnabled(false);
}
Tip1: 我也试过下面的写法,但是QTextBrowser的滚动条还是不可用,没有深究原因:
gboxCodeData->setAttribute(Qt::WA_Disabled);
Q_FOREACH(QWidget* child, gboxCodeData->findChildren<QWidget*>()) {
if (child != txtbrowManualFiles && child != txtbrowManualFiles->verticalScrollBar()) {
child->setEnabled(false);
}
}
Tip2:
// 不能直接用下面的方式disable QGroupBox,不然其子控件也会自动被禁用
gboxCodeData->setEnabled(false);