一、本次测试目的
基于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

界面文件中对象组件:

四、代码测试

