基于QT环境下,实现客户端红外采集人体向服务端通信。

一、本次测试目的

基于QT环境下STM32人体红外检测,实现客户端红外采集到信息向服务端通信。

二、功能

(1)、传入音乐,当服务端接收到信息时,打开音乐

(2)、在服务端上面显示图片,当接收到打开或者关闭信息时,切换图片

三、代码展示


【服务端】文件名称:untitledReceivingInformation


1、右键点击服务端文件夹,单击添加新文件。

2、在弹出的选择模板中选择Qt,选择Qt Resource File,单击Choose... 创建

3、输入添加新文件的名称 picture 单击下一步,单击完成。

4、因此项目文件untitledReceivingInformation路径下,出现资源文件路径,添加的新文件 picture.qrc 会自动生成到资源目录下面。

5、在picture.qrc 中单击添加列表,单击添加前缀,删除下方属性栏中前缀的内容。

【这里面的前缀是已经删除过原有的前缀】

6、点击添加列表,单击添加文件,会自动弹出存放untitledReceivingInformation文件的界面。因此我需要将图片保存到当前的文件夹。【以1.jpg为例】

头文件:widget.h

复制代码
 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 #include <QTcpServer>
 6 #include <QTcpSocket>
 7 #include <QHostAddress>
 8 #include <QMediaPlayer>
 9 #include <QPixmap>
10 
11 namespace Ui {
12 class Widget;
13 }
14 
15 class Widget : public QWidget
16 {
17     Q_OBJECT
18 
19 public:
20     explicit Widget(QWidget *parent = 0);
21     ~Widget();
22 private slots:
23     //写一个槽函数
24     //用于接收建立连接
25     void slotNewConn();
26 
27     //接收到信息后进行显示
28     void slotRecv();
29     //声音暂停按钮
30     void on_pushButton_clicked();
31     //手写槽,播放音乐
32     void openmusic();
33     //手写槽,关闭音乐
34     void closemusic();
35     //开灯的图片响应
36     void turn_on_the_light();
37     //关灯的图片响应
38     void close_on_the_light();
39 
40 private:
41     Ui::Widget *ui;
42     //声明server、socket指针变量
43     QTcpServer *server;
44     QTcpSocket *socket;
45 
46     QPixmap pix;
47     QMediaPlayer player;
48     int count;
49 };
50 
51 #endif // WIDGET_H

源文件:widget.cpp

