Qt控件可见性深度解析:isVisible、isHidden与isVisibleTo的微妙差异
一、对照实验代码#includeQApplication#includeQWidget#includeQPushButton#includeQDebugvoidprintStatus(constQStringtag,QWidget*container,QPushButton*btn){qDebug().noquote()QString(\n %1 ).arg(tag);qDebug()btn-isHidden() :btn-isHidden();qDebug()btn-isVisible() :btn-isVisible();qDebug()btn-isVisibleTo(btn) :btn-isVisibleTo(btn);qDebug()btn-isVisibleTo(container) :btn-isVisibleTo(container);qDebug()btn-isVisibleTo(nullptr) :btn-isVisibleTo(nullptr);qDebug()container-isHidden() :container-isHidden();qDebug()container-isVisible() :container-isVisible();}intmain(intargc,char*argv[]){QApplicationa(argc,argv);QWidget topWindow;QWidgetcontainer(topWindow);QPushButtonbtn(Test,container);topWindow.show();QApplication::processEvents();printStatus(初始状态全部可见,container,btn);container.setVisible(false);printStatus(container-setVisible(false),container,btn);container.setVisible(true);printStatus(container-setVisible(true) 恢复,container,btn);btn.setVisible(false);printStatus(btn-setVisible(false),container,btn);btn.setVisible(true);printStatus(btn-setVisible(true) 恢复,container,btn);container.hide();printStatus(container-hide(),container,btn);container.show();printStatus(container-show() 恢复,container,btn);btn.hide();printStatus(btn-hide(),container,btn);btn.show();printStatus(btn-show() 恢复,container,btn);container.setVisible(false);btn.setVisible(false);printStatus(container 和 btn 都隐藏,container,btn);container.setVisible(true);printStatus(仅 container 显示btn 仍隐藏,container,btn);container.setHidden(true);printStatus(container-setHidden(true),container,btn);container.setHidden(false);printStatus(container-setHidden(false) 恢复,container,btn);return0;}二、实际运行输出 初始状态全部可见 btn-isHidden() : false btn-isVisible() : true btn-isVisibleTo(btn) : true btn-isVisibleTo(container) : true btn-isVisibleTo(nullptr) : true container-isHidden() : false container-isVisible() : true container-setVisible(false) btn-isHidden() : false btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : true btn-isVisibleTo(nullptr) : false container-isHidden() : true container-isVisible() : false container-setVisible(true) 恢复 btn-isHidden() : false btn-isVisible() : true btn-isVisibleTo(btn) : true btn-isVisibleTo(container) : true btn-isVisibleTo(nullptr) : true container-isHidden() : false container-isVisible() : true btn-setVisible(false) btn-isHidden() : true btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : false btn-isVisibleTo(nullptr) : false container-isHidden() : false container-isVisible() : true btn-setVisible(true) 恢复 btn-isHidden() : false btn-isVisible() : true btn-isVisibleTo(btn) : true btn-isVisibleTo(container) : true btn-isVisibleTo(nullptr) : true container-isHidden() : false container-isVisible() : true container-hide() btn-isHidden() : false btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : true btn-isVisibleTo(nullptr) : false container-isHidden() : true container-isVisible() : false container-show() 恢复 btn-isHidden() : false btn-isVisible() : true btn-isVisibleTo(btn) : true btn-isVisibleTo(container) : true btn-isVisibleTo(nullptr) : true container-isHidden() : false container-isVisible() : true btn-hide() btn-isHidden() : true btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : false btn-isVisibleTo(nullptr) : false container-isHidden() : false container-isVisible() : true btn-show() 恢复 btn-isHidden() : false btn-isVisible() : true btn-isVisibleTo(btn) : true btn-isVisibleTo(container) : true btn-isVisibleTo(nullptr) : true container-isHidden() : false container-isVisible() : true container 和 btn 都隐藏 btn-isHidden() : true btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : false btn-isVisibleTo(nullptr) : false container-isHidden() : true container-isVisible() : false 仅 container 显示btn 仍隐藏 btn-isHidden() : true btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : false btn-isVisibleTo(nullptr) : false container-isHidden() : false container-isVisible() : true container-setHidden(true) btn-isHidden() : true btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : false btn-isVisibleTo(nullptr) : false container-isHidden() : true container-isVisible() : false container-setHidden(false) 恢复 btn-isHidden() : true btn-isVisible() : false btn-isVisibleTo(btn) : false btn-isVisibleTo(container) : false btn-isVisibleTo(nullptr) : false container-isHidden() : false container-isVisible() : true三、行为归纳与表格1. 接口等价关系表操作等价写法 显示控件setVisible(true)/show()/setHidden(false) 隐藏控件setVisible(false)/hide()/setHidden(true)2. 主表格基于setVisible写法因为setVisible、show、setHidden、hide接口有等价关系这里基于setVisible写法归纳。操作btn-isVisiblebtn-isVisibleTo(btn)btn-isVisibleTo(nullptr)btn-isVisibleTo(container)btn-isHiddencontainer-isHiddencontainer-isVisiblecontainer-setVisible(true)btn-setVisible(true)truetruefalsefalsetruecontainer-setVisible(false)btn-setVisible(true)falsetruefalsetruefalsecontainer-setVisible(true)btn-setVisible(false)falsefalsetruefalsetruecontainer-setVisible(false)btn-setVisible(false)falsefalsetruetruefalse3. 关键点btn-isVisibleTo(container)的特例检查从btn到container路径上btn自身的可见性不关心container是否隐藏。三个等价的 btn 查询函数btn-isVisible()、btn-isVisibleTo(btn)、btn-isVisibleTo(nullptr)在所有测试场景中返回值完全相同可视为等价。isHidden()含义仅反映控件自身是否被显式隐藏setVisible(false)/hide()/setHidden(true)不受祖先控件可见性影响。isVisible()含义需要控件自身及所有祖先直到顶层窗口均可见且顶层窗口已show()才返回true。