上一章节我们讲完了 Window Frame 对
geometry的影响,本章节我们继续来认识QWidget的另外两个核心属性------WindowTitle (窗口标题)和 WindowIcon(窗口图标)。这俩属性用法上有不少共通之处,也有一些容易踩坑的地方,咱们一并聊清楚。
一、WindowTitle:窗口标题
1.1 它是干嘛的
这个东西我们前面其实也举过例子了。通过 WindowTitle 这个属性,可以来设置窗口的标题:
- 一方面,我们可以直接通过
windowTitle()来获取当前窗口标题是什么 - 另一方面,也可以通过
setWindowTitle()来修改 窗口标题,参数就是我们前面交代过的QString
1.2 只对"顶层窗口"有效(重点!)
这里大家要注意,窗口标题这件事情,不是你给所有的 Widget 设置都有效。
当前我们的 windowTitle 属性以及这两个方法,它是从属于 QWidget 的。而 QWidget 是一个非常广泛的概念------你一个按钮是一个 QWidget,一个输入框也是一个 QWidget,同时你这个窗口也是一个 QWidget。
但是!
windowTitle属性只能针对"顶层窗口"这样的QWidget才有效。如果你给窗口里面的一个什么按钮、或者输入框设置
windowTitle,它是不具备任何效果的。
这点非常关键,谁才是那个窗口,我们才能给谁去设置。
二、代码实操:给窗口和按钮分别设置标题
从这里开始是实操部分。以下实操需要你亲自动手完成------创建项目、写代码、运行验证。
【实操 1】验证 WindowTitle 只对顶层窗口生效
目标:给顶层窗口设置标题(生效),再给按钮设置标题(不生效也不报错),观察现象。
第一步:创建项目
操作 :新建项目 QWidget_6,基类选 QWidget,一路下一步完成。
第二步:编写代码
代码参考:
cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton> // 别忘了包含头文件
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 1. 给顶层窗口(this)设置标题 ------ this 可以省略,这里写出来更清晰
this->setWindowTitle("这是窗口标题");
// 2. 再创建一个按钮,给按钮也设置一下 windowTitle
QPushButton* button = new QPushButton(this);
button->setText("按钮");
// 给按钮设置窗口标题 ------ 这一步是"不科学"的写法,用来演示现象
button->setWindowTitle("这是通过按钮设置窗口标题");
}
第三步:运行验证
验证流程:
- 运行程序,观察窗口标题栏------应该显示"这是窗口标题"
- 按钮上的文本显示为"按钮"(说明按钮相关代码确实执行到了)
- 但是------给按钮设置的
windowTitle没有任何效果,窗口标题也没有被影响

结论 :按钮文本都变成"按钮"两个字了,说明给按钮设置
windowTitle这一行代码确实执行到了 ,但这一行代码的执行对窗口标题没有任何影响 。主要就是------谁是那个窗口,我们才能给谁去设置,这点非常关键。
三、"静默失败"为什么不科学
不过这里有一个不太好的小问题:你虽然给按钮这个不该设置 windowTitle 的地方设置了,它并没有报错 ,也没有任何错误提示,只不过是什么都没有发生。
3.1 静默失败的隐患
这种"没有报错"的设定,其实是不太科学的。
为什么说不科学呢?假设在实际开发中,我们确实就想修改窗口标题,但是界面比较复杂,你可能搞错了------误以为某一个控件就是那个窗口,就给它设置了。结果设置之后没生效,你也没太注意,程序又没有任何报错,你以为功能实现了,其实这个问题就已经埋藏下来了。
3.2 报错是一件好事
所以我们更希望:当我们写出这种不科学的代码时,它能给一些显式的报错提示。
其实啊,像我们以前刚开始初学编程的时候,可能对新手朋友来说,报错是一个非常让人头疼的问题------我一写一行代码,结果出了两三个报错,这个就真的特别特别恼火。
但是!当你代码写得多了,当你具有一定的开发经验,尤其是当你为你代码中的 bug 买过单之后,那这个时候你就会知道------这个报错其实是一件多么好的事情。
报错它确实出错了,但是它出错之后,就能够让我们及时地发现问题、及时地改正问题,避免这个问题被拖延之后产生出一些更严重的后果------
变相地帮我们保住了年终奖啊!
所以这一点整体来说还是我们更期望能看到的。
3.3 开发建议:对关键操作做校验
因此同学们,我们后续自己在编写代码的时候,一定要确保------代码能够对一些关键性质的用户操作逻辑进行校验。
如果出现一些出错的操作,或者本来就不科学、不应该发生的情况,一定要能够及时给出提示,避免出现这种"将错就错"的情况。
报错本质上是提前暴露问题的有效机制,可以避免隐性 bug 累积引发更严重的线上问题,降低后续排查与修复成本。这一点希望大家重点理解。
四、WindowIcon:窗口图标
4.1 图标显示在哪儿
接下来我们介绍下一个属性------WindowIcon,它表示一个窗口的图标。
这个图标是啥呢?大家仔细观察一下当前运行的这些程序,它们的窗口都是带有一个小图标的。可以看到两个地方:
- 窗口最左上角 :标题栏左边那一小块

