I am not a multithreading expert. I know that the GUI should be managed by the main thread, however I'd need 2 things to be done by the mainthread simultanuously. The situation is the following:
The user clicks on a pushbutton (to take a selfie), a count down timer starts (3 seconds). The user can see in a QLabel the numbers 3-2 changing every second. Meanwhile the user can see the camera data in another QLabel of the same window.
In other words the mainthread should do 2 things:
- update QLabel1 to always show the timer
- update QLabel2 with the live videostram from the camera
I am having some difficulties to achieve this. Could someone help me out? I am not necessarily asking for an easy trick/work around. I'd like to use multithreading that way I can improve my knowledge about this technique and not just use a one time easy/quick workaround...
Thank you
My current code:
What I tried: when the user clicks the button called btnTakeSnap a new thread is started and in that thread the timer starts counting down and updating the labelTimeSnap (this is a QLabel in which I load "fancy" images with numbers 3-0). Once the timer reaches 0 a picture is taken.
But I don't see my QLabel being updated with the timer. It is only when 0 is reached that suddenly the number 0 gets displayed in my QLabel.
Any advice?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
snapIndex=1;
QString fileName = "../somePicture.jpg";
QImage imageFrame;
connect(ui->btnTakeSnap, SIGNAL(clicked()), this, SLOT(startTimerWorker()) );
}
void MainWindow::startTimerWorker()
{
timerSnapThread = new QThread(this);
MainWindow *workerTimerSnap = new MainWindow();
connect(timerSnapThread, &QThread::started, workerTimerSnap, &MainWindow::updateTimer);
workerTimerSnap->moveToThread(timerSnapThread);
timerSnapThread->start();
}
void MainWindow::updateTimer()
{
int selectedTimer;
if(ui->rdBtntimer1s->isChecked())
{selectedTimer = 1000;}
if(ui->rdBtntimer3s->isChecked())
{selectedTimer = 3000;}
QString filename;
QImage image;
//timer
if(selectedTimer == 3000) //3 seconds
{
QElapsedTimer t;
t.start();
while (t.elapsed() < selectedTimer)
{
if(t.elapsed()==0)
{
filename = "../../testImages/timer3.png";qDebug()<<"3";
image.load(filename);
image= image.scaled(ui->labelTimeSnap->width(), ui->labelTimeSnap->height(),Qt::KeepAspectRatio);
ui->labelTimeSnap->setPixmap(QPixmap::fromImage(image));
}
if(t.elapsed()==1000)
{
filename = "../../testImages/timer2.png";qDebug()<<"2";
image.load(filename);
image= image.scaled(ui->labelTimeSnap->width(), ui->labelTimeSnap->height(),Qt::KeepAspectRatio);
ui->labelTimeSnap->setPixmap(QPixmap::fromImage(image));
}
if(t.elapsed()==2000)
{
filename = "../../testImages/timer1.png";qDebug()<<"1";
image.load(filename);
image= image.scaled(ui->labelTimeSnap->width(), ui->labelTimeSnap->height(),Qt::KeepAspectRatio);
ui->labelTimeSnap->setPixmap(QPixmap::fromImage(image));
}
}
takeSnap();
}
if(selectedTimer == 1000)
{
QElapsedTimer t;
t.start();
while (t.elapsed() < selectedTimer)
{
if(t.elapsed()==0)
{
filename = "../../testImages/timer1.png";
qDebug()<<"1";
image.load(filename);
image= image.scaled(ui->labelTimeSnap->width(), ui->labelTimeSnap->height(),Qt::KeepAspectRatio);
ui->labelTimeSnap->setPixmap(QPixmap::fromImage(image));
}
if(t.elapsed()==1000)
{
filename = "../../testImages/timer1.png";
qDebug()<<"0";
image.load(filename);
image= image.scaled(ui->labelTimeSnap->width(), ui->labelTimeSnap->height(),Qt::KeepAspectRatio);
ui->labelTimeSnap->setPixmap(QPixmap::fromImage(image));
}
}
takeSnap();
}
}
void MainWindow::takeSnap()
{
static int i=0;
cv::VideoCapture cap(CV_CAP_ANY);
cv::Mat imgFrame;
cap >> imgFrame;
//BGR-> RGB
cv::cvtColor(imgFrame, imgFrame, CV_BGR2RGB);
//Mat -> QPixMap
QImage img;
img = QImage((uchar*)imgFrame.data, imgFrame.cols, imgFrame.rows, QImage::Format_RGB888);
QPixmap pixmap = QPixmap::fromImage(img);
int w = ui->labelSnap1->width();
int h = ui->labelSnap1->height();
if(i==0)
{ui->labelSnap1->setPixmap(pixmap.scaled(w,h,Qt::KeepAspectRatio));}
if(i==1)
{ui->labelSnap2->setPixmap(pixmap.scaled(w,h,Qt::KeepAspectRatio));}
if(i==2)
{ui->labelSnap3->setPixmap(pixmap.scaled(w,h,Qt::KeepAspectRatio));}
i++;
if(i==3){i=0;}
showNextSnap();
}