【Qt初识】QWidget 核心属性Enabled:控件可用状态与禁用机制

发布时间:2026/7/9 7:15:24
【Qt初识】QWidget 核心属性Enabled:控件可用状态与禁用机制 大家好我是Halcyon.平安欢迎文末添加好友交流共同进步目录一、为什么要先了解 QWidget1.1 QWidget 是所有控件的基类1.2 在 Qt Creator 中查看和编辑属性1.3 这么多属性不需要全背二、Enabled 属性到底是什么2.1 可用 vs 禁用2.2 禁用状态的三大表现2.3 灰色头像不会再跳动三、Enabled 相关的 API四、UI 控件的 objectName 命名规范4.1 objectName 是什么4.2 objectName 必须唯一4.3 自动命名的规律4.4 不要用数字命名五、clicked 信号的两个版本六、代码实操【实操 1】创建一个禁用按钮【实操 2】通过按钮动态切换禁用状态目录前面几个章节我们讲完了信号槽机制从本章节开始我们正式进入 Qt 控件体系的学习不过在介绍各种内置控件之前我们得先聊一聊QWidget这个祖宗类——毕竟 Qt 里的各种控件都继承自它把它里面通用的属性方法搞清楚了后续学其他控件就能事半功倍一、为什么要先了解 QWidget我们前面其实就已经多次接触到QWidget了比如创建项目时基类就选它。这里我们再系统地认识一下。1.1 QWidget 是所有控件的基类Qt 中的各种控件——QPushButton按钮、QLabel标签、QLineEdit输入框、QMainWindow主窗口等等——全部都继承自QWidget这个类。这就意味着什么呢意味着QWidget里提供的属性和方法会被它所有的子类统统继承下来。换句话说QWidget里的属性方法是整个 Qt 控件体系中通用的基础能力。所以这块内容是我们首先要了解的——你把QWidget的通用属性学明白了后面再学任何一个具体的控件不管是按钮、标签还是输入框这些属性它都继承下来都能用这不是学一次的事是学一次用一辈子的事。1.2 在 Qt Creator 中查看和编辑属性我们直接打开 Qt Creator切到之前的项目里。由于我们前面创建的窗口就是基于QWidget的所以此时鼠标选中窗口右侧的属性面板就会显示出当前QWidget提供的各种属性。这里有两点很方便能查看右侧面板列出了QWidget的所有公开属性一目了然能编辑不光能看还能直接在面板里修改这些属性的值这些属性都是什么含义呢其实这些属性还是挺多的我们都可以通过 Qt 官方文档来一一了解。1.3 这么多属性不需要全背但是话又说回来了这么多属性我们并不需要把每一个属性都搞得清清楚楚。这个其实也没啥太大的必要为啥呢(⊙_⊙)跟给你一本英文词典是一样的道理——你并不需要把这本词典里面所有的词、所有的每一句话都背下来。很多东西都是用的时候再去查。所以我这里也只是给大家介绍一些比较重要的、比较常用的属性。下面我也给大家提供了一个属性对照表把QWidget在 Qt Creator 中所显示出的这些属性都列出来了并且针对每一个属性做了简单的讲解。感兴趣的同学可以自己浏览一下这个表格扩展了解。Qt Widget 常用属性汇总表属性作用enabled设置控件是否可使用。true表示可用false表示禁用。geometry位置和尺寸。包含xywidthheight四个部分坐标以父元素为参考。windowTitle设置Widget的窗口标题。windowIcon设置Widget的窗口图标。windowOpacity设置Widget的透明度。cursor鼠标悬停时显示的图标形状如普通箭头、沙漏、十字等。可在Qt Designer中直观选择。font字体相关属性涉及字体家族、大小、粗体、斜体、下划线等样式。toolTip鼠标悬停在Widget上时在状态栏中显示的提示信息。toolTipDuringtoolTip提示信息的显示持续时间。statusTipWidget状态发生改变时如按钮被按下在状态栏显示的提示信息。whatsThis鼠标悬停并按下AltF1时在弹出窗口中显示的帮助信息。styleSheet允许使用CSS样式表来设置Widget的样式样式定制能力非常丰富。focusPolicy控件获取焦点的方式。•Qt::NoFocus不参与焦点管理。•Qt::TabFocus可通过Tab键获得焦点。•Qt::ClickFocus可通过鼠标点击获得焦点。•Qt::StrongFocus可通过键盘和鼠标获得焦点。•Qt::WheelFocus可通过鼠标滚轮获得焦点部分平台或样式可能不可用。contextMenuPolicy上下文菜单的显示策略。•Qt::DefaultContextMenu默认策略鼠标右键或键盘快捷键可触发。•Qt::NoContextMenu禁用上下文菜单。•Qt::PreventContextMenu阻止控件显示上下文菜单。•Qt::ActionsContextMenu将菜单替换为控件的“动作”菜单。•Qt::CustomContextMenu使用自定义的上下文菜单。locale设置语言和国家地区。acceptDrops该部件是否接受拖放操作。为true时可接收来自其他部件的拖放并触发相应事件如dropEvent为false则不接收。minimumSize控件的最小尺寸包含最小宽度和最小高度。maximumSize控件的最大尺寸包含最大宽度和最大高度。sizePolicy尺寸策略设置控件在布局管理器中的缩放方式。windowModality指定窗口是否具有“模态”行为。sizeIncrement拖动窗口大小时的增量单位。baseSize窗口的基础大小与sizeIncrement配合使用用于计算组件应调整到的合适尺寸。palette调色板用于设置Widget的颜色风格。mouseTracking是否跟踪鼠标移动事件。•true鼠标划过时Widget持续收到鼠标移动事件。•false鼠标划过时Widget只收到按下或释放事件不收到移动事件。tabletTracking是否跟踪触摸屏的移动事件类似于mouseTracking是Qt 5.9引入的属性。layoutDirection布局方向。•Qt::LeftToRight从左到右排列默认。•Qt::RightToLeft从右到左排列。•Qt::GlobalAtomics由应用程序中其他Widget的布局方向决定。autoFillBackground是否自动填充背景颜色。windowFilePath将Widget与一个本地文件路径关联起来实际作用不大。accessibleName设置Widget的可访问名称可被屏幕阅读器等辅助技术获取用于无障碍程序场景。accessibleDescription设置Widget的详细描述作用同accessibleName。inputMethodHints针对输入框有效提示用户当前可输入的合法数据格式如只能输入数字或日期等。我们接下来要做的就是从这些属性里挑出几个比较重要的、比较常用的单独拎出来配合代码给大家演示效果。我们第一个要介绍的重要属性就叫做Enabled。二、Enabled 属性到底是什么2.1 可用 vs 禁用这个所谓的Enabled其实也比较好理解它描述的是一个控件是否处于可用这样的状态。什么叫可用与可用相对的另外一个概念叫做禁用可用enabled你可以正常去使用它。我们之前创建的按钮、输入框啥的默认都属于可用状态。禁用disabled这个控件当前无法使用了。那禁用到底是什么效果主要有以下三点。2.2 禁用状态的三大表现第一不能接收任何用户的输入事件。什么意思就是禁用状态下你这个控件就不能再去接收任何用户的输入事件了——鼠标往上一点没啥反应键盘怎么去摁也没啥反应。你不管怎么操作它都不会去鸟你了完全无视。第二外观上会显示成一个灰色的状态。就是灰了嘛看起来就是点不了的样子。这个大家平时用软件应该也见过一个按钮变灰了你就知道它现在点不了。第三子元素会跟着一起被禁用重点大家不要忘了在 Qt 中我们的控件对象可都是以对象树的方式来组织的。这就意味着——如果一个控件被禁用了那么这个控件它的子元素也会被禁用。它属于是一荣俱荣一损俱损。你把这棵对象树上其中某个节点的控件设为禁用了那这个控件下面的所有子控件也就被禁用了。所以禁用是会沿着对象树向下传递的。这一点特别重要如果你以后发现一个控件怎么点都没反应除了检查它自己有没有被禁用还得往上看看它的父控件是不是被禁用了。2.3 灰色头像不会再跳动讲到禁用状态这个灰色的效果就恍然间让我想起一首许嵩的歌——不知道同学们有没有听过叫《灰色头像》其中怎么唱来着“你灰色头像不会再跳动”灰色头像不会再跳动意味着什么意味着你再给他发消息都不会再有响应了这跟我们禁用控件是一模一样的——按钮变灰了意思就是你再怎么点它都没用了。所以这还真是一个挺悲伤的故事啊。三、Enabled 相关的 API那我们如何去获取和设置一个控件的 enabled 状态呢回到课件上这里列出了相关的 API。API返回值说明isEnabled()bool获取当前控件是否可用。true就是可用false就是禁用setEnabled(bool)void设置当前控件是否可用。传true设为可用传false设为禁用人家这个方法名字呢起得也是非常直观——isEnabled就是是否可用setEnabled就是设置是否可用基本上一看名字咱们就能知道它是如何使用的。true/false对应可用/禁用一目了然。四、UI 控件的 objectName 命名规范在正式写代码演示之前我们先得补充一个非常关键的知识点——objectName 命名规范。这个知识点在我们通过 UI 文件拖拽创建控件的时候非常重要是后面写代码的基础必须搞清楚。4.1 objectName 是什么当我们通过 UI 文件也就是 Qt Designer 设计器拖拽创建控件的时候每个控件都会有一个叫做objectName对象名的属性这个东西非常关键比如我们拖一个push button到界面上选中它在右侧属性面板里就能看到它的 objectName 就叫做pushButton。再拖第二个按钮进去它的 objectName 就叫做pushButton_2。这个 objectName 有什么用呢后续我们在 C 代码中就可以通过ui-objectName的方式来获取到对应的控件对象ui-pushButton// 得到第一个按钮对象ui-pushButton_2// 得到第二个按钮对象4.2 objectName 必须唯一这里有一个硬性要求同一个界面中不同控件的 objectName 必须不同不能重复换句话说不能重名。为什么呢这就涉及我前面反复给大家提过的那个元编程技术了。元编程是怎么回事Qt 会根据我们的 UI 文件.ui文件在编译时自动生成一个叫做ui_widget.h的头文件。生成的过程中Qt 就会感知到这个界面上都有哪些控件、每个控件的 objectName 是什么。然后它就会根据 UI 文件的内容把这些控件作为成员变量统统定义到生成的Ui::Widget类里面——控件的 objectName 是什么成员变量名就叫什么。所以我们写ui-pushButton能拿到对应的对象本质上是因为 Qt 在背后根据 objectName 自动帮我们生成了对应的成员变量。如果你的 objectName 重名了生成的成员变量也就冲突了所以必须唯一。4.3 自动命名的规律仔细观察可以发现Qt 自动生成的 objectName 是有一定规律的控件类型 下划线 数字比如QPushButton这个类型去掉Q前缀就是push button所以第一个QPushButton→pushButton第二个QPushButton→pushButton_2第三个QPushButton→pushButton_3……依次往后排4.4 不要用数字命名但是这种以数字方式命名其实不是一个很好的编程习惯为啥因为数字是没有任何含义的你看到pushButton_2这个名字根本不知道这个按钮是干嘛用的。我们还是期望变量名能够见名知义。所以一般我们不太会直接使用自动生成的名字而是手动修改成一个更有描述性质的名字。比如一个按钮的作用是切换可用状态那我们就把它的 objectName 改成enable或者类似的语义化名字而不是用默认的pushButton_2。良好的命名习惯是工程化编码的基本要求。大家从一开始就养成这个习惯后面写出来的代码可读性会高很多五、clicked 信号的两个版本还有一个前面遗留的小知识点在这里一并说明。我们在给按钮转到槽的时候会发现clicked信号其实有两个版本// 版本 1无参数voidclicked();// 版本 2带布尔参数voidclicked(boolchecked);那我们用哪个呢对于QPushButton来说我们一般使用无参数版本即可。那个带布尔参数的版本里checked表示的是当前是否处于一个被勾选的状态——表示是否被勾选。这件事情对于普通的QPushButton来说是没有意义的所以我们不去考虑它。但是后续我们介绍到QCheckBox复选框、QRadioButton单选按钮这种可勾选的按钮类控件时这个带参版本就有用了。所以这里先记住普通 PushButton 用无参clicked()可勾选的 CheckBox / RadioButton 才考虑带参clicked(bool)。六、代码实操从这里开始就是实操部分了。以下两个实操需要我们亲自动手完成——创建项目、拖控件、写代码、运行验证。【实操 1】创建一个禁用按钮目标体验一下禁用到底长什么样。操作步骤创建项目新建一个项目起名为QWidget_1基类选择QWidget一路下一步完成写代码在Widget.cpp的构造函数里手动new一个按钮出来把它设为禁用状态运行观察看看按钮是不是变灰了点它有没有反应关联槽函数验证给按钮连上槽函数再次运行确认禁用状态下即使连了槽函数也点不动代码参考#includewidget.h#includeui_widget.h#includeQPushButton// 使用 QPushButton 需要包含这个头文件#includeQDebugWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);// new 一个按钮不要忘了传 this 指定父对象纳入对象树管理QPushButton*buttonnewQPushButton(this);button-setText(按钮);// 把按钮设为禁用状态button-setEnabled(false);}验证要点运行后按钮应该是灰色的鼠标点击它没有任何反应即使你给它关联了槽函数connect 打印日志禁用状态下槽函数也不会触发——这跟连不连槽函数没关系禁用了就是用不了【实操 2】通过按钮动态切换禁用状态目标通过第二个按钮在程序运行过程中动态切换第一个按钮的可用/禁用状态。操作步骤创建项目新建项目QWidget_2基类选QWidgetUI 搭建打开.ui文件拖入两个按钮第一个按钮文本设为按钮objectName 保持默认pushButton第二个按钮文本设为切换可用状态objectName 手动改为enable见名知义添加槽函数分别给两个按钮右键 → 转到槽 → 选择clicked()→ 确认写槽函数逻辑第一个按钮的槽函数打印一条日志验证它是否被触发第二个按钮的槽函数先获取第一个按钮的当前状态然后做取反切换运行验证点第一个按钮有反应点第二个按钮后第一个变灰再点第一个没反应再点第二个又恢复代码参考// 第一个按钮的槽函数打印日志验证是否触发voidWidget::on_pushButton_clicked(){//记得加上头文件#includeQDebugqDebug()执行了槽函数;}// 第二个按钮的槽函数切换第一个按钮的禁用状态voidWidget::on_enable_clicked(){// 先获取第一个按钮当前是否可用boolenableui-pushButton-isEnabled();if(enable){// 当前可用 - 设为禁用ui-pushButton-setEnabled(false);}else{// 当前禁用 - 设为可用ui-pushButton-setEnabled(true);}}验证流程程序启动连续点击第一个按钮观察控制台是否持续打印执行了槽函数点击第二个切换可用状态按钮观察第一个按钮是否立刻变灰变灰后再点击第一个按钮确认无反应、控制台不再打印再点一下第二个按钮观察第一个按钮是否恢复正常再点第一个按钮确认又能正常触发了核心结论禁用就是按钮变灰再怎么点都没用。理解了这一点本章节的目标就达成了