私はマルチスレッドの専門家ではありません。 GUIはメインスレッドで管理する必要がありますが、私はメインスレッドが同時に実行するには2つのことが必要です。 状況は次のとおりです。Qtマルチスレッド:2つのQLabelsを更新するには?
ユーザがプッシュボタンをクリックすると(セルフタイマーを取る)、カウントダウンタイマーが開始されます(3秒)。ユーザーはQLabelで毎秒変化する数字3-2を見ることができます。一方、ユーザは同じウィンドウの別のQLabelでカメラデータを見ることができます。いつも私はいくつかの困難を持っていたカメラ
からのライブvideostramでタイマー
- 更新QLabel1:
つまりmainthreadは、2つのことを行う必要がありますこれを達成する。誰かが私を助けてくれますか? 私は必ずしも簡単なトリック/回避策を求めているわけではありません。
:私ははあなたに
私の現在のコードをありがとう...私はこの技術についての私の知識を向上させ、一度だけ簡単/迅速な回避策を使用することはできませんそのようにマルチスレッドを使用したいです
私が試したこと:ユーザーがbtnTakeSnapというボタンをクリックすると、新しいスレッドが開始され、そのスレッドでtimerがカウントダウンを開始し、labelTimeSnapを更新します(これはQLabelで番号3-0の "fancy"画像を読み込みます) 。タイマーが0に達すると、画像が撮影されます。
しかし、QLabelがタイマーで更新されることはありません。突然0が私のQLabelに表示されるのは0に達したときだけです。
アドバイスはありますか?
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(); }
サブスレッドとメインスレッド間の通信に信号とスロットを使用します。 5番目のパラメータが 'Qt :: QueuedConnection'で' connect() 'を使用していることを確認してください。これは、スロットがメインスレッドで実行されることを保証します。直接、サブスレッド内のGUI要素を直接変更することはありません –