8

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

 1 year ago
source link: https://www.cnblogs.com/gddzkw/p/17932566.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

一、本次测试目的

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

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

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

三、代码展示


【服务端】文件名称:untitledReceivingInformation


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

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

2476643-20231228142222057-1871987873.png

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

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

2476643-20231228142833112-465145439.png

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

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

2476643-20231228143046941-394139994.png

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

2476643-20231228143529953-959208626.png

头文件: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

 界面文件中对象组件:

2476643-20231228144319974-709241108.png

 四、代码测试

2476643-20231228150407377-165218130.jpg

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK