接触QT三年有余,期间因为工作需要断断续续学习过,2010年开始接触,当时好像是4.7版本,现在都已经到5.2版本了,更新真快,前阵子安装了下5.2版本,还是有很多变化的,不过感觉好像编译速度慢了很多,而且编译出来的可执行文件需要附带的DLL多了很多,感觉不爽,所以还是回到了4.7版本的开发,一个重要原因是现在大部分的开发板都移植好了4.7版本的运行库,可以方便的将WINDOWS程序移植到嵌入式linux下,5.0以上的版本貌似还没有哪家公司移植到了嵌入式linux上,估计有很多个人已经移植过。

QT也是一套C++框架,和VC++类似,和VC一样有个好处就是编译好的可执行程序,一般不需要安装什么框架的,附带DLL就行,内存要求非常低,这个很适合在嵌入式设备上面跑。之前用.NET做了三年的项目开发,每当在客户电脑上面安装一个几十兆的框架时,甚是不爽,经过了三年多的比较,最终选用QT作为以后的开发首选。经过EnigmaVirtualBox7.0.exe这个工具的压缩,还可以将可执行程序封包到一个EXE,屡试不爽!

之前一直在网络上面参考别人的代码,现在也该拿出自己的一些东西来分享分享了,这个系列将会粗略的讲解一些工具和小项目的开发过程及遇到的难题和解决办法,将会全部开源并提供下载地址,其实这个开发之旅是有过一定的基础的,所以基础的东西可能都是一笔带过。需要读者自己下载源码去研究,阅读别人的代码还是可以学习到很多东西的,就算是一个循环一个简单的文本存储,都会有一些技巧在里面,我开源出来的代码不一定都是没问题的,但是确实是经过自己几经雕琢封装好的,还是有一定借鉴价值哦!

用DS7400主机调试工具作为开发之旅的第一个项目,是因为之前用.NET写过,而且陆续有很多人看到过加过我QQ咨询过,自己也用在多个商业项目中,所以把这个单独提取出来发布出来,直接一个可执行程序无需任何框架就可以在windows98以上的电脑上跑,甚是爽!

项目名称:DS7400主机调试工具

开发环境:WIN7+QT4.7+QT CREATOR2.8+MINGW

技术实现:通过串口与DS7400报警主机通信,解析协议并作出处理

实现功能:主机布防撤防,防区故障断开旁路报警等

运行截图:

粗略步骤:

第一步:准备QT串口通信文件,QT4.7没有包含串口通信的相关类,到了5.1后面的版本才有,所以需要引入第三方的串口类,毫无疑问在QT中网上用的绝大部分都是这几个文件win_qextserialport.h,win_qextserialport.cpp,qextserialbase.h,qextserialbase.cpp,源码都已经提供,在对应项目中右键选择添加现有文件,选择这四个文件。

第二步:添加主界面,放置好对应控件,并命名。

第三步:自定义报警按钮控件,就是一旦布防撤防报警等状态出现的时候,对应颜色改变,这里我是用的贴图,有状态改变时,对应背景图改变,源码里的mybuttonalarm类还封装了三种报警按钮样式。核心代码很简单如下:

void myButtonAlarm::paintEvent(QPaintEvent *event)

{

    QPainter painter(this);

    QPixmap pixMap(this->CurrentImage);

    QFont font("Arial",10,QFont::Bold,true);

    QRectF rect(0,0,32,47);

    painter.setFont(font);

    painter.drawPixmap(0,0,32,32,pixMap);

    painter.drawText(rect,Qt::AlignBottom | Qt::AlignCenter,this->defenceID);

}

就是将对应图片和文字画上去。

第四步:封装DS7400主机通信类。

博世DS7400主机通信协议格式

格式依次为: 85 18 09 6B(示例)

第一位为标识,第二位为事件类型(0E布防0D撤防07报警等),第三位为防区号(对应16进制转换成10进制加一,例如09转成10进制为09,再加一是10,对应010防区),第四位是校验码

布防:85 0E 00 74

报警主机:123  主机防区/分区:1  报警主机消息:AREA_ARM_DS7400

撤防:85 0D 00 77

