一、创建好云端MySQL服务器
这里我选用的是阿里云的云平台,数据是则从阿里云的物联网平台获取的传感器实时采集的数据流转到云平台的数据库中便于qt读取。
1.首先我们先登陆阿里云平台注册一个免费的RDS数据库,这里我选用的是MySQL Serverless数据库,试用的话有三个月试用时长。(注意这里注册的数据库地区要与物联网平台的地区保持一致)
2.注册好之后我们点击RDS管理控制台,点击自己的实例,点击账号管理,创建一个管理自己数据库的用户,一定要赋予高权限账号,否则普通账号无法访问数据库
3.点击数据库管理,创建一个数据库,数据库名任取。
4.创建完后先点击数据库连接,将数据库的外网地址打开,便于其他用户有权限可以访问我们的数据库。
5.点击白名单与安全组,将要访问到这个数据库的ip按照格式添加到列表中(或者点击全网开放,一般数据库不会被其他人攻击)
6.随后我们直接点击登陆数据库,输入在第二步创建好的高权限用户的账号密码,进入数据库管理,点击左侧数据库实例,找到我们第三部创建好的数据库
双击,可以选择直接创建表双击,可以在表那一栏中选择直接手动创建表,或者在右端控制台选择使用mysql语言创建表,这里大家自行操作,我这里创建了几个对应与物联网平台中物模型的数据
7.创建完数据表后接下来我们进入物联网平台里对数据进行流转到mysql数据库,进入我们自己的实例中,选中云产品流转,然后左上角选择旧版
8.然后点击创建规则,名字任意,数据类型选择json格式
9.在处理数据栏点击编写SQL,字段按照你设置的数据库表中需要的数据编写,例如
SELECT items.temperature.value as temperature,items.Humidity.value as Humidity,items.soilHumidity.value as soilHumidity,items.LightLux.value as LightLux,items.WaterOutletSwitch.value as WaterOutletSwitch,items.Rain.value as Rain FROM "/htr9bLcCQKY/name/thing/event/property/post" WHERE
我们可以更改其中的数据自行添加。
10.在topic中选择物模型数据上报,产品和设备选择自己需要流转到数据库的产品和设备。
11.在转发数据出选择添加操作,操作选择存储到RDS云数据中,填写自己的数据库以及账号密码,选择自己数据库中创建好的表名,然后对数据进行绑定,键的名字一定要与RDS数据库的名字一致,值的格式为${xxx},xxx一定要与自己设备里的物模型名字保持一致。点击完成(它会跳出授权RDS数据库的信息,我们直接点击它写的授权就可以了),发布上线。
我们要是安装了Navicat的可以先用一下Navicat看是否能连接到数据库,并查看到数据库里的数据。如果有问题就检查一下是不是第五步白名单没有开放,或者物模型数据流转有问题。
二、编写QT调用云端数据库的程序
这里我qt的版本是5.14.2,编译器MinGW 64-bit,使用语言为c++11
这里我实现的是一个登陆界面,然后添加了查询、增加、修改、删除等RDS数据库中数据的功能,具体文件如下
在写代码之前我们需要在pro文件中增加SQL调用,即在第一行后写入sql就行了
如果你的QT无法运行MySQL数据库,则需要下载好mysql的驱动文件,将mysql驱动的静态库和动态库放在QT编译器的bin、include、lib目录下,以及在plugins中设置好sqldrivers,将*.lib、*.dll全放进去,具体参考链接:QT连接Mysql数据库(详细成功版)_程序有序的博客-CSDN博客,我当初好像就是看到这篇搭建的MySQL环境。
1.登陆界面的实现,我这里是直接拖拽控件到ui界面中,设置了两个个Button控件,实现了登陆和退出功能,账号密码在.cpp文件中自行设置,若不符则报出MessageBox的提示框。主要代码如下:
void Dlg_Login::on_btn_login_clicked()
{
if (ui->le_user->text() == tr("root") && ui->le_password->text() == tr("123456"))
{
setResult(1);
hide();//隐藏登陆界面
}
else
{
QMessageBox::warning(this, tr("错误!"), tr("账号或密码错误,请检查账号密码!"), QMessageBox::Yes);
}
}
void Dlg_Login::on_btn_exit_clicked()
{
setResult(0);
hide();//隐藏登陆界面
}
这里的背景图片我是直接进入ui界面,右键更改样式表,设置自己所需设置的图片(图片添加到同级目录下即可),然后我们可以将密码输入框设置为不显示字体,点击密码的LineEdit控件,在右下角搜索框搜索echoMode设置为password即可
关于设置应用程序图片我这里有个简单的方法,当然首先添加图片你还是得创建一个Qt Resource File文件,把图片添加到这个文件夹里,然后直接在pro文件中写入RC_ICONS = xxx.ico就可以了,这个应用程序的图标必须是ico的格式,我这里有个免费图片转格式的链接:JPG转ICO - 免费在线将JPG文件转换成ICO
2.在我们输入账号密码之后,我设置的是一个QStackedWidget控件设置主窗口,实现多个页面的切换,这里我们需要包含到其他几个ui窗口的头文件,以便于进入该窗口,同时调用其他函数的实例
这里我写了一个窗口菜单的函数,主要代码如下:
void cell_main::dealMenu()
{
auto str= sender()->objectName();
do{
if("btn_time" == str)
{
ui->stackedWidget->setCurrentIndex(0);
break;
}
if("btn_AllData" == str)
{
ui->stackedWidget->setCurrentIndex(1);
break;
}
if("btn_SoilHumidity" == str)
{
ui->stackedWidget->setCurrentIndex(2);
break;
}
if("btn_Temperature" == str)
{
ui->stackedWidget->setCurrentIndex(3);
break;
}
}while(false);
}
这样我们就可以在几个窗口之间来回跳转了,效果如下:
3.这里进去的主页面是获取当地时间以及最新的RDS数据库中的数据,关于获取时间只需要包含关于时间函数QDateTime,和定时器QTimer就可以了,关键代码如下:
void Cell_timeDate::timerUpdate()
{
QDateTime time = QDateTime::currentDateTime();
QString str = time.toString("yyyy-MM-dd \nhh:mm:ss dddd");
ui->label_time_01->setText(str);
}
这是我主窗口所用到的几个控件,实时时间直接装在Lable就可以了
然后就是要在QT中调用我们的RDS云数据库了,这里我们将数据库中最新的数据 显示在主窗口的Lable上,连接数据库的代码如下:
db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName("xxx");//关键步骤/*进入某数据库*/
db.setHostName("xxxxx.com");//连接地址
db.setUserName("xxx");//数据库账户
db.setPassword("xxxxxx");//密码
QSqlQuery query(db);
db.open();//关键步骤 /*打开连接*/
这里的db是我在.h文件中申明的
然后就是查询当前最新数据,说白了就是SQL语言中的查询,主要代码如下:
void Cell_timeDate::on_pushButton_clicked()
{
QSqlQuery query;
query.exec("select * from xxx;");//需要查询的表名
while (query.next()) {
int id = query.value("id").toInt();
int temperature = query.value("temperature").toInt();
int Humidity = query.value("Humidity").toInt();
int soilHumidity = query.value("soilHumidity").toInt();
int LightLux = query.value("LightLux").toInt();
int Rain = query.value("Rain").toInt();
int WaterOutletSwitch = query.value("WaterOutletSwitch").toInt();
ui->label_temp->setNum(temperature);
ui->label_humi->setNum(Humidity);
ui->label_temp_2->setNum(soilHumidity);
ui->label_linu->setNum(LightLux);
ui->label_rain->setNum(Rain);
ui->label_open->setNum(WaterOutletSwitch);
}
}
4.对于数据的管理我设置了查询全部数据、搜索数据、增加数据、情况全部数据、删除数据以及id重置的功能,这里我仅写一下全部数据管理的文件,还剩下的两个文件的用法基本本该文件包含。
如图这是我ui上的控件:
对于LineEdit框的颜色我们可以右键组件,改变样式表,修改background-color: rgb(x, x, x);中的x调整颜色,x范围为0~255。
首先我们还是要写一下要访问的数据库:
Cell_AllDate::Cell_AllDate(QWidget *parent) :
QWidget(parent),
ui(new Ui::Cell_AllDate)
{
ui->setupUi(this);
db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName("wlwjs_11");//关键步骤/*进入某数据库*/
db.setHostName("rm-cn-x0r3cdapw000aw5o.rwlb.rds.aliyuncs.com");//连接地址
db.setUserName("zzy");//数据库账户
db.setPassword("leotauiu0516A");//密码
QSqlQuery query(db);
db.open();//关键步骤 /*打开连接*/
}
对于数据的显示,我设置了一个QListWidget列表框,然后创建了一个窗口列表,在我查询全部数据的时候调用这个列表,我这里修改对象名为itemfrom
在列表的cpp文件中我设置了一个函数:
void itemFrom::setvalue(int id, int temperature, int Humidity, int soilHumidity,int LightLux,int Rain,int WaterOutletSwitch)
{
ui->id_lineEdit->setText(QString::number(id));
ui->EnvironmentTemperature_lineEdit->setText(QString::number(temperature));
ui->EnvironmentHumidity_lineEdit->setText(QString::number(Humidity));
ui->SoilMoisture_lineEdit->setText(QString::number(soilHumidity));
ui->LightLux_lineEdit->setText(QString::number(LightLux));
ui->Rain_lineEdit->setText(QString::number(Rain));
ui->WaterOutletSwitch_lineEdit->setText(QString::number(WaterOutletSwitch));
}
然后我们可以在查询全部数据的时候将数据汇入这个函数中,最后再以添加item的形式添加到QListWidget列表框中。
具体查询全部数据代码如下:
void Cell_AllDate::on_on_selectBtn_clicked()
{
//【1】查询数据库中数据表信息输出到控制台里
ui->listWidget->clear();//查询数据前清空列表内容
QSqlQuery query;
query.exec("select * from xxxxx;");
int p = 1;
int q = 0;
while (query.next()) {//只要数据表中还有数据
int id = query.value("id").toInt();
int temperature = query.value("temperature").toInt();
int Humidity = query.value("Humidity").toInt();
int soilHumidity = query.value("soilHumidity").toInt();
int LightLux = query.value("LightLux").toInt();
int Rain = query.value("Rain").toInt();
int WaterOutletSwitch = query.value("WaterOutletSwitch").toInt();
if((soilHumidity <= 25) && p){
QMessageBox::warning(this,"预警","土壤湿度过低请及时浇水!");
p = 0;
}
if((temperature >= 42) && q){
QMessageBox::warning(this,"预警","环境温度过高请及时浇水!");
q = 0;
}
//【2】查询数据库中数据表信息输出到ui控件上
//1.创建一个列表条目
itemFrom * hitoitemFrom = new itemFrom;
hitoitemFrom->setvalue(id,temperature,Humidity,soilHumidity,LightLux,Rain,WaterOutletSwitch);
QListWidgetItem *item =new QListWidgetItem;
item->setSizeHint(QSize(830,78));
ui->listWidget->addItem(item);
ui->listWidget->setItemWidget(item,hitoitemFrom);
}
}
这里我查询时设置了一个预警窗口,当温度过高或者土壤湿度过低时都会预警。
其他的添加数据、删除数据、修改数据、清空数据、以及id重置都是关于SQL语言写的,我这里就直接上代码了
添加数据:
void Cell_AllDate::on_on_addBtn_clicked()
{
int temperature = ui->Temperature_lineEdit->text().toInt();
int Humidity = ui->Humidity_lineEdit->text().toInt();
int soilHumidity = ui->SoilMoisture_lineEdit->text().toInt();
int LightLux = ui->LightLux_lineEdit->text().toInt();
int Rain = ui->Rain_lineEdit->text().toInt();
int WateBtn =ui->WaterOutletSwitch_lineEdit->text().toInt();
QSqlQuery query;
QString sqlInsert = QString("insert into wlwjs_00(temperature,Humidity,soilHumidity,LightLux,Rain,WaterOutletSwitch) "
"values(%1,%2,%3,%4,%5,%6);").arg(temperature).arg(Humidity).arg(soilHumidity).arg(LightLux).arg(Rain).arg(WateBtn);
if(!query.exec(sqlInsert)){
QMessageBox::warning(this,"警告","添加数据失败");
}else {
QMessageBox::information(this,"提示","添加数据成功");
}
}
删除数据:
void Cell_AllDate::on_on_delectBtn_clicked()
{
QSqlQuery query;
QString id = ui->id_lineEdit->text();
QString delect = QString("delete from wlwjs_00 where id = %1").arg(id.toInt());
if(!query.exec(delect)){
QMessageBox::warning(this,"警告","删除数据失败");
}
else {
QMessageBox::information(this,"提示","删除数据成功");
}
}
清空数据:
void Cell_AllDate::on_on_lookup_clicked()
{
ui->listWidget->clear();//查询数据前清空列表内容
QSqlQuery query;
query.exec("select * from xxx;");
while (query.next()) {
int id = query.value("id").toInt();
int temperature = query.value("temperature").toInt();
int Humidity = query.value("Humidity").toInt();
int soilHumidity = query.value("soilHumidity").toInt();
int LightLux = query.value("LightLux").toInt();
int Rain = query.value("Rain").toInt();
int WaterOutletSwitch = query.value("WaterOutletSwitch").toInt();
if(ui->lookup_Edit->text().toFloat()>= soilHumidity){
//【2】查询数据库中数据表信息输出到ui控件上
//1.创建一个列表条目
itemFrom * valueitemFrom01 = new itemFrom;
valueitemFrom01->setvalue(id,temperature,Humidity,soilHumidity,LightLux,Rain,WaterOutletSwitch);
QListWidgetItem *item =new QListWidgetItem;
item->setSizeHint(QSize(830,78));
ui->listWidget->addItem(item);
ui->listWidget->setItemWidget(item,valueitemFrom01);
}
}
}
id重置:
void Cell_AllDate::on_res_Btn_clicked()
{
QSqlQuery query;
query.exec("alter table xxxx drop id;");//删除原来的主键值
query.exec("alter table xxxx add id int not null primary key auto_increment first;");//重新从1开始编号,并自增
}
void Cell_AllDate::on_on_EmptyBtn_clicked()
{
QSqlQuery query;
query.exec("truncate table wlwjs_00;");//删除原来的主键值
on_on_selectBtn_clicked();
}
这里展示下成果图:
三、关于Qt打包发送给其他用户使用该应用
首先我们需要打开Release编译模式:
然后找到生成的.exe文件
这里我们复制该应用程序,在桌面创建一个文件夹粘贴进去,随后win键搜索Qt控制台(电脑没有的话cmd控制台也可以,但需要把编译器的bin地址目录放在系统Path变量中),然后进入该文件夹下输入windeployqt xxx.exe将该程序对应的库添加到文件夹中,打包后添加的库如图:但是这个打包BT的就是并没有把我们的MySQL的驱动给打包过去,导致别人点开这个程序的时候涉及到数据的操作没有效果,这里我们需要将
1.libcrypto-1_1-x64.dll 2.libmysql.dll 3.libmysql.lib 4.libssl-1_1-x64.dll
随后在当前目录下创建一个plugins的目录,将qsqlmysql.dll添加进去
然后就可以打包发给其他用户正常使用啦!!!!!
这里我把最后涉及到的驱动放到网盘里,需要的人可以自行下载。
链接:https://pan.baidu.com/s/1UEHggBkYvUQDfwVG7CZB4w
提取码:leot
关于整套源码可以私信我我直接发你。