Qt广告机客户端(下位机)
创始人
2024-05-29 22:57:11
0

目录

  • 功能
  • 结构
  • adClient.pro
  • main.cpp
  • adclient.h 客户端
  • adclient.cpp 客户端
    • addate.h 时间处理
    • addate.cpp 时间处理
    • adsocket.h 客户端Socket处理
    • adsocket.cpp 客户端Socket处理
    • weather.h 天气信息处理
    • weather.cpp 天气信息处理
    • rollmassege.h 滚动信息处理
    • rollmassege.cpp 滚动信息处理
  • 效果

功能

  1. 连接服务器(上位机)
  2. 广告图片播放模块
  3. 日期显示模块
  4. 天气显示模块
  5. 信息提示模块

结构

在这里插入图片描述

adClient.pro

QT       += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11TARGET = adClient
TEMPLATE = appSOURCES += main.cpp\adclient.cpp \addate.cpp \adsocket.cpp \weather.cpp \rollmassege.cppHEADERS  += adclient.h \addate.h \adsocket.h \tcp_MSG.h \weather.h \rollmassege.hFORMS    += adclient.uiRESOURCES += \res.qrc

main.cpp

#include "adclient.h"
#include 
#include 
#include 
int main(int argc, char *argv[])
{QApplication a(argc, argv);// 判断当前运行环境是否为Linux或Windows。
#ifdef Q_OS_LINUXqDebug() << "Current OS is Linux";
#elif defined(Q_OS_WIN)qDebug() << "Current OS is Windows";
#elseqDebug() << "Unknown OS";
#endifQString folderName = "pic";//QString folderPath = QDir::currentPath() + "/" + folderName;QString folderPath = QApplication::applicationDirPath() + "/" + folderName;QDir folder(folderPath);if (!folder.exists()){bool success = folder.mkpath("."); // 创建文件夹if (success)qDebug() << "文件夹创建成功";elseqDebug() << "文件夹创建失败";}elseqDebug() << "文件夹已存在";QDir::setCurrent(folderPath);// 设置文件生成路径AdClient w;w.show();return a.exec();
}

adclient.h 客户端

