diff --git a/src/citra_qt/camera/qt_camera_base.cpp b/src/citra_qt/camera/qt_camera_base.cpp
index 65bf2361c..69593ab51 100644
--- a/src/citra_qt/camera/qt_camera_base.cpp
+++ b/src/citra_qt/camera/qt_camera_base.cpp
@@ -40,8 +40,9 @@ std::vector<u16> QtCameraInterface::ReceiveFrame() {
                                     flip_vertical);
 }
 
-std::unique_ptr<CameraInterface> QtCameraFactory::CreatePreview(
-    const std::string& config, int width, int height, const Service::CAM::Flip& flip) const {
+std::unique_ptr<CameraInterface> QtCameraFactory::CreatePreview(const std::string& config,
+                                                                int width, int height,
+                                                                const Service::CAM::Flip& flip) {
     std::unique_ptr<CameraInterface> camera = Create(config, flip);
 
     if (camera->IsPreviewAvailable()) {
diff --git a/src/citra_qt/camera/qt_camera_base.h b/src/citra_qt/camera/qt_camera_base.h
index e66c3bb46..6c6095a28 100644
--- a/src/citra_qt/camera/qt_camera_base.h
+++ b/src/citra_qt/camera/qt_camera_base.h
@@ -30,7 +30,7 @@ private:
 // Base class for camera factories of citra_qt
 class QtCameraFactory : public CameraFactory {
     std::unique_ptr<CameraInterface> CreatePreview(const std::string& config, int width, int height,
-                                                   const Service::CAM::Flip& flip) const override;
+                                                   const Service::CAM::Flip& flip) override;
 };
 
 } // namespace Camera
diff --git a/src/citra_qt/camera/qt_multimedia_camera.cpp b/src/citra_qt/camera/qt_multimedia_camera.cpp
index 05bcbd4f8..ad6bad876 100644
--- a/src/citra_qt/camera/qt_multimedia_camera.cpp
+++ b/src/citra_qt/camera/qt_multimedia_camera.cpp
@@ -106,8 +106,8 @@ bool QtMultimediaCamera::IsPreviewAvailable() {
     return handler->CameraAvailable();
 }
 
-std::unique_ptr<CameraInterface> QtMultimediaCameraFactory::Create(
-    const std::string& config, const Service::CAM::Flip& flip) const {
+std::unique_ptr<CameraInterface> QtMultimediaCameraFactory::Create(const std::string& config,
+                                                                   const Service::CAM::Flip& flip) {
     return std::make_unique<QtMultimediaCamera>(config, flip);
 }
 
diff --git a/src/citra_qt/camera/qt_multimedia_camera.h b/src/citra_qt/camera/qt_multimedia_camera.h
index e6d7b6b6d..14242c554 100644
--- a/src/citra_qt/camera/qt_multimedia_camera.h
+++ b/src/citra_qt/camera/qt_multimedia_camera.h
@@ -54,7 +54,7 @@ private:
 class QtMultimediaCameraFactory final : public QtCameraFactory {
 public:
     std::unique_ptr<CameraInterface> Create(const std::string& config,
-                                            const Service::CAM::Flip& flip) const override;
+                                            const Service::CAM::Flip& flip) override;
 };
 
 class QtMultimediaCameraHandler final : public QObject {
diff --git a/src/citra_qt/camera/still_image_camera.cpp b/src/citra_qt/camera/still_image_camera.cpp
index a166e3336..b466d17df 100644
--- a/src/citra_qt/camera/still_image_camera.cpp
+++ b/src/citra_qt/camera/still_image_camera.cpp
@@ -5,6 +5,7 @@
 #include <QFileDialog>
 #include <QImageReader>
 #include <QMessageBox>
+#include <QThread>
 #include "citra_qt/camera/still_image_camera.h"
 
 namespace Camera {
@@ -24,7 +25,7 @@ bool StillImageCamera::IsPreviewAvailable() {
     return !image.isNull();
 }
 
-const std::string StillImageCameraFactory::GetFilePath() {
+const std::string StillImageCameraFactory::GetFilePath() const {
     QList<QByteArray> types = QImageReader::supportedImageFormats();
     QList<QString> temp_filters;
     for (QByteArray type : types) {
@@ -36,11 +37,18 @@ const std::string StillImageCameraFactory::GetFilePath() {
         .toStdString();
 }
 
-std::unique_ptr<CameraInterface> StillImageCameraFactory::Create(
-    const std::string& config, const Service::CAM::Flip& flip) const {
+std::unique_ptr<CameraInterface> StillImageCameraFactory::Create(const std::string& config,
+                                                                 const Service::CAM::Flip& flip) {
     std::string real_config = config;
     if (config.empty()) {
-        real_config = GetFilePath();
+        // call GetFilePath() in UI thread (note: StillImageCameraFactory itself is initialized in
+        // UI thread, so we can just pass in "this" here)
+        if (thread() == QThread::currentThread()) {
+            real_config = GetFilePath();
+        } else {
+            QMetaObject::invokeMethod(this, "GetFilePath", Qt::BlockingQueuedConnection,
+                                      Q_RETURN_ARG(std::string, real_config));
+        }
     }
     QImage image(QString::fromStdString(real_config));
     if (image.isNull()) {
diff --git a/src/citra_qt/camera/still_image_camera.h b/src/citra_qt/camera/still_image_camera.h
index 80e43ba17..ccfc13211 100644
--- a/src/citra_qt/camera/still_image_camera.h
+++ b/src/citra_qt/camera/still_image_camera.h
@@ -25,13 +25,14 @@ private:
     QImage image;
 };
 
-class StillImageCameraFactory final : public QtCameraFactory {
+class StillImageCameraFactory final : public QObject, public QtCameraFactory {
+    Q_OBJECT
+
 public:
     std::unique_ptr<CameraInterface> Create(const std::string& config,
-                                            const Service::CAM::Flip& flip) const override;
+                                            const Service::CAM::Flip& flip) override;
 
-private:
-    static const std::string GetFilePath();
+    Q_INVOKABLE const std::string GetFilePath() const;
 };
 
 } // namespace Camera
diff --git a/src/core/frontend/camera/factory.h b/src/core/frontend/camera/factory.h
index dc795f0ce..0fe9f314f 100644
--- a/src/core/frontend/camera/factory.h
+++ b/src/core/frontend/camera/factory.h
@@ -22,7 +22,7 @@ public:
      * @returns a unique_ptr to the created camera object.
      */
     virtual std::unique_ptr<CameraInterface> Create(const std::string& config,
-                                                    const Service::CAM::Flip& flip) const = 0;
+                                                    const Service::CAM::Flip& flip) = 0;
 
     /**
      * Creates a camera object for preview based on the configuration string.
@@ -36,7 +36,7 @@ public:
      */
     virtual std::unique_ptr<CameraInterface> CreatePreview(const std::string& config, int width,
                                                            int height,
-                                                           const Service::CAM::Flip& flip) const {
+                                                           const Service::CAM::Flip& flip) {
         return Create(config, flip);
     }
 };