复制代码
  1 #include "widget.h"
  2 #include "ui_widget.h"
  3 #include "QPixmap"
  4 #include "QDir"
  5 
  6 Widget::Widget(QWidget *parent) :
  7     QWidget(parent),
  8     ui(new Ui::Widget)
  9 {
 10     ui->setupUi(this);
 11     //计算函数
 12     count = 1;
 13     this->setWindowTitle("服务端");
 14     //给server指针开辟内存
 15     server = new QTcpServer(this);
 16     //监听是否收到客户端的信息
 17     server->listen(QHostAddress::AnyIPv4,9999);
 18 
 19     //提前约定
 20     //对手写槽进行连接
 21     connect(server,
 22             SIGNAL(newConnection()),
 23             this,
 24             SLOT(slotNewConn()));
 25 
 26     //将当前的图片保存到path中
 27     QString path = QDir::currentPath();
 28     //连接音乐
 29     ///Jingle Bells.mp3
 30     player.setMedia(QUrl(path + "/1.wav"));
 31 
 32 }
 33 
 34 Widget::~Widget()
 35 {
 36     delete ui;
 37 }
 38 /**
 39  * @brief Widget::slotNewConn
 40  * 手写的槽函数用于接收是否连接到网络
 41  */
 42 void Widget::slotNewConn(){
 43 
 44     if(server->hasPendingConnections()){
 45         socket = server->nextPendingConnection();
 46         //如果显示输出,则连接建立成功
 47         //在label上面显示
 48         ui->label->setText("有客户端来了");
 49 
 50         //手写槽需要建立连接 connect【接收】
 51         connect(socket,//信号的发出者
 52                 SIGNAL(readyRead()),//读消息
 53                 this,
 54                 SLOT(slotRecv()));
 55 
 56     }
 57 }
 58 
 59 /**
 60  * @brief Widget::slotRecv
 61  * 在服务器内接收客户端的信息
 62  * 没有按钮来点击接收,因此需要添加一个 手写槽slotRecv()
 63  * 用来接收人体传感器的信息
 64  */
 65 void Widget::slotRecv(){
 66 
 67     //在服务器内接收客户端的信息
 68     //没有按钮来点击接收,因此需要添加一个 手写槽slotRecv()【类型于自己手写一个显示方法】
 69     //现在接收的类型是 QByteArray 类型
 70     QString str;
 71     QByteArray array;
 72 
 73     //readAll()  读取所有的东西
 74     array = socket->readAll();
 75 
 76     //调用append函数【添加】,将类型转换成QString类型
 77     str.append(array);
 78 
 79     //然后在label_2上面显示字符串类型的内容
 80     ui->label_2->setText(str);
 81     if(str == "infared_on\r\n"){
 82         //如果接收的信息是"infared_on"
 83         //那么我就在label_3上面显示开灯
 84         ui->label_3->setText("开灯");
 85         //调用手写槽函数
 86         //如果是开灯,就播放这张照片
 87         turn_on_the_light();
 88         //这个音乐
 89         openmusic();
 90         //在这个写这段代码,有一个弊端,接收点一下发送消息,才会响应一次
 91         //【需要:当我发送的是开灯信号的时候,声音是一直播放的】
 92         //如果接收到开灯的信号,那么将播放音乐
 93         //player.play();
 94         //如果接收到开灯的信号,那么将把照片放置到label_4中
 95         //pix.load(":/1.jpg","jpg");
 96         //ui->label_4->setPixmap(pix);
 97         //将图片进行自适应
 98         //ui->label_4->setScaledContents(true);
 99 
100         //定义一个手写槽
101 
102     }else{
103 
104         ui->label_3->setText("关灯");
105         //如果接收到关灯的信号,那么将暂停音乐
106         //player.pause();
107         //调用手写槽,如果是关灯,就换另一种图片
108         close_on_the_light();
109         closemusic();
110     }
111 }
112 /**
113  * @brief Widget::on_pushButton_clicked
114  * 手动暂停按钮
115  */
116 void Widget::on_pushButton_clicked()
117 {
118     //当按钮被按下,音乐会被暂停【手动暂停】
119     //如果接收到开灯的信息,不想播放声音,可以手动暂停
120     closemusic();
121 }
122 /**
123  * @brief Widget::openmusic
124  * 手写槽打开音乐
125  */
126 void Widget::openmusic(){
127     //【修复一个只有在点击的情况下,才会播放音乐】
128     //【让音乐持续播放】
129     //修复音乐无限的bug,原因是while的判断条件内,count初始不能为0
130     while(count){//上面代码块中定义的count = 1
131         player.play();
132         if(count == 5){
133             return;
134         }
135         count++;
136     }
137 
138 }
139 
140 /**
141  * @brief Widget::closemusic
142  * //手写槽,关闭音乐
143  */
144 void Widget::closemusic(){
145 
146     player.pause();
147 
148 }
149 /**
150  * @brief Widget::turn_on_the_light
151  * 开灯的图片响应
152  */
153 void Widget::turn_on_the_light()
154 {
155     pix.load(":/2.jpg","jpg");
156     ui->label_4->setPixmap(pix);
157     ui->label_4->setScaledContents(true);
158 }
159 /**
160  * @brief Widget::close_on_the_light
161  * 关灯的图片响应
162  */
163 void Widget::close_on_the_light()
164 {
165     pix.load(":/1.jpg","jpg");
166     ui->label_4->setPixmap(pix);
167     ui->label_4->setScaledContents(true);
168 }

界面文件:widget.ui

界面文件中对象组件:


【服务端】文件名称:untitledTransmission


头文件:widget.h

复制代码
 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 #include <QTcpServer>
 6 #include <QTcpSocket>
 7 #include <QSerialPort>
 8 #include <QMessageBox>
 9 
10 namespace Ui {
11 class Widget;
12 }
13 
14 class Widget : public QWidget
15 {
16     Q_OBJECT
17 
18 public:
19     explicit Widget(QWidget *parent = 0);
20     ~Widget();
21 
22 private slots:
23     //建立连接按钮
24     void on_pushButton_clicked();
25     //是否连接成功
26     void slotCostomer();
27     //发送信息  按钮
28     void on_pushButton_4_clicked();
29     //串口按钮
30     void on_pushButton_5_clicked();
31     //创建的手写槽
32     //读取消息
33     void slotRecvSerial();
34     //建立手写槽自动给服务端发送信息
35     void Automatically_send_messages();
36 
37 private:
38     Ui::Widget *ui;
39 
40     //创建一个socket的指针变量
41     QTcpSocket *socket;
42     //创建一个serial的指针变量
43     QSerialPort* serial;
44 
45 };
46 
47 #endif // WIDGET_H

源文件:widget.cpp

