我不是多线程专家。我知道GUI应该由主线程管理,但是我需要由主线程同时完成两件事情。情况如下:
用户点击一个按钮(采取自拍),一个计数下计时器开始(3秒)。用户可以在QLabel中看到数字3-2每秒钟发生变化.同时,用户可以在同一窗口的另一个QLabel中看到相机数据。
换句话说,主线程应该做两件事:
要做到这一点,我有一些困难。有人能帮我吗?我不一定要求一个简单的技巧/工作。我想使用多线程的方式,我可以提高我的知识,这项技术,而不只是使用一次简单/快速的解决办法.
谢谢
我现在的代码是:
我尝试过的是:当用户单击名为btnTakeSnap的按钮时,将启动一个新线程,在该线程中,计时器开始计数并更新labelTimeSnap (这是一个QLabel,在其中加载数字3-0的“花哨”图像)。一旦计时器达到0,就会拍摄一张照片。
但是我没有看到我的QLabel正在用计时器更新。只有当达到0时,数字0才会突然显示在我的QLabel中。
有什么建议吗?
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();
}发布于 2017-07-22 07:36:02
您可以使用信号将线程通信到一起。
在第二个线程中定义如下所示的信号:
signals:
void changeLabelOnMain(QString text);在第二个线程中发出信号:
emit changeLabelOnMain("some text");将信号连接到主通道的一个插槽:
SecondClassName secondObject= new SecondClassName();
connect(secondObject, &SecondClassName::changeLabelOnMain, this, &MainClassName::YourSlotName);这是一个简单的示例,可以让线程进行通信。
https://stackoverflow.com/questions/45251898
复制相似问题