Hi, I wanted to create a test project to use my webcam to take a still picture and save it as a file.
I'm using Qt 5.3.1 on Windows7 and Qt 5.5.1 on Xubuntu 14
The code is identical in both platforms, but in my Mainwindows application, I have to different ways of taking the picture:
- The first way involves creating a QCamera, a QCameraViewfinder and a QCameraImageCapture from within the Mainwindow. One slot creates the camera and viewfinder which it displays as a separate window. The second slot attempts to capture the image so as to save to a file.
- The second way is to create a separate dialog box which has the QCameraViewfinder inside a QLayout. Most of the dialog is designed with the QtDesigner inside QtCreator,
and the QCameraViewfinder is appended (by hand written code) as a widget to the vertical layout I have used to align a btCapture button and a stop button.
It's a surprise to me that the first method works on Xubuntu, but not on Windows: I get a message
failed to start
Stream did not open
in Windows (with a black viewfinder)
but a small and functional viewfinder in Xubuntu.
The problem with this is that I get a lot of
QWidget:: paintEngine: Should no longer be called
messages.
The second solution works in Windows without a problem, but on Xubuntu I get a lot of
QWidget:: paintEngine: Should no longer be called
messages.
I dont know if those messages signal danger!
Of course a nice small fully working example would be welcome.
Now here is the code. In the mainwindow.cpp file I have this
MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow),
m_QCamera(NULL),
m_QCameraImageCapture(NULL),
m_QCameraViewfinder(NULL),
m_DialogViewer(NULL)
{
ui->setupUi(this);
m_DialogViewer = new DialogViewer(this);
connect(ui->actionCount_cameras,SIGNAL(triggered(bool)),this, SLOT(slotCountCameras()));
connect(ui->actionViewfinder,SIGNAL(triggered(bool)),this,SLOT(slotViewfinder1()));
connect(ui->actionCapture_Image,SIGNAL(triggered(bool)),this,SLOT(slotCaptureImage1()));
connect(ui->actionCapture_Image2,SIGNAL(triggered(bool)),this,SLOT(slotCaptureImage2()));
connect(ui->actionViewer_dialog,SIGNAL(triggered(bool)),this,SLOT(slotDialogViewer()));
}
MainWindow::~MainWindow()
{
delete ui;
if(m_QCamera)
delete m_QCamera;
if(m_QCameraImageCapture)
delete m_QCameraImageCapture;
if(m_QCameraViewfinder)
delete m_QCameraViewfinder;
if(m_DialogViewer)
delete m_DialogViewer;
}
void MainWindow
::tracemsg(QString s
) {
ui->plainTextEdit1->append(s);
}
void MainWindow::slotCountCameras()
{
int camera_count = QCameraInfo::availableCameras().count();
tracemsg(tr("Number of cameras connected = %1").arg(camera_count));
for(int i = 0; i < camera_count;i++)
{
QCameraInfo caminfo = QCameraInfo::availableCameras().at(i);
tracemsg(tr("device name = %1").arg(caminfo.deviceName()));
tracemsg(tr("description = %1").arg(caminfo.description()));
}
}
// adaptation of code in http://doc.qt.io/qt-5/cameraoverview.html
void MainWindow::slotViewfinder1()
{
m_QCamera = new QCamera;
m_QCamera->setCaptureMode(QCamera::CaptureStillImage);
m_QCameraViewfinder = new QCameraViewfinder;
m_QCamera->setViewfinder(m_QCameraViewfinder);
m_QCameraViewfinder->show();
m_QCamera->start(); // to start the viewfinder
}
void MainWindow::slotCaptureImage1()
{
if(m_QCameraImageCapture)
delete m_QCameraImageCapture;
m_QCameraImageCapture = new QCameraImageCapture(m_QCamera);
m_QCameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
tracemsg(tr("Codec used = %1").arg(m_QCameraImageCapture->encodingSettings().codec()));
connect(m_QCameraImageCapture,
SIGNAL(imageCaptured
(int,
QImage)),
this,
SLOT(slotSaveImage1
(int,
QImage)));
if(m_QCameraImageCapture->isAvailable())
{
m_QCameraImageCapture->capture("");
}
else
{
tracemsg(tr("Capture not available"));
}
}
void MainWindow::slotCaptureImage2()
{
if(m_QCameraImageCapture)
delete m_QCameraImageCapture;
m_QCameraImageCapture = new QCameraImageCapture(m_QCamera);
m_QCameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
tracemsg(tr("Codec used = %1").arg(m_QCameraImageCapture->encodingSettings().codec()));
if(m_QCameraImageCapture->isAvailable())
{
m_QCameraImageCapture->capture("Portrait2.jpg");
}
else
{
tracemsg(tr("Capture not available"));
}
}
void MainWindow
::slotSaveImage1(int id,
QImage img
) {
tracemsg(tr("id save image received %1").arg(id));
img.save(tr("Portrait1.jpg"),"JPEG") ;
}
void MainWindow::slotDialogViewer()
{
m_DialogViewer->show();
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
m_QCamera(NULL),
m_QCameraImageCapture(NULL),
m_QCameraViewfinder(NULL),
m_DialogViewer(NULL)
{
ui->setupUi(this);
m_DialogViewer = new DialogViewer(this);
connect(ui->actionCount_cameras,SIGNAL(triggered(bool)),this, SLOT(slotCountCameras()));
connect(ui->actionViewfinder,SIGNAL(triggered(bool)),this,SLOT(slotViewfinder1()));
connect(ui->actionCapture_Image,SIGNAL(triggered(bool)),this,SLOT(slotCaptureImage1()));
connect(ui->actionCapture_Image2,SIGNAL(triggered(bool)),this,SLOT(slotCaptureImage2()));
connect(ui->actionViewer_dialog,SIGNAL(triggered(bool)),this,SLOT(slotDialogViewer()));
}
MainWindow::~MainWindow()
{
delete ui;
if(m_QCamera)
delete m_QCamera;
if(m_QCameraImageCapture)
delete m_QCameraImageCapture;
if(m_QCameraViewfinder)
delete m_QCameraViewfinder;
if(m_DialogViewer)
delete m_DialogViewer;
}
void MainWindow::tracemsg(QString s)
{
ui->plainTextEdit1->append(s);
}
void MainWindow::slotCountCameras()
{
int camera_count = QCameraInfo::availableCameras().count();
tracemsg(tr("Number of cameras connected = %1").arg(camera_count));
for(int i = 0; i < camera_count;i++)
{
QCameraInfo caminfo = QCameraInfo::availableCameras().at(i);
tracemsg(tr("device name = %1").arg(caminfo.deviceName()));
tracemsg(tr("description = %1").arg(caminfo.description()));
}
}
// adaptation of code in http://doc.qt.io/qt-5/cameraoverview.html
void MainWindow::slotViewfinder1()
{
m_QCamera = new QCamera;
m_QCamera->setCaptureMode(QCamera::CaptureStillImage);
m_QCameraViewfinder = new QCameraViewfinder;
m_QCamera->setViewfinder(m_QCameraViewfinder);
m_QCameraViewfinder->show();
m_QCamera->start(); // to start the viewfinder
}
void MainWindow::slotCaptureImage1()
{
if(m_QCameraImageCapture)
delete m_QCameraImageCapture;
m_QCameraImageCapture = new QCameraImageCapture(m_QCamera);
m_QCameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
tracemsg(tr("Codec used = %1").arg(m_QCameraImageCapture->encodingSettings().codec()));
connect(m_QCameraImageCapture,SIGNAL(imageCaptured(int,QImage)),this, SLOT(slotSaveImage1(int,QImage)));
if(m_QCameraImageCapture->isAvailable())
{
m_QCameraImageCapture->capture("");
}
else
{
tracemsg(tr("Capture not available"));
}
}
void MainWindow::slotCaptureImage2()
{
if(m_QCameraImageCapture)
delete m_QCameraImageCapture;
m_QCameraImageCapture = new QCameraImageCapture(m_QCamera);
m_QCameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
tracemsg(tr("Codec used = %1").arg(m_QCameraImageCapture->encodingSettings().codec()));
if(m_QCameraImageCapture->isAvailable())
{
m_QCameraImageCapture->capture("Portrait2.jpg");
}
else
{
tracemsg(tr("Capture not available"));
}
}
void MainWindow::slotSaveImage1(int id, QImage img)
{
tracemsg(tr("id save image received %1").arg(id));
img.save(tr("Portrait1.jpg"),"JPEG") ;
}
void MainWindow::slotDialogViewer()
{
m_DialogViewer->show();
}
To copy to clipboard, switch view to plain text mode
Here is the code of DialogViewer
#include <QCamera>
#include <QMessageBox>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include "dialogviewer.h"
#include "ui_dialogviewer.h"
DialogViewer
::DialogViewer(QWidget *parent
) : ui(new Ui::DialogViewer),
m_QCamera(NULL),
m_QCameraImageCapture(NULL),
m_QCameraViewfinder(NULL)
{
ui->setupUi(this);
m_QCamera = new QCamera(this);
m_QCameraViewfinder = new QCameraViewfinder(this);
m_QCameraViewfinder->setBaseSize(600,800);
m_QCameraViewfinder->setSizePolicy(policy);
m_QCamera->setViewfinder(m_QCameraViewfinder);
ui->verticalLayout->addWidget(m_QCameraViewfinder);
m_QCamera->start(); // to start the viewfinder
}
void DialogViewer
::tracemsg(QString s
) {
}
DialogViewer::~DialogViewer()
{
delete ui;
}
void DialogViewer::on_btCapture_clicked()
{
m_QCameraImageCapture = new QCameraImageCapture(m_QCamera);
m_QCameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
//connect(m_QCameraImageCapture,SIGNAL(imageCaptured(int,QImage)),this, SLOT(slotSaveImage1(int,QImage)));
if(m_QCameraImageCapture->isAvailable())
{
QString file("portrait_from_dialog.jpg");
m_QCameraImageCapture->capture(file);
}
else
{
tracemsg(tr("Capture not available"));
}
}
void DialogViewer::on_stop_clicked()
{
close();
}
#include <QCamera>
#include <QMessageBox>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include "dialogviewer.h"
#include "ui_dialogviewer.h"
DialogViewer::DialogViewer(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogViewer),
m_QCamera(NULL),
m_QCameraImageCapture(NULL),
m_QCameraViewfinder(NULL)
{
ui->setupUi(this);
QSizePolicy policy(QSizePolicy::Preferred,QSizePolicy::Preferred,QSizePolicy::DefaultType);
m_QCamera = new QCamera(this);
m_QCameraViewfinder = new QCameraViewfinder(this);
m_QCameraViewfinder->setBaseSize(600,800);
m_QCameraViewfinder->setSizePolicy(policy);
m_QCamera->setViewfinder(m_QCameraViewfinder);
ui->verticalLayout->addWidget(m_QCameraViewfinder);
m_QCamera->start(); // to start the viewfinder
}
void DialogViewer::tracemsg(QString s)
{
QMessageBox::critical(this,tr("error"),s);
}
DialogViewer::~DialogViewer()
{
delete ui;
}
void DialogViewer::on_btCapture_clicked()
{
m_QCameraImageCapture = new QCameraImageCapture(m_QCamera);
m_QCameraImageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
//connect(m_QCameraImageCapture,SIGNAL(imageCaptured(int,QImage)),this, SLOT(slotSaveImage1(int,QImage)));
if(m_QCameraImageCapture->isAvailable())
{
QString file("portrait_from_dialog.jpg");
m_QCameraImageCapture->capture(file);
}
else
{
tracemsg(tr("Capture not available"));
}
}
void DialogViewer::on_stop_clicked()
{
close();
}
To copy to clipboard, switch view to plain text mode
For completeness here is Mainwindow.h
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class QCamera;
class QCameraViewfinder;
class QCameraImageCapture;
class DialogViewer;
{
Q_OBJECT
public:
explicit MainWindow
(QWidget *parent
= 0);
~MainWindow();
private slots:
void slotCountCameras();
void slotViewfinder1();
void slotCaptureImage1();
void slotCaptureImage2();
void slotSaveImage1
(int id,
QImage img
);
void slotDialogViewer();
private:
Ui::MainWindow *ui;
QCamera *m_QCamera;
QCameraViewfinder *m_QCameraViewfinder;
QCameraImageCapture *m_QCameraImageCapture;
DialogViewer *m_DialogViewer;
};
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class QCamera;
class QCameraViewfinder;
class QCameraImageCapture;
class DialogViewer;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void tracemsg(QString s);
void slotCountCameras();
void slotViewfinder1();
void slotCaptureImage1();
void slotCaptureImage2();
void slotSaveImage1(int id, QImage img);
void slotDialogViewer();
private:
Ui::MainWindow *ui;
QCamera *m_QCamera;
QCameraViewfinder *m_QCameraViewfinder;
QCameraImageCapture *m_QCameraImageCapture;
DialogViewer *m_DialogViewer;
};
To copy to clipboard, switch view to plain text mode
The code of Dialogviewer.h
#include <QDialog>
class QCamera;
class QCameraViewfinder;
class QCameraImageCapture;
namespace Ui {
class DialogViewer;
}
class DialogViewer
: public QDialog{
Q_OBJECT
public:
explicit DialogViewer
(QWidget *parent
= 0);
~DialogViewer();
private slots:
void on_btCapture_clicked();
void on_stop_clicked();
private:
Ui::DialogViewer *ui;
QCamera *m_QCamera;
QCameraViewfinder *m_QCameraViewfinder;
QCameraImageCapture *m_QCameraImageCapture;
};
#include <QDialog>
class QCamera;
class QCameraViewfinder;
class QCameraImageCapture;
namespace Ui {
class DialogViewer;
}
class DialogViewer : public QDialog
{
Q_OBJECT
public:
explicit DialogViewer(QWidget *parent = 0);
~DialogViewer();
private slots:
void on_btCapture_clicked();
void on_stop_clicked();
private:
Ui::DialogViewer *ui;
QCamera *m_QCamera;
QCameraViewfinder *m_QCameraViewfinder;
QCameraImageCapture *m_QCameraImageCapture;
void tracemsg(QString s);
};
To copy to clipboard, switch view to plain text mode
Bookmarks