[libcamera-devel] [PATCH 3/6] qcam: Introduce a toolbar and camera switching

Kieran Bingham kieran.bingham at ideasonboard.com
Thu Feb 6 16:05:01 CET 2020


Implement a quit button, and a list of cameras.

Selecting a different camera from the Toolbar will stop the current
stream, and start streaming the chosen camera device if it can be
acquired.

Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---
 src/qcam/main_window.cpp | 60 ++++++++++++++++++++++++++++++++++++++++
 src/qcam/main_window.h   |  4 +++
 2 files changed, 64 insertions(+)

diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index b51a16de199d..1c7260f32d0a 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -13,6 +13,8 @@
 #include <QCoreApplication>
 #include <QInputDialog>
 #include <QTimer>
+#include <QToolBar>
+#include <QToolButton>
 
 #include <libcamera/camera_manager.h>
 #include <libcamera/version.h>
@@ -27,6 +29,8 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
 {
 	int ret;
 
+	createToolbars(cm);
+
 	title_ = "QCam " + QString::fromStdString(CameraManager::version());
 	setWindowTitle(title_);
 	connect(&titleTimer_, SIGNAL(timeout()), this, SLOT(updateTitle()));
@@ -53,6 +57,31 @@ MainWindow::~MainWindow()
 	}
 }
 
+int MainWindow::createToolbars(CameraManager *cm)
+{
+	QAction *action;
+
+	toolbar_ = addToolBar("");
+
+	action = toolbar_->addAction("Quit");
+	connect(action, &QAction::triggered, this, &MainWindow::quit);
+
+	QAction *cameraAction = new QAction("&Cameras", this);
+	toolbar_->addAction(cameraAction);
+
+	QToolButton *cameraButton = dynamic_cast<QToolButton *>(toolbar_->widgetForAction(cameraAction));
+
+	cameraButton->setPopupMode(QToolButton::InstantPopup);
+
+	for (const std::shared_ptr<Camera> &cam : cm->cameras()) {
+		action = new QAction(QString::fromStdString(cam->name()));
+		cameraButton->addAction(action);
+		connect(action, &QAction::triggered, this, [=]() { this->setCamera(cam); });
+	}
+
+	return 0;
+}
+
 void MainWindow::quit()
 {
 	QTimer::singleShot(0, QCoreApplication::instance(),
@@ -72,6 +101,37 @@ void MainWindow::updateTitle()
 	setWindowTitle(title_ + " : " + QString::number(fps, 'f', 2) + " fps");
 }
 
+int MainWindow::setCamera(const std::shared_ptr<Camera> &cam)
+{
+	std::cout << "Chose " << cam->name() << std::endl;
+
+	if (cam->acquire()) {
+		std::cout << "Failed to acquire camera" << std::endl;
+		return -EBUSY;
+	}
+
+	std::cout << "Switching to camera " << cam->name() << std::endl;
+
+	stopCapture();
+	camera_->release();
+
+	/*
+	 * If we don't disconnect this signal, it will persist (and get
+	 * re-added and thus duplicated later if we ever switch back to an
+	 * previously streamed camera). This causes all sorts of pain.
+	 *
+	 * Perhaps releasing a camera should disconnect all (public?) connected
+	 * signals forcefully!
+	 */
+	camera_->requestCompleted.disconnect(this, &MainWindow::requestComplete);
+	camera_ = cam;
+	camera_->requestCompleted.connect(this, &MainWindow::requestComplete);
+
+	startCapture();
+
+	return 0;
+}
+
 std::string MainWindow::chooseCamera(CameraManager *cm)
 {
 	QStringList cameras;
diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
index a11443b30b37..f7c96fdd5c30 100644
--- a/src/qcam/main_window.h
+++ b/src/qcam/main_window.h
@@ -44,7 +44,10 @@ private Q_SLOTS:
 	void quit();
 	void updateTitle();
 
+	int setCamera(const std::shared_ptr<Camera> &cam);
+
 private:
+	int createToolbars(CameraManager *cm);
 	std::string chooseCamera(CameraManager *cm);
 	int openCamera(CameraManager *cm);
 
@@ -71,6 +74,7 @@ private:
 	uint32_t previousFrames_;
 	uint32_t framesCaptured_;
 
+	QToolBar *toolbar_;
 	ViewFinder *viewfinder_;
 	std::map<int, std::pair<void *, unsigned int>> mappedBuffers_;
 };
-- 
2.20.1



More information about the libcamera-devel mailing list