一、前言

地图管理的主要功能是将系统中的地图文件做添加和删除,支持常见的jpg、png、bmp等格式图片,图片分辨率建议小于1080P,最好是和目标客户端电脑分辨率一致,这样在拉伸缩放的时候会比较清晰。图片建议使用鸟瞰图,有3D立体感,类似于那些卖房子售楼部的3D模型,不懂的人还以为是什么高级的技术呢,其实就是一张图片。在做很多需要地图模块的系统的过程中,总结出了几个经验,如下:

第一个是如何快速的加载图片,记得以前有个Qt大神jason写过类似的文章,看过之后才发现,原来和我的做法完全一致,核心就是系统启动的时候将图片文件加载到内存,用QList存储起来,需要的时候根据名称标识符取出对应的图片即可,这样有多个好处,尤其是嵌入式linux上,资源很紧缺,绝大部分时候读写数据的瓶颈在IO,频繁的IO读写会大大降低性能,如果只是在程序启动的时候读写一次放到内存,用到的时候内存访问,那速度真的是瞬间,大部分初学者可能首先使用的是文件路径的方式加载图片,每次都用这种方式加载,当图片很大的时候,切换图片的时候,电脑配置好那没事,那种嵌入式linux的板子,就很卡了,相当于每次都去做了IO读取。

第二个是图片名称的管理,一开始做的是取的文件名称加上拓展名直接显示在qlistwidget的节点的text,后面发现有些时候用户会导入一张名字很长的图片文件,此时整个图片列表看起来歪歪扭扭,都被这个很长的名字撑开了,于是加上了过滤,比如超过20个字符,取前面10个和后面10个字符显示,中间加上省略号,最好还可以省去拓展名,毕竟用户从来不关心拓展名,他只知道从这个图片的缩略图单击查看切换,QListWidget的节点有个setIcon函数负责将图片转成缩略图显示,setText负责显示名称,setData负责设置自定义的数据,一般设置Qt::UserRole角色的数据,用来存放图片文件的标识符,这样在单击切换的时候取这个标识符取队列中找到对应的图片显示即可,快速完美。

皮肤开源:https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo

文件名称:styledemo

体验地址:https://gitee.com/feiyangqingyun/QWidgetExe https://github.com/feiyangqingyun/QWidgetExe

文件名称:bin_sams.zip

二、功能特点

  1. 采集数据端口,支持串口端口+网络端口,串口支持自由设置串口号+波特率,网络支持自由设置IP地址+通讯端口,每个端口支持采集周期,默认1秒钟一个地址,支持设置通讯超时次数,默认3次,支持最大重连时间,用于重新读取离线的设备。
  2. 控制器信息,能够添加控制器名称,选择控制器地址+控制器型号,设置该控制器下面的探测器数量。
  3. 探测器信息,能够添加位号,可自由选择探测器型号,气体种类,气体符号,高报值,低报值,缓冲值,清零值,是否启用,报警声音,背景地图,存储周期,数值换算小数点位数,报警延时时间,报警的类型(HH,LL,HL)等。
  4. 控制器型号+探测器型号+气体种类+气体符号,均可自由配置。
  5. 地图支持导入和删除,所有的探测器对应地图位置可自由拖动保存。
  6. 端口信息+控制器信息+探测器信息,支持导入导出+导出到excel+打印。
  7. 运行记录+报警记录+用户记录,支持多条件组合查询,比如时间段+控制器+探测器等,所有记录支持导出到excel+打印。
  8. 导出到excel的记录支持所有excel+wps等表格文件版本,不依赖excel等软件。
  9. 可删除指定时间范围内的数据,支持自动清理早期数据,设置最大保存记录数。
  10. 支持报警短信转发,支持多个接收手机号码,可设定发送间隔,比如即时发送或者6个小时发送一次所有的报警信息,短信内容过长,自动拆分多条短信。
  11. 支持报警邮件转发,支持多个接收邮箱,可设定发送间隔,比如即时发送或者6个小时发送一次所有的报警信息,支持附件发送。
  12. 高报颜色+低报颜色+正常颜色+0值颜色+曲线背景+曲线颜色等,都可以自由选择。
  13. 软件的中文标题+英文标题+logo路径+版权所有都可以自由设置。
  14. 提供开关设置开机运行+报警声音+自动登录+记住密码等。
  15. 报警声音可设置播放次数,界面提供17种皮肤文件选择。
  16. 支持云端数据同步,可设置云端数据库的信息,比如数据库名称,用户名+密码等。
  17. 支持网络转发和网络接收,网络接收开启后,软件从udp接收数据进行解析。网络转发支持多个目标IP,这样就实现了本地采集的软件,自由将数据转到客户端,随时查看探测器数据。
  18. 自动记住用户最后停留的界面+其他信息,重启后自动应用。
  19. 报警自动切换到对应的地图,探测器按钮闪烁。
  20. 双击探测器图标,可以进行回控。
  21. 支持用户权限管理,管理员+操作员两大类,用户登录+用户退出,可以记住密码和自动登录,超过三次报错提示并关闭程序。
  22. 支持四种监控模式,设备面板监控+地图监控+表格数据监控+曲线数据监控,可自由切换,四种同步应用。
  23. 支持报警继电器联动,一个位号可以跨串口联动多个模块和继电器号,支持多对多。
  24. 本地数据存储支持sqlite+mysql,支持远程数据同步到云端数据库。自动重连。
  25. 本地设备采集到的数据实时上传到云端,以便手机APP或者web等其他方式提取。
  26. 支持两种数据源,一种是串口和网络通过协议采集设备数据,一种是数据库采集。数据库采集模式可以作为通用的系统使用。
  27. 自带设备模拟工具,支持16个设备数据模拟,同时还带数据库数据模拟,以便在没有设备的时候测试数据。
  28. 默认通信协议采用modbus协议,后期增加mqtt等物联网协议的支持,做成通用系统。
  29. 支持所有windows操作系统+linux操作系统和其他操作系统。

