#include "MainWindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #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 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="<(widget)->SizeChange(); if (i == 0) { widget = this; setGeometry(QRect(pt, sz)); setFixedSize(sz); } widget->show(); } }