culturered_client/PhotoDisplay/MainWindow.cpp

303 lines
10 KiB
C++
Raw Permalink Normal View History

2024-09-07 03:34:44 +00:00
#include "MainWindow.h"
#include <QMessageBox>
#include <QVBoxLayout>
#include <QLabel>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QNetworkReply>
#include <QFile>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QScreen>
#include "NetClient.h"
#include "DisplayWidget.h"
#include "TokenRequest.h"
#include "FileReceiver.h"
#include "ui_MainWindow.h"
MainWindow* s_instance = nullptr;
void clearFile() {
const QString path = QApplication::applicationDirPath() + "/PhotoDisplay/paper/";
QDir dir(path);
dir.removeRecursively();
dir.mkpath(path);
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
setWindowFlags(Qt::FramelessWindowHint);
ui->setupUi(this);
s_instance = this;
clearFile();
connect(qApp, &QApplication::screenAdded, this, &MainWindow::ScreenChange);
connect(qApp, &QApplication::screenRemoved, this, &MainWindow::ScreenChange);
if (!ParseSetting()) {
QMessageBox::about(this, QString("错误"), QString("读取配置文件失败"));
exit(-1);
}
qDebug() << __FUNCTION__ << "screen:" << QApplication::screens().count();
for (int i = 0; i < m_setting.widgets.count(); ++i) {
DisplayWidget* widget = new DisplayWidget(m_setting.widgets[i]);
if (i == 0) {
setCentralWidget(widget);
}
connect(widget, &DisplayWidget::ScreenGeometryChanged, this, &MainWindow::ScreenChange);
m_widgets.append(widget);
}
ScreenChange();
if (!zmqServer_.Start(m_setting.port)) {
qDebug() << "QMainServer::Start listen failed" << m_setting.port;
return ;
}
connect(&zmqServer_, &ZMQServer::MessageReady, this, &MainWindow::OnHandleMessage);
//connect(&m_udpSocket, &QUdpSocket::readyRead, this, &MainWindow::OnDataRead);
m_tokenRequest = new TokenRequest(this);
}
MainWindow::~MainWindow() {
//m_netClient->Stop();
zmqServer_.Stop();
delete ui;
s_instance = nullptr;
}
MainWindow& MainWindow::Get() {
return *s_instance;
}
void MainWindow::OnDataRead() {
// while (m_udpSocket.hasPendingDatagrams()) {
return;
{
// QByteArray datagram;
// datagram.resize(m_udpSocket.pendingDatagramSize());
// QHostAddress peerHostAddress;
// m_udpSocket.readDatagram(datagram.data(), datagram.size(), &peerHostAddress);
qDebug() << __FUNCTION__ <<"";
QJsonDocument jsonDoc = QJsonDocument::fromJson("");
if (!jsonDoc.isNull() && jsonDoc.isObject()) {
QJsonObject jsonObj = jsonDoc.object();
// 获取 cmd 字段的值
if (jsonObj.contains("cmd")) {
QString cmd = jsonObj["cmd"].toString();
//if (cmd == "photo_ready") {
if (cmd == "trans") {
// 获取 file 和 download 字段的值
QString file = jsonObj["file"].toString();
QString download = jsonObj["download"].toString();
QString tag = jsonObj["info"].toString();
QString url = QString("http://%1:5000/download/%2").arg(m_serverIp, file);
QNetworkReply* reply = manager.get(QNetworkRequest(QUrl(url)));
connect(reply, &QNetworkReply::finished, [this, reply, file, download, tag]() {
if (reply->error() == QNetworkReply::NoError) {
// 获取 HTTP 状态码
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// 获取相应的数据
QByteArray imageData = reply->readAll();
const QString savePath = QApplication::applicationDirPath() + "/PhotoDisplay/paper/" + file;
// 保存图片到本地文件
QFile file(savePath);
file.open(QIODevice::WriteOnly);
file.write(imageData);
file.close();
ShowPaper(savePath, download, tag);
qDebug() << "下载完成" << savePath;
}
else {
qDebug() << "下载失败:" << reply->errorString();
}
});
}
}
}
else {
/* QString message(datagram);
if (datagram == "printServerBroadcast") {
m_serverIp = peerHostAddress.toString();
}*/
}
}
}
void MainWindow::ShowPaper(const QString& filePath, const QString& url, const QString& info) {
QFileInfo fileInfo(filePath);
QString fileName = fileInfo.completeBaseName();
int num = fileName.toInt() - 1;
int index = num % m_setting.count;
qDebug() << __FUNCTION__ << "filePath:" << filePath << " url:" << url << " info:" << info;
for (int i = 0; i < m_widgets.size(); ++i) {
m_widgets[i]->SetPaper(filePath, url, info);
}
}
void MainWindow::closeEvent(QCloseEvent* event) {
zmqServer_.Stop();
for (int i = 1; i < m_widgets.size(); ++i) {
m_widgets[i]->close();
m_widgets[i]->deleteLater();
}
}
bool MainWindow::ParseSetting() {
const QString jsonPath = QApplication::applicationDirPath() + "/PhotoDisplay/config.json";
QFile file(jsonPath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Failed to open file";
qApp->exit();
return false;
}
QByteArray fileData = file.readAll();
file.close();
QJsonDocument jsonDoc = QJsonDocument::fromJson(fileData);
if (jsonDoc.isNull()) {
qDebug() << "json parse error";
return false;
}
QJsonObject jsonObj = jsonDoc.object();
m_setting.total = jsonObj.value("total").toInt();
m_setting.start = jsonObj.value("start").toInt();
m_setting.count = jsonObj.value("count").toInt();
m_setting.port = jsonObj.value("port").toInt();
m_serverIp = jsonObj.value("server").toString();
QJsonArray widgetsArray = jsonObj.value("widgets").toArray();
for (int i = 0; i < widgetsArray.size(); ++i) {
Widget widget;
QJsonObject widgetObj = widgetsArray.at(i).toObject();
widget.x = widgetObj.value("x").toInt();
widget.y = widgetObj.value("y").toInt();
widget.width = widgetObj.value("width").toInt();
widget.height = widgetObj.value("height").toInt();
widget.bg = widgetObj.value("bg").toString();
widget.anim = widgetObj.value("anim").toInt();
widget.duration = widgetObj.value("duration").toInt();
widget.tag = widgetObj.value("tag").toString();
m_setting.widgets.emplace_back(std::move((widget)));
}
return true;
}
void MainWindow::OnHandleMessage(const QString& message) {
if (message.isEmpty()) {
qDebug() << __FUNCTION__ << "message is empty";
return;
}
qDebug() << __FUNCTION__ << message;
QJsonDocument jsonDoc = QJsonDocument::fromJson(message.toUtf8());
if (!jsonDoc.isNull() && jsonDoc.isObject()) {
QJsonObject jsonObj = jsonDoc.object();
// 获取 cmd 字段的值
if (jsonObj.contains("cmd")) {
QString cmd = jsonObj["cmd"].toString();
//if (cmd == "photo_ready") {
if (cmd == "trans") {
// 获取 file 和 download 字段的值
QString file = jsonObj["file"].toString();
QString download = jsonObj["download"].toString();
QString tag = jsonObj["info"].toString();
QString url = QString("http://%1:5000/download/%2").arg(m_serverIp, file);
QNetworkReply* reply = manager.get(QNetworkRequest(QUrl(url)));
connect(reply, &QNetworkReply::finished, [this, reply, file, download, tag]() {
if (reply->error() == QNetworkReply::NoError) {
// 获取 HTTP 状态码
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// 获取相应的数据
QByteArray imageData = reply->readAll();
const QString savePath = QApplication::applicationDirPath() + "/PhotoDisplay/paper/" + file;
// 保存图片到本地文件
QFile file(savePath);
file.open(QIODevice::WriteOnly);
file.write(imageData);
file.close();
ShowPaper(savePath, download, tag);
qDebug() << "下载完成" << savePath;
}
else {
qDebug() << "下载失败:" << reply->errorString();
}
});
}
}
else {
qDebug() << "解析失败";
}
}
}
void MainWindow::ScreenChange() {
const QList<QScreen*> screens = QApplication::screens();
qDebug() << __FUNCTION__ << "screen:" << screens.count();
int screenIndex = 0;
for (int i = 0; i < m_setting.widgets.count(); ++i) {
QWidget* widget = m_widgets[i];
screenIndex = i;
if (screenIndex >= screens.count()) {
// widget->hide();
// continue;
screenIndex = screens.count() - 1;
}
const QRect rect = screens[screenIndex]->geometry();
QSize sz(qMin(m_setting.widgets[i].width, rect.width()), qMin(m_setting.widgets[i].height, rect.height()));
QPoint pt(m_setting.widgets[i].x, m_setting.widgets[i].y);
widget->setGeometry(QRect(pt, sz));
widget->setFixedSize(sz);
qDebug() << __FUNCTION__ << "i=" << i << ", screenIndex=" << screenIndex << " pt=" << pt << " size="<<sz;
reinterpret_cast<DisplayWidget*>(widget)->SizeChange();
if (i == 0) {
widget = this;
setGeometry(QRect(pt, sz));
setFixedSize(sz);
}
widget->show();
}
}