diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp index 2b87e240d4aa9a222f6758a063659824c0ad1f50..13b7d225eee00d662394455ca85f20df71052257 100644 --- a/src/backend/backend.cpp +++ b/src/backend/backend.cpp @@ -132,19 +132,13 @@ void Backend::updatePopup(const QString &text, bool indeterminate) void Backend::initializeProjectManager() { m_projectManager.reset(new ProjectManager(this, m_settings.autoScaleProject())); - connect( - m_projectManager.get(), - &ProjectManager::closingProject, - this, - [&] { - emit popupClose(); - m_projectManager.reset(); - QMetaObject::invokeMethod(m_dsManager.get(), - "sendProjectStopped", - Qt::QueuedConnection, - Q_ARG(QString, m_lastProjectSenderId)); - }, - Qt::QueuedConnection); + + connect(m_projectManager.get(), &QObject::destroyed, this, [this] { + QMetaObject::invokeMethod(m_dsManager.get(), + "sendProjectStopped", + Qt::QueuedConnection, + Q_ARG(QString, m_lastProjectSenderId)); + }); } void Backend::initDsManager() @@ -210,10 +204,7 @@ void Backend::runProject(const QString &id, const QByteArray &projectData) if (!m_projectManager->runProject(projectPath)) { qCritical() << "Could not run project. Please check the logs for more information."; - QMetaObject::invokeMethod(m_dsManager.get(), - "sendProjectStopped", - Qt::QueuedConnection, - Q_ARG(QString, id)); + m_projectManager.reset(); } else { m_projectManager->showAppWindow(); } @@ -226,33 +217,25 @@ void Backend::scanQrCode() m_qrScanner.reset(new QrScanner); connect(m_qrScanner.get(), &QrScanner::qrCodeScanned, this, [&](const QString &qrCode) { qDebug() << "QR code scanned:" << qrCode; - parseDesignViewerUrl(QUrl(qrCode)); m_qrScanner.reset(); + parseDesignViewerUrl(QUrl(qrCode)); }); + + connect(m_qrScanner.get(), &QrScanner::windowClosed, this, [&]() { m_qrScanner.reset(); }); + m_qrScanner->scanQrCode(); } void Backend::parseDesignViewerUrl(const QUrl &url) { if (url.scheme() == "qtdesignstudio") { - qDebug() << "Connecting to Design Studio from QR code"; - if (url.host().isEmpty()) { - qWarning() << "No Design Studio IP address found in the QR code"; - return; - } else if (url.query().isEmpty()) { - qWarning() << "No Design Studio ID found in the QR code"; + qWarning() << "No Design Studio IP address found in the QR code. URL:" + << url.toString(); return; } - const QString ipv4Addr = url.host(); - const QString designStudioId = url.query(); - - QMetaObject::invokeMethod(m_dsManager.get(), - "designStudioFound", - Qt::QueuedConnection, - Q_ARG(QString, ipv4Addr), - Q_ARG(QString, designStudioId)); + connectDesignStudio(url.host()); } else { qWarning() << "Unknown QR code format"; qWarning() << "URL:" << url.toString(); diff --git a/src/backend/backend.h b/src/backend/backend.h index 4a24e3f3cc8d9eb90f660cd463c4b061fff7e45b..297cc52489fa62a844af2211ab94b2af419e7073 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -42,8 +42,8 @@ public: private: // Other members - std::unique_ptr<ProjectManager> m_projectManager; - std::unique_ptr<QrScanner> m_qrScanner; + QScopedPointer<ProjectManager> m_projectManager; + QScopedPointer<QrScanner> m_qrScanner; // DS Connector QScopedPointer<DesignStudioManager> m_dsManager; diff --git a/src/backend/dsconnector/ds.cpp b/src/backend/dsconnector/ds.cpp index f3282b41194e8f07b60bad0728490a5b2423a442..86bb1fa7c5faa18dc76d5d2cd9662f9f60ba32e0 100644 --- a/src/backend/dsconnector/ds.cpp +++ b/src/backend/dsconnector/ds.cpp @@ -53,7 +53,6 @@ void DesignStudio::initPingPong() }); connect(&m_socket, &QWebSocket::pong, this, [this](quint64 elapsedTime, const QByteArray &) { - qDebug() << "Pong received from Design Studio" << m_id << "in" << elapsedTime << "ms"; m_pongTimer.stop(); }); diff --git a/src/backend/qrscanner.cpp b/src/backend/qrscanner.cpp index 3c507e45b35ea4999d3f4a23747ff83438584185..d6c2b7f788f0d65fcf01a2f525861ad906b47b9b 100644 --- a/src/backend/qrscanner.cpp +++ b/src/backend/qrscanner.cpp @@ -82,57 +82,53 @@ void QrScanner::openCamera() m_captureSession.reset(new QMediaCaptureSession(this)); m_captureSession->setCamera(new QCamera(this)); m_captureSession->setVideoOutput(new CustomVideoWidget); - m_captureSession->camera()->setFocusMode(QCamera::FocusModeAuto); - CustomVideoWidget *videoWidget = qobject_cast<CustomVideoWidget *>( - m_captureSession->videoOutput()); + m_videoWidget = qobject_cast<CustomVideoWidget *>(m_captureSession->videoOutput()); + m_processing = 0; + ZXing::ReaderOptions readerOptions; + readerOptions.setTryRotate(false); + readerOptions.setTryHarder(false); + readerOptions.setTryInvert(false); + readerOptions.setDownscaleFactor(2); connect(m_captureSession->videoSink(), &QVideoSink::videoFrameChanged, this, - [&](const QVideoFrame &frame) { - static int i = 0; - static QAtomicInt running = 0; - - if (i++ < 20 || running > 0) { + [&, readerOptions](const QVideoFrame &frame) { + if (!frame.isValid()) return; - } - i = 0; + if (!m_processing.testAndSetOrdered(0, 1)) { + return; // Another task is already running + } QtConcurrent::run([=] { - // lock the thread so that only one barcode can be read at a time - running++; + if (!m_captureSession) + return QList<Result>(); QElapsedTimer timer; timer.start(); - QList<Result> results = ReadBarcodes(frame.toImage()); + QList<Result> results = ReadBarcodes(frame.toImage(), readerOptions); qDebug() << "Barcode detection took" << timer.elapsed() << "ms"; - // release the lock so that another barcode can be read - running--; + if (!results.size()) + m_processing = 0; + return results; }).then([=](const QList<Result> &results) { if (results.isEmpty() || !m_captureSession) return; - qDebug() << "Stopping camera"; - qobject_cast<CustomVideoWidget *>(m_captureSession->videoOutput())->close(); - qDebug() << "Camera stopped"; - Result result = results.first(); qDebug() << "Text: " << result.text(); qDebug() << "Format: " << result.format(); qDebug() << "Content:" << result.contentType(); + qDebug() << "Position:" << result.position().bottomLeft() + << result.position().bottomRight() << result.position().topLeft() + << result.position().topRight(); - // we have to use invokeMethod because we are in a different thread - // then where the serviceConnector is created - // QMetaObject::invokeMethod(this, - // "parseDesignViewerUrl", - // Qt::QueuedConnection, - // Q_ARG(QUrl, result.text())); emit qrCodeScanned(result.text()); }); }); @@ -148,15 +144,12 @@ void QrScanner::openCamera() }); // stop camera when video widget is closed - connect(videoWidget, &CustomVideoWidget::closed, this, [&] { - qDebug() << "Video widget closed. Clearing capture session"; - m_captureSession->camera()->stop(); - m_captureSession->camera()->deleteLater(); - m_captureSession->videoOutput()->deleteLater(); - m_captureSession.clear(); + connect(m_videoWidget, &CustomVideoWidget::closed, this, [&] { + qDebug() << "Video widget closed."; + emit windowClosed(); }); - videoWidget->setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint); - videoWidget->show(); + m_videoWidget->setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint); + m_videoWidget->show(); m_captureSession->camera()->start(); } diff --git a/src/backend/qrscanner.h b/src/backend/qrscanner.h index dab9787be7acad7aba79bace92fca2f0a5642d66..8931d4992ddfe053306df530e0aaaf7d71e702ee 100644 --- a/src/backend/qrscanner.h +++ b/src/backend/qrscanner.h @@ -25,7 +25,9 @@ #pragma once +#include <QList> #include <QMediaCaptureSession> +#include <QRect> #include <QVideoWidget> class CustomVideoWidget : public QVideoWidget @@ -35,8 +37,8 @@ public: explicit CustomVideoWidget(QWidget *parent = nullptr) : QVideoWidget(parent) {} - ~CustomVideoWidget() override {} + ~CustomVideoWidget() override {} void closeEvent(QCloseEvent *) override { emit closed(); } signals: @@ -52,9 +54,12 @@ public: private: QSharedPointer<QMediaCaptureSession> m_captureSession; + CustomVideoWidget *m_videoWidget; + QAtomicInt m_processing; void openCamera(); signals: void qrCodeScanned(const QString &qrCode); + void windowClosed(); };