三、效果图

四、核心代码

#include "frmconfigmap.h"
#include "ui_frmconfigmap.h"
#include "quiwidget.h"
#include "api.h"
#include "devicemap.h"
#include "devicehelper.h" frmConfigMap::frmConfigMap(QWidget *parent) : QWidget(parent), ui(new Ui::frmConfigMap)
{
ui->setupUi(this);
this->initForm();
} frmConfigMap::~frmConfigMap()
{
delete ui;
} void frmConfigMap::initForm()
{
ui->navTitle->setText("地图列表");
ui->navTitle->setLeftIcon(0xf0e8);
ui->navTitle->setRightIcon5(0xf1f8);
ui->widgetRight->setFixedWidth(App::RightWidth); DeviceHelper::initDeviceMap(ui->listWidget); if (ui->listWidget->count() > 0) {
ui->listWidget->setCurrentRow(0);
on_listWidget_pressed();
}
} void frmConfigMap::on_listWidget_pressed()
{
int row = ui->listWidget->currentRow();
if (row < 0) {
return;
} DeviceHelper::initDeviceMapCurrent(ui->labMap, DBData::MapNames.at(row));
} void frmConfigMap::on_btnInput_clicked()
{
QString defaultDir = API::getDefaultDir();
QString fileName = API::getFileName("Images (*.png *.bmp *.jpg *.gif *.jpeg)", defaultDir); if (fileName.length() > 0) {
QFileInfo f(fileName);
QString imageName = f.fileName(); //判断文件是否过大,暂定1MB,过大则弹出提示并不加载
if (f.size() > 1 * 1024 * 1024) {
QUIHelper::showMessageBoxError("图片文件过大,请控制在1MB以内,谢谢!", 3);
return;
} //如果导入的图片有乱码则自动重命名
if (imageName.contains("?") || imageName.length() > 10) {
imageName = QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss.") + f.suffix();
} QString fullName = QString("%1/%2").arg(DBData::MapPath).arg(imageName); //2018-10-18 增加大像素图片过滤,等比例缩放图片
QImage img(fileName);
if (img.width() > 1920 || img.height() > 1080) {
img = img.scaled(App::MapWidth, App::MapHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
img.save(fullName);
} else {
QUIHelper::copyFile(fileName, fullName);
} DBData::MapNames.append(imageName);
DeviceMap::Instance()->appendMapPix(imageName);
DeviceHelper::initDeviceMap(ui->listWidget);
DeviceHelper::initDeviceMap(); //自动切换到当前导入的地图
ui->listWidget->setCurrentRow(ui->listWidget->count() - 1);
on_listWidget_pressed();
emit changeMap();
}
} void frmConfigMap::on_btnDelete_clicked()
{
int row = ui->listWidget->currentRow();
if (row < 0) {
return;
} if (QUIHelper::showMessageBoxQuestion("确定要删除当前选中地图文件吗?") == QMessageBox::Yes) {
QString imageName = DBData::MapNames.at(row);
QString fileName = QString("%1/%2").arg(DBData::MapPath).arg(imageName);
QFile f(fileName);
f.remove(); DBData::MapNames.removeOne(imageName);
DeviceMap::Instance()->removeMapPix(imageName);
DeviceHelper::initDeviceMap(ui->listWidget);
DeviceHelper::initDeviceMap(); //如果还有地图则自动切换到第一张地图,没有则清空显示
if (ui->listWidget->count() > 0) {
ui->listWidget->setCurrentRow(0);
on_listWidget_pressed();
} else {
ui->labMap->clear();
} emit changeMap();
}
}

Qt编写气体安全管理系统24-地图管理的更多相关文章

  1. Qt编写气体安全管理系统19-端口管理

    一.前言 所有设备的信息配置,主要就三大点:端口管理.控制器管理.探测器管理,整个硬件系统的架构是有多个不同的通信端口(主要是串口和网络),每个通信端口下面挂着多个控制器(每个控制器都有唯一的地址,从 ...

  2. Qt编写气体安全管理系统17-记录清理

    一.前言 记录清理功能,在数据量很小的情况下,用不上,如果数据量大了的话,长年累月存储的,那就显得极其重要了,好比视频监控中的NVR存储的视频一样,一般来说存储个60天,那超过60天怎办呢,擦除早期的 ...

  3. Qt编写气体安全管理系统10-数据导出

    一.前言 数据导出一般指导出到excel表格,可能有部分用户还需要导出到pdf,因为pdf基本上不可编辑,防止用户重新编辑导出的数据,excel可能绝大部分用过电脑的人都知道,广为流行,主要就是微软的 ...

  4. Qt编写气体安全管理系统20-控制器管理

    一.前言 控制器管理,主要就是对控制器进行添加删除和修改,其中包括编号.端口名称.控制器名称.控制器地址.控制器型号.探测器数量这几个字段,端口名称表示当前控制器所属哪个端口,一个系统中可以有好多个端 ...

  5. Qt编写气体安全管理系统21-探测器管理

    一.前言 探测器在整个系统中是最核心的关键的硬件,终端节点硬件,安装有探测芯片装置,负责探测前端对应气体浓度,并记录值,等待控制器轮训数据回复,控制器信息表也是字段最多的,要存储位号.控制器名称.探测 ...

  6. Qt编写气体安全管理系统(界面超漂亮)

    自从把Qt样式表葵花宝典这个pdf文件看完以后,将所有的qss内容都轮了一遍,还写了个皮肤生成器工具,https://blog.csdn.net/feiyangqingyun/article/deta ...

  7. Qt编写气体安全管理系统18-数据库设置

    一.前言 作为一个管理系统,数据库肯定是不可或缺的,Qt内置的sqlite数据库已经是够用的,而且本人亲测数据量能支持亿级别,而不是像网上很多人说的千万级别,我模拟过一亿多条数据,依然能够很好的查询, ...

  8. Qt编写气体安全管理系统2-界面框架

    一.前言 整体框架包括两个部分,一部分是UI界面框架,比如一级二级导航菜单按钮整体布局等,一部分是项目框架,上一篇文章说的是项目框架,这一篇文章来说界面框架,Qt做界面非常快速和高效,尤其是提供了可视 ...

  9. Qt编写气体安全管理系统1-项目框架

    一.前言 说到项目框架,也叫代码框架,其实是非常重要的,随着编程经验的增加,相信每个程序员都会有一个自己的习惯的项目框架,这个东西跟建房子一样,先把架子搭好,然后挨个往里边填充内容,据说牛逼的架构师都 ...

随机推荐

  1. Vue当中的this

    10事件绑定 methods当中的this就是Vue实例对象vm var vm = new Vue({ el: '#app', data: { num: 0 }, // 注意点: 这里不要忘记加逗号 ...

  2. Python高级编程和异步IO并发编程(笔记)

    一.魔法函数 # 例子 class Company(object): def __init__(self, employee_list): self.employee = employee_list ...

  3. C# winform Panel 添加 滚动条

    Detailed discussion here. Try this instead for 'only' scrolling vertical.(auto scroll needs to be fa ...

  4. H3CNE学习1 课程简介

    一.认证对比 二.企业网架构

  5. Kibana 的安装(Windows版本)

    一.安装 安装条件 保证安装了JDK 保证安装node 保证安装了Elasticsearch 1.点击kibana官网下载  [kibana的版本和elasticsearch的版本和必须一致] 2.修 ...

  6. 43、内置函数及每日uv、销售额统计案例

    一.spark1.5内置函数 在Spark 1.5.x版本,增加了一系列内置函数到DataFrame API中,并且实现了code-generation的优化.与普通的函数不同,DataFrame的函 ...

  7. 洛谷P2751 工序安排Job Processing

    题目 任务调度贪心. 需要明确一点,任务调度贪心题,并不是简单地应用排序的贪心,而是动态的运用堆,使每次选择是都能保持局部最优,并更新状态使得下次更新答案可以取到正确的最小值. 这是A过程的解. 然后 ...

  8. Flower(规律+逆向思维)

    Flower: 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6486 题解: 逆向思维+规律 因为每次剪n-1,所以逆向就是控制n-1朵不变,每次增高1 ...

  9. realloc()函数

    原型:extern void *realloc(void *mem_address, unsigned int newsize); 参数: mem_address: 要改变内存大小的指针名 newsi ...

  10. docker 随笔记录

    .docker 固定网络ip地址,启动 Docker的时候,用 --network 参数,可以指定网络类型 eg:docker run -itd --name test1 --network brid ...