一、主要功能介绍
1.1 登录界面
登录界面,用来判断是否账号密码输入正确,错误将会弹出消息框。
void first::on_enroll_clicked(){
if(ui->account->text()=="共创芯未来"&&ui->password->text()=="2024"){
my_next->show();
this->hide();
}else
QMessageBox::about(this,"提示","密码错误");
}
1.2 创建服务器
在主窗口的的构造函数中,初始化TCP服务器并监听指定的端口。并实现newConnection函数来处理新的连接请求。当有客户端尝试连接时,这个函数将被调用。
// 初始化TCP服务器:
my_server = new QTcpServer(this);
connect(my_server,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));
// 处理连接
void next::newConnection_Slot(){
my_socket = my_server->nextPendingConnection();//得到通信的套接字对象
connect(my_socket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}
1.3 编辑发送指令
//发送指令
void next::on_pushButton_TX_clicked(){
QString SendCon = ui->lineEdit_TxAT->text().toLocal8Bit().data();
//封装编码
QByteArray receiveDate;
QTextCodec *tc = QTextCodec::codecForName("GBK"); //编码转换,否则乱码
//向输出框打印发送的数据,同时向下位机发送指令
ui->plainTextEdit_Rxdata->appendPlainText(str2);
my_socket->write(ui->lineEdit_TxAT->text().toLocal8Bit().data());
}
1.4 实现按键切换效果
设置标志位,实现UI界面的切换效果。
int flag_forward = 0; //前进标志位
int flag_back = 0; //后退标志位
int flag_left = 0; //左转标志位
int flag_right = 0; //右转标志位
int flag_mode = 0; //避障模式标志位
效果如下图所示:
二、上位机代码
2.1 first.c
#include "first.h"
#include "ui_first.h"
first::first(QWidget *parent) :
QWidget(parent),
ui(new Ui::first)
{
ui->setupUi(this);
my_next = new next;
this->setWindowIcon(QIcon(":/myResource/APP3.png"));
this->setWindowTitle("登录");
ui->account->setStyleSheet(
"border-style: solid;" /* 边框样式 */
"color: rgb(255, 255, 255);"
//"font: 15pt "华文中宋";"
"background-color: rgb(0, 0, 0);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
);
ui->account->setAlignment(Qt::AlignCenter); // 设置文本水平居中
ui->account->setText("共创芯未来");
ui->password->setStyleSheet(
"border-style: solid;" /* 边框样式 */
"color: rgb(255, 255, 255);"
//"font: 15pt "华文中宋";"
"background-color: rgb(0, 0, 0);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
);
ui->password->setAlignment(Qt::AlignCenter); // 设置文本水平居中
ui->password->setText("2024");
}
first::~first()
{
delete ui;
}
void first::on_enroll_clicked()
{
if(ui->account->text()=="共创芯未来"&&ui->password->text()=="2024"){
my_next->show();
this->hide();
}
else
{
QMessageBox::about(this,"提示","密码错误");
//ui->lineEdit->clear();
//ui->lineEdit_2->clear();
}
}
2.2 first.h
#ifndef FIRST_H
#define FIRST_H
#include <QWidget>
#include <QMessageBox>
#include "next.h"
namespace Ui {
class first;
}
class first : public QWidget
{
Q_OBJECT
public:
explicit first(QWidget *parent = 0);
~first();
private slots:
void on_enroll_clicked();
private:
Ui::first *ui;
next * my_next;
};
#endif // FIRST_H
2.3 next.c
#include "next.h"
#include "ui_next.h"
#include <QTextCodec>
int flag_connect = 0;
next::next(QWidget *parent) :
QWidget(parent),
ui(new Ui::next)
{
ui->setupUi(this);
this->setWindowIcon(QIcon(":/myResource/APP4.png"));
this->setWindowTitle("六足机器人控制系统 2024共创芯未来");
//QPixmap *pixmap = new QPixmap(":/myResource/2024应用赛道作品视频封面.png");
//pixmap->scaled(ui->label->size(), Qt::KeepAspectRatio);
//ui->label->setScaledContents(true);
//ui->label->setPixmap(*pixmap);
//实例化对象
my_socket = new QTcpSocket;
my_server = new QTcpServer(this);
my_timer = new QTimer;
//关联信号与槽
//套接字对象存在一个信号connected,该信号触发的时机是套接字连接成功,当信号触发由该界面的connect_success函数进行响应
connect(my_socket,SIGNAL(connected()),this,SLOT(connect_success()));
//套接字对象存在一个信号readyread,该信号触发的时机是套接字内存在数据可读,当信号触发则由该界面的recv_data_from_server函数进行响应
connect(my_socket,SIGNAL(readyRead()),this,SLOT(recv_data_from_server()));
connect(my_timer,SIGNAL(timeout()),this,SLOT(time_out()));
//初始化TCP服务器:在主窗口的构造函数中,初始化TCP服务器并监听指定的端口。
//my_server = new QTcpServer(this);
connect(my_server,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));
//my_server->listen(QHostAddress::Any, port); // 监听任意地址的****端口
//QHostAddress serverAddress("192.168.45.36");
//my_server->listen(serverAddress, 6666);
}
next::~next()
{
delete ui;
}
//处理连接:实现NewConnection函数来处理新的连接请求。当有客户端尝试连接时,这个函数将被调用。
void next::newConnection_Slot(){
flag_connect = 1;
my_socket = my_server->nextPendingConnection();//得到通信的套接字对象
connect(my_socket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
connect(my_socket,SIGNAL(disconnected()),this,SLOT(disconnected_Slot()));
ui->label_3->setStyleSheet("border-image: url(:/myResource/connect.png)");
}
//服务器或客户机连接状态
void next::disconnected_Slot(){
flag_connect = 0;
my_socket->close();
ui->label_3->setStyleSheet("border-image: url(:/myResource/discon.png)");
}
void next::readyRead_Slot()
{
QByteArray receivedData = my_socket->readAll(); // 直接读取所有可用数据
if (!receivedData.isEmpty())
{
QTextCodec *tc = QTextCodec::codecForName("GBK"); // 只在需要时创建编码器
QString strBuf = tc->toUnicode(receivedData); // 编码转换
ui->plainTextEdit_Rxdata->appendPlainText(strBuf);
}
// receivedData.clear(); 在这里不需要被清除,因为它是局部变量
}
//开启服务器
void next::on_pushButton_connect_clicked()
{
QString port = ui->lineEdit_port->text();
my_server->listen(QHostAddress::Any, atoi(port.toStdString().data())); // 监听任意地址的****端口
//QString ip=ui->lineEdit_ip->text();
//QString port=ui->lineEdit_port->text();
//my_socket->connectToHost(QHostAddress(ip),atoi(port.toStdString().data()));
}
//开启定时器计时
void next::on_pushButton_oncamera_clicked()
{
my_timer->start(1000);
}
//暂停定时器计时
void next::on_pushButton_offcamera_clicked()
{
my_timer->stop();
}
void next::recv_data_from_server()
{
if(flag_camera == 0){
//获取图像大小
char pic_len_buf[10] = {0};
my_socket->read(pic_len_buf,10);
pic_len = atoi(pic_len_buf);
flag_camera = 1;
}else if(flag_camera == 1){
//当套接字内数据还没累计到一张图像时暂时不做读取
if(my_socket->bytesAvailable()<pic_len){
return ;
}
//获取图像内容,并显示
char pic_buf[1024*1024] = {0};
my_socket->read(pic_buf,pic_len);
//定义一个QPixmap对象
QPixmap my_pixmap;
my_pixmap.loadFromData((uchar*)pic_buf,pic_len);
my_pixmap = my_pixmap.scaled(ui->label_2->size());
ui->label_2->setScaledContents(true);
ui->label_2->setPixmap(my_pixmap);
flag_camera = 0;
}
}
void next::connect_success()
{
QMessageBox::about(this,"连接提示","连接成功");
}
void next::time_out()
{
char buf[1024] = "get_pic";
my_socket->write(buf,sizeof(buf));
}
//清空接收区
void next::on_pushButton_clear_clicked()
{
ui->plainTextEdit_Rxdata->clear();
}
//发送指令
void next::on_pushButton_TX_clicked()
{
QString SendCon = ui->lineEdit_TxAT->text().toLocal8Bit().data();
if(flag_connect){
if(SendCon!=""){
//封装编码
QByteArray receiveDate;
QTextCodec *tc = QTextCodec::codecForName("GBK"); //编码转换,必须转换编码,否则乱码
//对发送框编码
receiveDate = ui->lineEdit_TxAT->text().toLocal8Bit().data();
QString strBuf=tc->toUnicode(receiveDate);
//整合符号 ->
QString str = "->";
QString str2 = str.append(strBuf);
//向输出框打印发送的数据
ui->plainTextEdit_Rxdata->appendPlainText(str2);
my_socket->write(ui->lineEdit_TxAT->text().toLocal8Bit().data());
}
else{
QMessageBox::critical(this,"警告","不能发送空白信息!");
}
}
else
{
QMessageBox::critical(this,"提示","发送失败,未连接!");
}
}
//前进指令
void next::on_pushButton_forward_clicked()
{
if(flag_forward == 0){
//char buff[20]="forward_on";
char buff[20]="2";
ui->pushButton_forward->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(0, 255, 255);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
my_socket->write(buff,strlen(buff));
flag_forward = 1;
}else{
ui->pushButton_forward->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(139, 139, 139);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
//char buff[20]="forward_off";
char buff[20]="22";
my_socket->write(buff,strlen(buff));
flag_forward = 0;
}
}
void next::on_pushButton_right_clicked()
{
if(flag_right== 0){
char buff[20]="5";
ui->pushButton_right->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(0, 255, 255);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
my_socket->write(buff,strlen(buff));
flag_right = 1;
}else{
ui->pushButton_right->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(139, 139, 139);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
char buff[20]="55";
my_socket->write(buff,strlen(buff));
flag_right = 0;
}
}
void next::on_pushButton_left_clicked()
{
if(flag_left== 0){
char buff[20]="4";
ui->pushButton_left->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(0, 255, 255);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
my_socket->write(buff,strlen(buff));
flag_left = 1;
}else{
ui->pushButton_left->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(139, 139, 139);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
char buff[20]="44";
my_socket->write(buff,strlen(buff));
flag_left = 0;
}
}
void next::on_pushButton_back_clicked()
{
if(flag_back== 0){
char buff[20]="3";
ui->pushButton_back->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(0, 255, 255);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
my_socket->write(buff,strlen(buff));
flag_back = 1;
}else{
ui->pushButton_back->setStyleSheet(
"border-style: solid;" /* 边框样式 */
//"font: 15pt "华文中宋";"
"color: rgb(139, 139, 139);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 10px;" /* 边框圆角 */
"border-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));"
);
char buff[20]="33";
my_socket->write(buff,strlen(buff));
flag_back = 0;
}
}
void next::on_pushButton_mode_clicked()
{
if(flag_mode == 0){
char buff[20]="1";
ui->pushButton_mode->setStyleSheet(
"border-style: solid;" /* 边框样式 */
"border-color: rgb(170, 255, 255);"
"color: rgb(0, 255, 255);"
"border-width: 7px;"/* 边框宽度 */
"border-radius: 25px;" /* 边框圆角 */
"background-color: rgb(148, 148, 148);");
my_socket->write(buff,strlen(buff));
flag_mode = 1;
}else{
ui->pushButton_mode->setStyleSheet(
"border-style: solid;" /* 边框样式 */
"color: rgb(176, 176, 176);"
"border-width: 7px;" /* 边框宽度 */
"border-radius: 25px;" /* 边框圆角 */);
char buff[20]="0";
my_socket->write(buff,strlen(buff));
flag_mode = 0;
}
}
2.4 next.h
#ifndef NEXT_H
#define NEXT_H
#include <QWidget>
#include <QTcpSocket>
#include <QTcpServer>
#include <QHostAddress>
#include <QPixmap>
#include <QMessageBox>
//定时器类头文件
#include <QTimer>
namespace Ui {
class next;
}
class next : public QWidget
{
Q_OBJECT
public:
explicit next(QWidget *parent = 0);
~next();
private slots:
void on_pushButton_oncamera_clicked();
void on_pushButton_offcamera_clicked();
void recv_data_from_server();
void connect_success();
void time_out();
void on_pushButton_connect_clicked();
void on_pushButton_forward_clicked();
void newConnection_Slot();
void disconnected_Slot();
void readyRead_Slot();
void on_pushButton_clear_clicked();
void on_pushButton_TX_clicked();
void on_pushButton_right_clicked();
void on_pushButton_left_clicked();
void on_pushButton_back_clicked();
void on_pushButton_mode_clicked();
private:
Ui::next *ui;
QTcpSocket * my_socket;
QTcpServer * my_server;
//定时器对象指针
QTimer * my_timer;
int flag_camera = 0;
int pic_len;
int flag_forward = 0;
int flag_back = 0;
int flag_left = 0;
int flag_right = 0;
int flag_mode = 0;
};
#endif // NEXT_H