本文参考了以下文章:
- xukai871105的CSDN:树莓派学习笔记——获取树莓派CPU温度
- 遗步看风景的简书:几种设置树莓派开机自启的方法
CPU是树莓派的核心硬件,也是主要热源。官方标配的树莓派不具备散热部件,例如散热片、风扇等等,如果CPU温度过高就会引发过热保护,对寿命也有一定影响。通常购买一些散热片能改善这个问题,同时也有必要编写工具实时查询并显示CPU温度,起到提示的作用。
Qt是跨平台的C++编程框架,号称“一次编写,到处编译”。树莓派的软件库中也具备Qt,说明Qt对树莓派也有良好的支持。这篇博文介绍的就是使用Qt编写的,树莓派CPU温度实时显示的工具。
树莓派CPU温度的查看方法
树莓派的温度监测机制是这样的,检测CPU的温度并写入系统文件中,而且定时刷新。这个文件的具体路径是/sys/class/thermal/thermal_zone0/temp,它是一个只读文件。我们只须访问这个文件,即可获得当前CPU的温度。通过图形界面查看比较简单,这里只提供使用终端命令查看的方法。
在终端输入以下命令:
cd /sys/class/thermal/thermal_zone0
进入temp文件所在的目录后,输入以下命令:
cat temp
系统输出(以我的树莓派为例):51540
注意:需要将这个数值除以1000,获得才是实际的温度,以摄氏度为单位。那么我的树莓派的CPU当前温度约为52℃。
软件设计思路
这个小工具的主要功能是显示树莓派的CPU温度,它应该具有以下特点:
- 常驻桌面:对CPU温度的监测是个持续的过程。一方面我们要随时了解树莓派的CPU温度情况,另一方面工具窗口又不能干扰正常的工作。有两种实现方式,即桌面小部件/托盘图标,最终我选择了托盘图标的方式。
- 实时显示:CPU的温度是不断变化的,这个工具必须不断的查询CPU温度,然后显示到工具界面上。实现方式:设置一个定时器,通过读秒的方式不断的访问temp文件,并刷新工具显示。
- 开机启动:显示CPU温度是重要的需求,有必要每次使用树莓派都启动这个工具,因此设置该工具的开机启动势在必行。具体的实现方式在后文介绍。
编写程序
注意:阅读这部分内容需要一定的C++与Qt基础。
前置条件
假定你有一个Raspbian系统的树莓派,并安装了Qt Creator和Qt5。
建立工程
Qt Creator在各平台的使用都基本相同,这里不详细说明。我建立的工程名为cpu,设置的基类是QDialog。
实现托盘显示
首先要隐藏主窗口。这个程序的功能是通过托盘图标进行的,因此主窗口不需要显示。进入main.cpp并删除以下代码:
w.show();
然后找一张托盘图标的素材,这个看个人喜好。既然是显示CPU温度的工具,我选择了这张图片:
需要注意的是,因为要显示CPU的温度,图片中央空白为好。之后将该图片导入项目的资源文件中。这个步骤比较简单,不再说明。在我的项目中,该图片的路径为“://cpu.png”。这样,素材准备完成。
编程方面,Qt中提供了与托盘操作相关的类QSystemTrayIcon。我们使用这个类创建托盘图标对象icon。图标的显示需要用到QPixmap类,图标对象为image。以下是详细代码。
dialog.h
首先引入头文件:
#include <QSystemTrayIcon>
#include <QPixmap>
定义托盘对象:
private:
QSystemTrayIcon *icon;
QPixmap image;
dialog.cpp
在构造函数中对托盘对象和图标对象进行初始化,代码如下:
image.load("://cpu.png"); //读取图标资源文件
icon = new QSystemTrayIcon(this);
icon->setIcon(QIcon(image));
icon->show(); //显示托盘图标
到这步可以查看一下运行效果。在我的树莓派上,运行结果是这样的:
因为隐藏了主窗口,程序是没法关闭的。作为监测CPU温度的程序,用户主动关闭的可能性较小,但是编写这个功能仍是必要的。因此,在dialog.cpp的构造函数中加入以下代码:
connect(icon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
qApp, SLOT(quit()));
将对托盘图标的操作信号连接到程序的退出槽上,也就是鼠标点击托盘图标,程序退出。
实现查询功能
由上文树莓派cpu温度的查看方法可知,查询过程比较简单,并不涉及硬件操作,只是文件访问而已。因此就要用到QFile类,我们定义一个文件指针temp,用于访问保存CPU温度的文本文件。
dialog.h
引入头文件:
#include <QFile>
#include <QTextStream> //文本流类,用于对文本文件的读写。
定义文件指针:
private:
QFile *temp;
dialog.cpp
在构造文件中对temp进行初始化,其中的字符串是树莓派CPU温度文件的路径:
temp = new QFile("/sys/class/thermal/thermal_zone0/temp");
此时可以测试一下看是否能输出系统的温度,在上文后加入以下代码:
/********************测试内容********************/
if (!temp->open(QIODevice::ReadOnly | QIODevice::Text)) //打开CPU温度文件。
{
qDebug()<<"读取文件失败"; //需要引入<QDebug>头文件。
qApp->exit(); //程序退出。
}
else
{
QTextStream stream(temp);
QString string = stream.readAll(); //读取温度。
temp->close(); //关闭文件。
long s = string.toLong() / 1000; //转换成长整形的,以摄氏度为单位的数值。
qDebug()<<"CPU温度为"<<s<<"℃";
}
/********************测试内容********************/
运行程序,正常情况下会在控制台输出如下语句:“CPU温度为XX℃”。
设置定时器
我们需要设置一个定时器,来保证不断地查询CPU的温度并显示。在Qt中,定时器的使用比较固定,基本遵循这4个步骤:定义定时器指针、编写槽函数、将定时器时间耗尽的信号与槽函数连接、启动定时器。以下是详细代码。
dialog.h
引入定时器头文件:
#include <QTimer>
定义定时器指针、声明槽函数update():
private:
QTimer *timer;
private slots:
void update();
dialog.cpp
在构造函数中加入以下代码:
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(3000);
第一行初始化定时器指针timer,第二行是timer的时间耗尽信号与update()槽函数的连接,第三行是启动定时器。根据start(int)函数的说明,参数是以毫秒为单位的,3000毫秒就是3秒。
关于设置3秒的说明:我认为监测CPU的温度没有频繁更新的必要,而且存储树莓派CPU温度的temp文件本身更新频率也是比较慢的。
当然,还要加入update()函数的实现:
void Dialog::update()
{
}
此时,你可以将上面的测试代码,不加修改复制到update()的函数体中,并运行。正常情况下,程序会每隔3秒在控制台输出如下语句:“CPU温度为XX℃”。
之后的内容请看下一篇博客。
工具的代码及可执行程序下载地址:
http://download.csdn.net/detail/u012952807/9825067