复制代码
  1 #include "widget.h"
  2 #include "ui_widget.h"
  3 
  4 Widget::Widget(QWidget *parent) :
  5     QWidget(parent),
  6     ui(new Ui::Widget)
  7 {
  8     ui->setupUi(this);
  9     this->setWindowTitle("客户端");
 10 
 11     //为这个创建的指针变量分配空间
 12     socket = new QTcpSocket(this);
 13     //手写槽建立连接
 14     connect(socket,
 15             SIGNAL(connected()),
 16             this,
 17             SLOT(slotCostomer()));
 18 
 19     //检测红外信号接收【采集人体传感器信息,然后进行发送】
 20     //给指针分配内存
 21     serial = new QSerialPort(this);
 22 
 23     //手写槽创建连接
 24     connect(serial,
 25             SIGNAL(readyRead()),
 26             this,
 27             SLOT(slotRecvSerial())
 28                 );
 29 
 30     //建立自动连接发送信息
 31     connect(serial,
 32             SIGNAL(readyRead()),
 33             this,
 34             SLOT(Automatically_send_messages())
 35                 );
 36 
 37 
 38 }
 39 
 40 Widget::~Widget()
 41 {
 42     delete ui;
 43 }
 44 
 45 /**
 46  * @brief Widget::on_pushButton_clicked
 47  * 这个按钮是建立连接
 48  */
 49 void Widget::on_pushButton_clicked()
 50 {
 51     QString ipaddr,port;
 52     //获取IP地址的内容
 53     //lineEdit 是IP地址
 54     ipaddr = ui->lineEdit->text();
 55     //获取端口号的内容
 56     //lineEdit_2 是端口号
 57     port = ui->lineEdit_2->text();
 58 
 59     int m_port;
 60     //将端口号转换成int类型
 61     m_port = port.toInt();
 62 
 63     //cmd  ipconfig/all
 64     //ipv4   192.168.66.179
 65     //将这个程序进行发送
 66     socket->connectToHost(ipaddr,m_port);
 67 }
 68 
 69 /**
 70  * @brief Widget::slotCostomer
 71  * 这个连接是不需要按钮触发的,因此需求在加载的时候触发连接
 72  */
 73 void Widget::slotCostomer(){
 74     //label  是显示连接信息
 75     ui->label->setText("连接服务器成功...");
 76 }
 77 
 78 //192.168.87.95
 79 //下面的代码是发送消息按钮
 80 /**
 81  * @brief Widget::on_pushButton_4_clicked
 82  * 如果点击发送按钮,人体传感器的消息才会发送给服务端
 83  *
 84  * 【新问题】如果不借助按钮事件装置,将检测到人体传感器的信息直接发送到服务端
 85  * 1、应该将按钮装置设置成一个手写槽
 86  * 2、将手写槽建立自动连接
 87  */
 88 /*
 89 void Widget::on_pushButton_4_clicked()
 90 {
 91     QByteArray array;
 92     QString str;
 93 
 94     //获取lineEdit_3的内容
 95     //内容是任何获取的呢?
 96     //【是我检测到人体传感器然后获取人体传感器的内容进行转发】
 97     str = ui->label->text();
 98 
 99     //发送的时候只能发送QByteArray类型
100     //因此调用append方法【增加】,把str追加到QSring后面,实现类型转换
101     array.append(str);
102 
103     //转换完成后就要进行发送
104     //上方代码块中已经在内存中为socket开辟了空间
105     socket->write(array);
106 }
107 */
108 /**
109  * @brief Automatically_send_messages()
110  * 建立自动连接发送信息
111  */
112 void Widget::Automatically_send_messages(){
113 
114     QByteArray array;
115     QString str;
116 
117     //获取lineEdit_3的内容
118     //内容是任何获取的呢?
119     //【是我检测到人体传感器然后获取人体传感器的内容进行转发】
120     str = ui->label->text();
121 
122     //发送的时候只能发送QByteArray类型
123     //因此调用append方法【增加】,把str追加到QSring后面,实现类型转换
124     array.append(str);
125 
126     //转换完成后就要进行发送
127     //上方代码块中已经在内存中为socket开辟了空间
128     socket->write(array);
129 }
130 
131 /**
132  * @brief on_pushButton_5_clicked()
133  * 串口按钮
134  */
135 void Widget::on_pushButton_5_clicked()
136 {
137     QString strPortName,strBaudRate;
138     //获取comboBox的数据
139     strPortName = ui->comboBox->currentText();
140     strBaudRate = ui->comboBox_2->currentText();
141     serial->setPortName(strPortName);
142     serial->setBaudRate(strBaudRate.toInt());
143 
144     //设置数据位
145     //枚举类型
146     serial->setDataBits(QSerialPort::Data8);
147     //设置停止位
148     serial->setStopBits(QSerialPort::OneStop);
149     //校验位
150     serial->setParity(QSerialPort::NoParity);
151     //
152     serial->setFlowControl(QSerialPort::NoFlowControl);
153 
154     //打开
155     bool ok;
156     ok = serial->open(QIODevice::ReadWrite);
157     if(ok == true){
158         QMessageBox::information(this,"打开串口","串口打开成功");
159     }else{
160         QMessageBox::warning(this,"打开串口","串口打开失败");
161     }
162 }
163 /**
164  * @brief Widget::slotRecvSerial
165  * 创建的手写槽
166  * 读取消息
167  */
168 void Widget::slotRecvSerial(){
169 
170     //读取获取人体传感器此时的消息
171     QByteArray array;
172     QString str;
173     //全部读取【人体传感器此时的信息】
174     array = serial->readAll();
175     //类型转换
176     str.append(array);
177     //读取的消息,我直接在label上面显示出来【】
178     ui->label->setText(str);//当我点击发送消息的按钮时,label上面显示的人体传感器的消息会发送给服务端
179 }

界面文件:widget.ui

界面文件中对象组件:

四、代码测试