#ifndef ADCLIENT_H
#define ADCLIENT_H#include 
#include "addate.h"
#include "adsocket.h"
#include "weather.h"
#include "rollmassege.h"
#include 
#include 
#include "stdlib.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include namespace Ui {
class AdClient;
}class AdClient : public QMainWindow
{Q_OBJECTpublic:explicit AdClient(QWidget *parent = 0);~AdClient();void saveFile();// 保存文件void InitStatusBar();// 初始化底部状态栏QString GetLocalIP();// 获取本地IPpublic slots:void showImage(QImage);// 图片显示void showProgressBar(int currentProgress,int finish);//进度条显示void autoPlayTimeOut();//自动播放void GUI_WarningMsg(QString title,QString text,QString buttons,QString defaultButton);//设置警报void connectToServer();// 链接到服务器
private:Ui::AdClient *ui;AdDate *date;AdSocket *socket;Weather *weater;RollMassege *rollmsg;QProgressDialog *progress;// 创建进度条QTimer autoPlayTimer;int index;QLabel *mLocalIP;QLabel *serverIP_lb;QLineEdit *serverIP;QLabel *serverPort_lb;QLineEdit *serverPort;QPushButton *connectTcp;};#endif // ADCLIENT_H

adclient.cpp 客户端

#include "adclient.h"
#include "ui_adclient.h"
#include QMap qMapPicturePath;// 图片路径//QTcpSocket 的默认缓存区大小是 64KB(65536字节)
AdClient::AdClient(QWidget *parent) :QMainWindow(parent),ui(new Ui::AdClient)
{ui->setupUi(this);this->setWindowIcon(QIcon(":/client.jpg"));date = new AdDate(ui->date_lb);//时间socket = new AdSocket;// TCP客户端weater = new Weather(ui->weather_lb);// 接收天气信息绘制rollmsg = new RollMassege(ui->msg_lb, ui->msg_lb);// 滚动信息connect(socket, SIGNAL(sig_showWeather(QString,QString,QString)), weater, SLOT(showWeather(QString,QString,QString)));connect(socket, SIGNAL(sig_showTxt(QString)), rollmsg, SLOT(showTxt(QString)));connect(socket, SIGNAL(sig_showImage(QImage)), this, SLOT(showImage(QImage)));connect(socket, SIGNAL(sig_showProgressBar(int,int)), this, SLOT(showProgressBar(int,int)),Qt::QueuedConnection);connect(socket, SIGNAL(GUI_WarningSignal(QString,QString,QString,QString)), this, SLOT(GUI_WarningMsg(QString,QString,QString,QString)));date->start();//更新时间progress = nullptr;autoPlayTimer.stop();connect(&autoPlayTimer, SIGNAL(timeout()), this, SLOT(autoPlayTimeOut()));InitStatusBar();// 初始化底部状态栏
}AdClient::~AdClient()
{delete socket;delete ui;
}// 保存文件
void AdClient::saveFile()
{QString fileName=qMapPicturePath.lastKey();qDebug()<<"lastKey:"<mLocalIP=new QLabel(this);mLocalIP->setMinimumWidth(230);QString ip = GetLocalIP();//    mLocalIP->setText("本地IP:"+ip);mLocalIP->setText("本地IP:"+tr("%1").arg(ip));serverIP_lb=new QLabel(this);serverIP_lb->setMinimumWidth(100);serverIP_lb->setText("服务器IP:");serverIP=new QLineEdit(this);serverIP->setMinimumWidth(200);serverIP->setInputMask("000.000.000.000");serverPort_lb=new QLabel(this);serverPort_lb->setMinimumWidth(60);serverPort_lb->setText("Port:");serverPort=new QLineEdit(this);serverPort->setMinimumWidth(60);serverPort->setPlaceholderText("8888");connectTcp=new QPushButton("链接",this);connectTcp->setMinimumWidth(100);ui->statusBar->addWidget(mLocalIP);ui->statusBar->addWidget(serverIP_lb);ui->statusBar->addWidget(serverIP);ui->statusBar->addWidget(serverPort_lb);ui->statusBar->addWidget(serverPort);ui->statusBar->addWidget(connectTcp);connect(connectTcp, SIGNAL(clicked()), this, SLOT(connectToServer()));
}// 获取本地IP
QString AdClient::GetLocalIP()
{QList list=QNetworkInterface::allAddresses();foreach(QHostAddress address,list){if(address.protocol()==QAbstractSocket::IPv4Protocol){qDebug()<qDebug()<<"显示图片"<<__LINE__;QPixmap pixmap=QPixmap::fromImage(image);// 内容是否自动缩放,参数true自动缩放ui->video_lb->setScaledContents(true);//显示图片的全部// 将图片缩放到指定大小,参数ui->label->size()表示缩放的大小,Qt::KeepAspectRatio表示保持图片的宽高比,Qt::SmoothTransformation表示使用平滑缩放算法ui->video_lb->setPixmap(pixmap.scaled(ui->video_lb->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));qDebug()<<"图片数量:"<=2){if(!autoPlayTimer.isActive()){// 两张以上图片开启播放autoPlayTimer.start(5000);index=0;}}else{autoPlayTimer.stop();}if(qMapPicturePath.count()>=1){// 功能没问题,调试注释,避免多次保存//saveFile();// 保存文件}
}//进度条显示
void AdClient::showProgressBar(int currentProgress, int finish)
{qDebug()<<"进度条显示"<<__LINE__;if (!progress){//创建进度条progress = new QProgressDialog("接收中....", "取消", 0, 100, this);progress->setWindowModality(Qt::WindowModal);progress->setFixedSize(this->width()*0.3,this->height()*0.3);progress->setVisible(true);}//usleep(500);//在Windows环境下已被弃用QThread::msleep(50);//休眠50毫秒//更新进度条progress->setValue(currentProgress * 100 / finish);//如果任务已经完成,隐藏进度条if (currentProgress == finish){qDebug()<<"进度条显示完成"<<__LINE__;progress->hide();delete progress;progress = nullptr;}
}//自动播放
void AdClient::autoPlayTimeOut()
{QList keyList = qMapPicturePath.keys();//存放的就是QMap的key值if(index>=qMapPicturePath.count())// 删除广告时有可能 >index=0;QImage image=qMapPicturePath.value(keyList.at(index));qDebug()<<"自动播放:"<Q_UNUSED(buttons)//忽略编译器发出的警告,表明变量event未使用Q_UNUSED(defaultButton)QMessageBox *box=new QMessageBox(QMessageBox::Warning,title,text,QMessageBox::Cancel,this);QTimer::singleShot(5000,this,[=](){if(!box->isHidden()&&box->isVisible()){box->accept();}});// 5s后必执行box->exec();return;
}// 链接到服务器
void AdClient::connectToServer()
{if(serverIP->text().isEmpty()||serverPort->text().isEmpty()){QMessageBox::warning(this,"提示","请输入IP或Port");return;}socket->id=GetLocalIP();socket->address=serverIP->text();qDebug()<<"服务器IP:"<address;socket->port=serverPort->text().toInt();qDebug()<<"服务器Port:"<port;qDebug()<<"是否已经连接:"<isValid();if(socket->isValid())// 如果套接字有效并且可以使用,则返回true;否则返回false。{socket->disconnectFromHost();// 与服务器断开连接// 无需再手动连接,只要更新IP和Port就行,AdSocket::conAgain会重新发起连接.}else{socket->connectToHost(QHostAddress(socket->address), socket->port);}qDebug()<<"是否已经连接:"<isValid();
}

addate.h 时间处理

#ifndef ADDATE_H
#define ADDATE_H#include 
#include 
#include 
#include class AdDate : public QObject
{Q_OBJECT
public:AdDate(QLabel *_mlabel, QObject *parent = 0);~AdDate();void start();// 定时器开启
public slots:void updateTime();// 定时器1s超时执行一次
private:QLabel *mlabel;QTimer *mtimer;
};#endif // ADDATE_H

addate.cpp 时间处理

#include "addate.h"AdDate::AdDate(QLabel *_mlabel, QObject *parent):QObject(parent)
{mlabel = _mlabel;mtimer = new QTimer;connect(mtimer, SIGNAL(timeout()), this, SLOT(updateTime()));
}AdDate::~AdDate()
{delete mtimer;
}void AdDate::start()
{mtimer->start(1000);
}void AdDate::updateTime()
{QString time = QTime::currentTime().toString("hh:mm:ss")+"\n"+QDate::currentDate().toString("yy/MM/dd ddd");mlabel->setText(time);
}

adsocket.h 客户端Socket处理

#ifndef ADSOCKET_H
#define ADSOCKET_H#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "string.h"
#include "tcp_MSG.h"class AdSocket : public QTcpSocket
{Q_OBJECT
public:explicit AdSocket(QObject *parent = 0);~AdSocket();QString id;QString address;int port;int readMsgType;signals:void sig_showWeather(QString city,QString area,QString wt);// 发送天气信息void sig_showTxt(QString tcp_Txt);// 发送文字信息void sig_showImage(QImage tcp_image);// 发送文字信息void sig_showProgressBar(int currentProgress, int finish);// 发送进度条信息void GUI_WarningSignal(QString title,QString text,QString buttons,QString defaultButton);//设置警报public slots:void readMsg();// 接收信息void conSuc(); // 成功建立连接void conAgain();// 重新连接void conAgain(QAbstractSocket::SocketError);// 重新连接private:int needFileSize;int currentReceiveSize;QByteArray currentReceiveByte;int milsec;QString fileName;
};#endif // ADSOCKET_H

adsocket.cpp 客户端Socket处理

#include "adsocket.h"
#include extern QMap qMapPicturePath;// 图片路径// QTcpSocket会自动处理大小端问题
AdSocket::AdSocket(QObject *parent) :QTcpSocket(parent)
{//注册tcp_MSG类型qRegisterMetaType("tcp_MSG");id = "0011";/* 每当有新的输入数据时,就会发出这个信号。请记住,新传入的数据只报告一次;如果您不读取所有数据,这个类会缓冲数据,您可以稍后读取它,但是除非新数据到达,否则不会发出信号。*/connect(this, SIGNAL(readyRead()),this, SLOT(readMsg()));//该信号在调用connectToHost()并成功建立连接之后发出。connect(this, SIGNAL(connected()),this, SLOT(conSuc()));// 该信号在套接字断开连接时发出connect(this, SIGNAL(disconnected()),this, SLOT(conAgain()));address="127.0.0.1";port=8888;//connectToHost(QHostAddress(address), port);// 默认连接127.0.0.1 8888//该信号在错误发生后发出。socketError参数描述发生错误的类型connect(this, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(conAgain(QAbstractSocket::SocketError)));readMsgType=MsgType::Init;milsec=0;
}AdSocket::~AdSocket()
{}// 接收信息
void AdSocket::readMsg()
{//读取缓冲区数据QByteArray  buffer = readAll();qDebug()<<"进来了"<<__LINE__;if(readMsgType==MsgType::Init){tcp_MSG *msg=(tcp_MSG *)buffer.data();        //强转为结构体,需要用结构体指针接收qDebug()<<"进来了"<<__LINE__;qDebug()<<"类型"<type;switch (msg->type){case WEATHER://天气{QString city=msg->city;QString area=msg->area;QString weather=msg->weather;//weather="\t\t"+city+"\t"+area+"\n"+weather;emit sig_showWeather(city,area,weather);// 发送天气信息break;}case MASSEGE:// 留言{QString tcp_Txt=msg->txt;qDebug()<<"文字信息:"<qDebug()<<"添加广告"<<__LINE__;qDebug()<<"文件名"<< QString(msg->fileName);qDebug()<<"编号"<< msg->index;qDebug()<<"总数"<< msg->allAd_Num;needFileSize=msg->fileSize;currentReceiveSize=0;currentReceiveByte.clear();QByteArray  sendTcpData;//使用字节数组,将结构体转为字符数组,发送的是字符数组(数据在传输过程中都是byte类型的)//直接sizeof(senddata)内存会变小,设置了对齐方式解决sendTcpData.resize(sizeof(tcp_backMSG));tcp_backMSG backMsg={};strcpy(backMsg.id,id.toUtf8().data());backMsg.state=1;backMsg.type=MsgType::Write_back;//将封装好的结构体转为QByteArray数组,因为传输都是Byte类型memcpy(sendTcpData.data(),&backMsg,sizeof(tcp_backMSG));this->write(sendTcpData);// 回复fileName.clear();fileName=QString(msg->fileName);readMsgType=MsgType::AD_add;break;}case AD_delete://删除广告{qDebug()<<"删除广告"<<__LINE__;qDebug()<<"文件名"<< QString(msg->fileName);int  success= qMapPicturePath.remove(QString(msg->fileName));if(success){if(qMapPicturePath.count()>=1){// 有图片emit sig_showImage(qMapPicturePath.first());}else{// 没有图片QImage image(100, 100, QImage::Format_RGBA8888);image.fill(QColor(0, 0, 0, 0));// 纯透明图片emit sig_showImage(image);}emit GUI_WarningSignal("提示","删除广告成功",NULL,NULL);}else{emit GUI_WarningSignal("提示","删除广告失败",NULL,NULL);}break;}default:qDebug()<<"";break;}}else if(readMsgType==MsgType::AD_add){qDebug()<<"添加广告"<<__LINE__;qDebug()<<"需要接收大小:"<qDebug()<<"图片接收完成";startTime = QTime::currentTime();QByteArray Ret_bytearray = QByteArray::fromBase64(currentReceiveByte);QBuffer buffer(&Ret_bytearray);buffer.open(QIODevice::WriteOnly);QPixmap imageresult;imageresult.loadFromData(Ret_bytearray);qMapPicturePath.insert(fileName,imageresult.toImage());// 先插入键值emit sig_showImage(imageresult.toImage());readMsgType=MsgType::Init;endTime = QTime::currentTime();milsec += startTime.msecsTo(endTime);qDebug()<<"接收消耗时间"<QByteArray  sendTcpData;//使用字节数组,将结构体转为字符数组,发送的是字符数组(数据在传输过程中都是byte类型的)//直接sizeof(senddata)内存会变小,设置了对齐方式解决sendTcpData.resize(sizeof(tcp_backMSG));tcp_backMSG msg={};strcpy(msg.id,id.toUtf8().data());msg.state=0;msg.type=MsgType::Init;//将封装好的结构体转为QByteArray数组,因为传输都是Byte类型memcpy(sendTcpData.data(),&msg,sizeof(tcp_backMSG));this->write(sendTcpData);qDebug()<<"connect success";
}// 重新连接
void AdSocket::conAgain()
{qDebug()<<"套接字断开连接时重新连接";abort();// 终止当前连接并重置套接字connectToHost(QHostAddress(address), port);
}
// 重新连接
void AdSocket::conAgain(QAbstractSocket::SocketError error)
{qDebug()<<"连接失败:"<connectToHost(QHostAddress(address), port);}
}

weather.h 天气信息处理

#ifndef WEATHER_H
#define WEATHER_H#include 
#include 
#include 
class Weather : public QObject
{Q_OBJECT
public:explicit Weather( QLabel *_label,QObject *parent = 0);signals:public slots:void showWeather(QString city,QString area,QString weather);private:QLabel *label;QString _city;QString _area;
};#endif // WEATHER_H

weather.cpp 天气信息处理

#include "weather.h"Weather::Weather( QLabel *_label, QObject *parent) :QObject(parent)
{label = _label;
}void Weather::showWeather(QString city,QString area,QString weather)
{_city=city;qDebug()<<"城市:"<<_city;_area=area;qDebug()<<"地区:"<<_area;weather="\t\t"+_city+"\t"+_area+"\n\t"+weather;label->setText(weather);
}

rollmassege.h 滚动信息处理

#ifndef ROLLMASSEGE_H
#define ROLLMASSEGE_H#include 
#include 
#include 
#include 
#include 
#include class RollMassege : public QLabel
{Q_OBJECT
public:explicit RollMassege(QWidget *parent = 0);explicit RollMassege(QLabel *_label, QWidget *parent = 0);void paintEvent(QPaintEvent *event);
signals:public slots:void updateMsg();void showTxt(QString tcp_Txt);
private:QString txt;QRect rect;int offset;//偏移量QTimer *timer;
};#endif // ROLLMASSEGE_H

rollmassege.cpp 滚动信息处理

#include "rollmassege.h"
#include RollMassege::RollMassege(QWidget *parent) :QLabel(parent)
{
}RollMassege::RollMassege(QLabel *_label, QWidget *parent) :QLabel(parent)
{rect = _label->geometry();rect.setWidth(798);rect.setHeight(80);setGeometry(rect);show();qDebug()<start(50);
}
// 绘画事件
void RollMassege::paintEvent(QPaintEvent *event)
{Q_UNUSED(event); //忽略编译器发出的警告,表明变量event未使用QPainter painter(this);QFont font;font.setPointSize(16);painter.setFont(font);painter.drawText(rect.x()+offset, rect.y()+30, txt);// 绘制文字,x+偏移量
}void RollMassege::updateMsg()
{offset--;if(offset<0) offset = rect.width();update();// 刷新,触发绘画事件paintEvent
}void RollMassege::showTxt(QString tcp_Txt)
{txt =tcp_Txt;update();
}

效果

在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

Python|位运算|数组|动... 目录 1、只出现一次的数字(位运算,数组) 示例 选项代...
张岱的人物生平 张岱的人物生平张岱(414年-484年),字景山,吴郡吴县(今江苏苏州)人。南朝齐大臣。祖父张敞,东...
西游西后传演员女人物 西游西后传演员女人物西游西后传演员女人物 孙悟空 六小龄童 唐僧 徐少华 ...
名人故事中贾岛作诗内容简介 名人故事中贾岛作诗内容简介有一次,贾岛骑驴闯了官道.他正琢磨着一句诗,名叫《题李凝幽居》全诗如下:闲...
和男朋友一起优秀的文案? 和男朋友一起优秀的文案?1.希望是惟一所有的人都共同享有的好处;一无所有的人,仍拥有希望。2.生活,...
戴玉手镯的好处 戴玉手镯好还是... 戴玉手镯的好处 戴玉手镯好还是碧玺好 女人戴玉?戴玉好还是碧玺好点佩戴手镯,以和田玉手镯为佳!相嫌滑...
依然什么意思? 依然什么意思?依然(汉语词语)依然,汉语词汇。拼音:yī    rán基本解释:副词,指照往常、依旧...
高尔基的散文诗 高尔基的散文诗《海燕》、《大学》、《母亲》、《童年》这些都是比较出名的一些代表作。
心在飞扬作者简介 心在飞扬作者简介心在飞扬作者简介如下。根据相关公开资料查询,心在飞扬是一位优秀的小说作者,他的小说作...
卡什坦卡的故事赏析? 卡什坦卡的故事赏析?讲了一只小狗的故事, 我也是近来才读到这篇小说. 作家对动物的拟人描写真是惟妙...
林绍涛为简艾拿绿豆糕是哪一集 林绍涛为简艾拿绿豆糕是哪一集第三十二集。 贾宽认为是阎帅间接导致刘映霞住了院,第二天上班,他按捺不...
小爱同学是女生吗小安同学什么意... 小爱同学是女生吗小安同学什么意思 小爱同学,小安同学说你是女生。小安是男的。
内分泌失调导致脸上长斑,怎么调... 内分泌失调导致脸上长斑,怎么调理内分泌失调导致脸上长斑,怎么调理先调理内分泌,去看中医吧,另外用好的...
《魔幻仙境》刺客,骑士人物属性... 《魔幻仙境》刺客,骑士人物属性加点魔幻仙境骑士2功1体质
很喜欢她,该怎么办? 很喜欢她,该怎么办?太冷静了!! 太理智了!爱情是需要冲劲的~不要考虑着考虑那~否则缘...
言情小说作家 言情小说作家我比较喜欢匪我思存的,很虐,很悲,还有梅子黄时雨,笙离,叶萱,还有安宁的《温暖的玄》 小...
两个以名人的名字命名的风景名胜... 两个以名人的名字命名的风景名胜?快太白楼,李白。尚志公园,赵尚志。
幼儿教育的代表人物及其著作 幼儿教育的代表人物及其著作卡尔威特的《卡尔威特的教育》,小卡尔威特,他儿子成了天才后写的《小卡尔威特...
海贼王中为什么说路飞打凯多靠霸... 海贼王中为什么说路飞打凯多靠霸气升级?凯多是靠霸气升级吗?因为之前刚到时确实打不过人家因为路飞的实力...
运气不好拜财神有用吗运气不好拜... 运气不好拜财神有用吗运气不好拜财神有没有用1、运气不好拜财神有用。2、拜财神上香前先点蜡烛,照亮人神...