一、本次测试目的
基于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
界面文件中对象组件:
四、代码测试