报警主机:123  主机防区/分区:1  报警主机消息:AREA_DISARM_DS7400

取消报警:85 0C 00 76

报警主机:123  主机防区/分区:1  报警主机消息:CANCEL_ALARM_DS7400

正常:A0 02 5D

接收到DS7400主机状态报告

09防区:撤防状态与布防状态

正常断开:85 18 08 6A

报警主机:123  主机防区/分区:9  报警主机消息:ZONE_OPEN_DS7400

正常连上:85 19 08 6B

报警主机:123  主机防区/分区:9  报警主机消息:ZONE_RESTORE_DS7400

报警断开:85 18 08 6A     85 07 08 75

报警主机:123  主机防区/分区:9  报警主机消息:ZONE_OPEN_DS7400

报警主机:123  主机防区/分区:9  报警主机消息:BURGLAR_ZONE_ALARM_DS7400

报警连上:85 19 08 6B    85 11 08 63

报警主机:123  主机防区/分区:9  报警主机消息:ZONE_RESTORE_DS7400

报警主机:123  主机防区/分区:9  报警主机消息:ZONE_ALARM_RESTORE_DS7400

旁路:85 0F 08 7D

报警主机:123  主机防区/分区:9  报警主机消息:FORCED_BYPASS_DS7400

第五步:实例化串口类,通信。

void frmMain::on_btnOpen_clicked()

{

    if (ui->btnOpen->text()=="打开串口")

    {

        QString port=ui->cboxPortName->currentText();

        DS7400->SetHostID("");

        DS7400->SetHostName("");

        DS7400->SetHostType("");

        DS7400->SetHostAddr(1);

        DS7400->SetHostConnectType("COM");

        DS7400->SetHostConnectValue(port);

        if (DS7400->Open())

        {

            connect(DS7400,SIGNAL(Connect(QString)),this,SLOT(Connect()));

            connect(DS7400,SIGNAL(DisConnect(QString)),this,SLOT(DisConnect()));

            connect(DS7400,SIGNAL(BuFang(QString,int)),this,SLOT(BuFang()));

            connect(DS7400,SIGNAL(CheFang(QString,int)),this,SLOT(CheFang()));

            connect(DS7400,SIGNAL(BaoJing(QString,QString)),this,SLOT(BaoJing(QString,QString)));

            connect(DS7400,SIGNAL(DuanKai(QString,QString)),this,SLOT(DuanKai(QString,QString)));

            connect(DS7400,SIGNAL(GuZhang(QString,QString)),this,SLOT(GuZhang(QString,QString)));

            connect(DS7400,SIGNAL(HuiFu(QString,QString)),this,SLOT(HuiFu(QString,QString)));

            connect(DS7400,SIGNAL(PangLu(QString,QString)),this,SLOT(PangLu(QString,QString)));

            ui->btnOpen->setText("关闭串口");

            this->AddMessage("打开串口成功");

        }

        else

        {

            this->AddMessage("打开串口失败");

        }

    }

    else

    {

        DS7400->Close();

        disconnect(DS7400,SIGNAL(Connect(QString)),this,SLOT(Connect()));

        disconnect(DS7400,SIGNAL(DisConnect(QString)),this,SLOT(DisConnect()));

        disconnect(DS7400,SIGNAL(BuFang(QString,int)),this,SLOT(BuFang()));

        disconnect(DS7400,SIGNAL(CheFang(QString,int)),this,SLOT(CheFang()));

        disconnect(DS7400,SIGNAL(BaoJing(QString,QString)),this,SLOT(BaoJing(QString,QString)));

        disconnect(DS7400,SIGNAL(DuanKai(QString,QString)),this,SLOT(DuanKai(QString,QString)));

        disconnect(DS7400,SIGNAL(GuZhang(QString,QString)),this,SLOT(GuZhang(QString,QString)));

        disconnect(DS7400,SIGNAL(HuiFu(QString,QString)),this,SLOT(HuiFu(QString,QString)));

        disconnect(DS7400,SIGNAL(PangLu(QString,QString)),this,SLOT(PangLu(QString,QString)));

        ui->btnOpen->setText("打开串口");

        this->AddMessage("关闭串口成功");

    }

}

第六步:实现具体槽函数

void frmMain::AddMessage(QString Message)

{

    ui->txtData->append(QString("收到消息:%1  时间:%2")

                        .arg(Message)

                        .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")));

}

void frmMain::Connect()

{

    this->AddMessage("主机上线");

}

void frmMain::DisConnect()

{

    this->AddMessage("主机下线");

}

void frmMain::BuFang()

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        btn->SetDefenceStatus(DefenceStatusBuFang);

    }

    this->AddMessage("主机布防");

}

void frmMain::CheFang()

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        btn->SetDefenceStatus(DefenceStatusCheFang);

    }

    this->AddMessage("主机撤防");

}

void frmMain::BaoJing()

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        btn->SetDefenceStatus(DefenceStatusBaoJing);

    }

    this->AddMessage("主机报警");

}

void frmMain::PangLu()

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        btn->SetDefenceStatus(DefenceStatusPangLu);

    }

    this->AddMessage("主机旁路");

}

void frmMain::DuanKai()

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        btn->SetDefenceStatus(DefenceStatusDuanKai);

    }

    this->AddMessage("主机断开");

}

void frmMain::GuZhang()

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        btn->SetDefenceStatus(DefenceStatusGuZhang);

    }

    this->AddMessage("主机故障");

}

void frmMain::BaoJing(QString hostID, QString defenceID)

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        if (btn->GetDefenceID()==defenceID)

        {

            btn->SetDefenceStatus(DefenceStatusBaoJing);

            break;

        }

    }

    this->AddMessage(QString("%1防区报警").arg(defenceID));

}

void frmMain::DuanKai(QString hostID, QString defenceID)

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        if (btn->GetDefenceID()==defenceID)

        {

            btn->SetDefenceStatus(DefenceStatusDuanKai);

            break;

        }

    }

    this->AddMessage(QString("%1防区断开").arg(defenceID));

}

void frmMain::GuZhang(QString hostID, QString defenceID)

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        if (btn->GetDefenceID()==defenceID)

        {

            btn->SetDefenceStatus(DefenceStatusGuZhang);

            break;

        }

    }

    this->AddMessage(QString("%1防区故障").arg(defenceID));

}

void frmMain::HuiFu(QString hostID, QString defenceID)

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        if (btn->GetDefenceID()==defenceID)

        {

            btn->SetDefenceStatus(DefenceStatusCheFang);

            break;

        }

    }

    this->AddMessage(QString("%1防区恢复").arg(defenceID));

}

void frmMain::PangLu(QString hostID, QString defenceID)

{

    int count=ui->gboxMain->children().count();

    for (int i=0;i<count;i++)

    {

        myButtonAlarm *btn=(myButtonAlarm *)ui->gboxMain->children().at(i);

        if (btn->GetDefenceID()==defenceID)

        {

            btn->SetDefenceStatus(DefenceStatusPangLu);

            break;

        }

    }

    this->AddMessage(QString("%1防区旁路").arg(defenceID));

}

这里采用QString(“”)而不是tr(“”) ,之前看过某人说过要慎用tr,确实,tr是用来国际化的,如果需要字符串拼接,可以用QString(“%1”).arg(“”)这种占位符形式,很方便。和.NET里面的string.Forrmat用法一样。

博客园上传资源大小有限,所以放到了CSDN上面,如有不便还请见谅,可以向私人索取!

可执行文件下载地址:http://download.csdn.net/detail/feiyangqingyun/6708143

源码猛点这里:http://download.csdn.net/detail/feiyangqingyun/6708149