- 任务栏 :你运行一个程序,任务栏这里也会显示出对应的图标

不同的程序图标不一样------Chrome 浏览器是一个圆圈,画图板是另外一个图标。
4.2 Qt 默认图标比较丑
那么我们之前所写的这些 Qt 程序,它那个图标长啥样呢?找个前面的项目运行一下就能看到------
这个默认的图标看起来好像就比较丑,并不好看。所以我们就可以使用
windowIcon这样的属性来修改这个图标,把它改成一个你觉得比较美观的图标。
4.3 相关 API
| API | 返回值 | 说明 |
|---|---|---|
windowIcon() |
QIcon |
获取当前窗口图标,返回一个 QIcon 对象 |
setWindowIcon() |
void |
设置窗口图标,传入一个 QIcon 对象 |
前面这个
windowIcon()获取操作其实我们很少会用到 ------一般不会去获取图标,也不会中途更改图标。setWindowIcon()才是我们主要使用的方式:你这个程序,提前把 logo 做好、把图标做好,程序启动时就给它设置过去,这样整个程序看起来就会比较好看。
4.4 QIcon 是什么
windowIcon() 返回的是一个 QIcon 对象。这个东西我们前面没遇到过,但同学们应该不难理解------
在 Qt 中,它的面向对象做得就很好。Qt 中把各种相关概念,都封装成了类。这个
QIcon它就表示一个图标。
具体怎么用,写代码一看就了解了。
4.5 同样只对顶层窗口生效
大家也要注意,这个 API 和我们刚才说的那个 WindowTitle 一样------都只是针对当前的这个顶层窗口才能使用。
类似于
WindowTitle,只能针对顶层窗口使用。你要是针对窗口内的一个普通控件来使用,它是没有效果的。
五、QIcon 创建规范(重点)
写代码之前,这里有一个小细节大家要注意:咱们用的这个 QIcon,它就不能够再在堆上去 new 出这个对象了,咱们还是尽量直接在栈上创建。
5.1 为什么 QIcon 在栈上创建
我们前面推荐使用堆上创建对象,主要是为了------
- 通过 Qt 对象树来释放对象
- 确保控件的生命周期足够
但是对于 QIcon 来说,它是不一样的:
第一,QIcon 自身是一个比较小的对象。 我们创建出对象之后,目的就是为了把它设置到某个 QWidget 里面。这个时候你这个 QIcon 对象本身释放不释放,它不影响图标最终的显示。
像之前我们搞的什么
QPushButton,如果它提前释放了,最后界面上就显示不出来。但是QIcon不存在这个问题------你只要设置过去之后,原来的对象就算释放了,那最终这个图标也是有效的。
第二,QIcon 并不支持对象树机制。 也就是说你无法给它指定一个父对象,自然也就没法让 Qt 通过对象树机制对它进行释放。
所以这里我们直接把它创建在栈上就行了,函数一结束自己就释放,OK。
5.2 头文件包含规则
创建好 QIcon 对象之后,可能会提示"不完整类型"------说明它不认识 QIcon。这个事情也好办,包含一个对应的头文件 #include <QIcon> 就行。
在 Qt 中,封装的这些类都会有一个同名的头文件。你哪个类找不到定义,那就包含哪个类对应的头文件就行了。这一点很方便,规则都是一致的,不需要额外去查什么文档。后面同学们做程序设计的时候,也可以参考这种设计风格。
六、代码实操:设置窗口图标
以下实操需要你亲自动手完成。本实操只是把图标设上去,关于"用绝对路径加载图片不科学"的问题,我们留到下一篇博客专门讲------这里先看到效果即可。
【实操 2】给顶层窗口设置图标
目标 :准备一张图片,用 QIcon + setWindowIcon 把窗口默认图标替换成自定义图片。
第一步:准备图片
操作:
- 提前准备好一张图片(比如一坨小粑粑
baba.png,或者你喜欢的唱跳rap篮球图片都行,"你们乐意设置啥就设置啥") - 把图片放在一个好找的路径 下,比如直接放在
E:盘下面,文件名叫baba.png
注意:文件名和文件路径不要带中文!这点要求我们前面也说过。这里先用绝对路径,下一篇我们会专门讲为什么绝对路径不科学。
第二步:创建项目
操作 :新建项目 QWidget_7,基类选 QWidget,完成。
第三步:编写代码
代码参考:
cpp
#include "widget.h"
#include "ui_widget.h"
#include <QIcon> // 用到 QIcon,别忘包含头文件
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 1. QIcon 在栈上创建(不要 new!),构造时传入图片路径
// 路径用正斜杠作为分隔符,避免反斜杠的转义问题
QIcon icon("E:/baba.png");
// 2. 把图标设置到顶层窗口
this->setWindowIcon(icon);
}
开发小贴士(路径写法):
- 优先使用正斜杠
/,简单直接- 反斜杠在 C++ 中是转义字符 ,如果写成
"D:\rose.jpg",\r就被当成回车符了(光标回到行首),路径就错了,图片加载不出来- 如果非要用反斜杠,就写双反斜杠
"D:\\rose.jpg"转义一下- C++11 还提供了 RawString 语法:
R"(D:\rose.jpg)",里面的字符全部不转义。但既然有正斜杠,咱就没必要写那么麻烦了
第四步:运行验证
验证流程:
- 运行程序,观察窗口最左上角的图标------应该变成了你设置的那张图片
- 观察任务栏对应程序位置------图标也应该是你设置的那张图片
- 如果图标仍然是默认的(没变化也没报错)------说明图片路径写错了!Qt 不会报错,只会回退到默认图标,这点要主动校验

七、本篇小结
| 属性 | 作用 | 适用范围 | 关键 API |
|---|---|---|---|
WindowTitle |
设置/获取窗口标题 | 仅顶层窗口 | windowTitle() / setWindowTitle() |
WindowIcon |
设置/获取窗口图标 | 仅顶层窗口 | windowIcon() / setWindowIcon() |

我们改上图标+标题,甚至可以玩点更有趣的,比如说是你通过按钮链接信号槽来动态改变!
两个核心要点:
- 这两个属性都只对顶层窗口生效,给普通子控件设置既无效果也无报错------这种"静默失败"不科学,咱们自己写代码时要主动对关键操作做校验
QIcon是个小对象、不支持对象树,直接在栈上创建 即可,不要new
那么问题来了------我们刚才用绝对路径
D:/rose.jpg加载图片,这种写法科学吗?程序发布到用户电脑上还能用吗?下一篇我们就来好好聊聊文件路径的处理方案 ,以及 Qt 提供的终极解法------QRC 资源机制。