QT开发之旅一DS7400主机调试工具的更多相关文章

  1. QT开发之旅三串口设备调试工具

    这里首先说明一下,这个为什么叫串口设备调试工具而不是串口调试工具,是因为这个工具比网络上的串口调试工具多出了一些真实需要的用来调试设备的功能,首先一点就是大部分的串口调试工具收到数据都是立即返回,这样 ...

  2. QT开发之旅二TCP调试工具

    TCP调试工具顾名思义用来调试TCP通信的,网上这样的工具N多,之前用.NET写过一个,无奈在XP下还要安装个.NET框架才能运行,索性这次用QT重写,发现QT写TCP通信比.NET还要便捷一些,运行 ...

  3. QT开发之旅四邮件发送工具

    终于有了一个晚上安静的写写程序,最近一直忙着公司商务上的事情,一直想用QT实现一个调用最底层socket通信来实现的邮件发送程序,以前用C#写过,微软都封装好的,不知道底层是如何实现的,只知道调用方法 ...

  4. QT开发之旅-Udp聊天室编程

    一.概要设计 登录对话框(继承自QDialog类)进行用户登录查询数据库用户是否存在,注册插入数据到用户表.用户表字段: (chatid int primary key, passwd varchar ...

  5. VS2008下QT开发环境搭建(转)

    原博文地址:http://blog.csdn.net/sunnyboycao/article/details/6364444 VS2008集成QT4.7.2环境搭建 作者:jimmy 日期:2011- ...

  6. ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  7. QT开发环境搭建

    一.Qt发展史 1991年,由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架: 2008年,Nokia从Trolltech公司收购Qt, 并增加LGPL的授权模式: 2011年,Digia从N ...

  8. 嵌入式Qt开发环境的搭建详解

    一.嵌入式Qt开发环境的搭建前奏 1.下载arm-linux-gcc-4.4.3-20100728.tar.gz 2.下载qt-everywhere-opensource-src-4.8.5.tar. ...

  9. QT开发环境的建立以及QTE4.6.3、tslib1.4的移植过程

    1.首先是建立Linux开发环境1.1.在windowsXP下安装博创公司提供的虚拟机软件VMware Workstation,版本为VMware-workstation-full-7.0.1-227 ...

随机推荐

  1. C# 结构体 struct

    C# 结构体 struct C#中结构类型和类类型在语法上非常相似,他们都是一种数据结构,都可以包括数据成员和方法成员. 结构和类的区别: 1.结构是值类型,它在栈中分配空间:而类是引用类型,它在堆中 ...

  2. 每天一个linux命令:pwd命令

    Linux中用 pwd 命令来查看”当前工作目录“的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置. ...

  3. sublime3 docblocker插件定制自己的注释,配置步骤

    DocBlockr很好用,不仅仅可以自动生成注释,还可以手动编辑注释的格式. 安装方法:   Cmd+Shift+P -> Install Package -> docblockr  wi ...

  4. DataTable内容导出为CSV文件

    CSVHelper.cs内容: using System; using System.Collections.Generic; using System.Linq; using System.Text ...

  5. (第3篇)HDFS是什么?HDFS适合做什么?我们应该怎样操作HDFS系统?

    摘要: 这篇文章会详细介绍HDFS是什么,HDFS的作用,适合和不适合的场景,我们该如何操作HDFS?   HDFS文件系统 Hadoop 附带了一个名为 HDFS(Hadoop分布式文件系统)的分布 ...

  6. nvm安装node和npm,个人踩坑记录

    我采用nvm-setup安装windows版本的nvm nvm安装node出现的问题: 1.node成功了,npm没成功 解决:在nvm 安装了node之后,输入npm找不到该命令,当时安装报错如下: ...

  7. synchronized关键字的用法总结

    synchronized关键字主要有以下这3种用法: 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 修饰代 ...

  8. CentOS6.8手动安装MySQL5.6

    众所周知,mysql5.7推出后有很多没有填好的坑,对于老的系统和项目兼容性也存在问题,所以现在普遍的web项目还是应该跑在centos6.8+mysql5.6的环境之下,今天主要说一下mysql5. ...

  9. linux中如何对一个文件的内容进行处理,文件中每行有多个字段的值,中间用空格分隔开?

    需求描述: 今天在帮同事看个需求,将操作系统上的文件进行修改名字,改为特定的名字,所以呢,就先把这些原名字及对应的新名字关系放到了一个文本中,对于这个文本执行循环. 文件格式如下: .00000005 ...

  10. Oauth2.0(二):开放平台

    上一节说到Oauth2.0 的交互模型.模型涉及到三方:资源拥有者.客户端.服务提供方.其中,服务提供方包含两个角色:鉴权服务器和资源服务器.鉴权服务器负责对用户进行认证,并授权给客户端权限.认证这一 ...