[Qt]显示摄像头-4 使用线程

————————.pro——————————-
QT += core gui
QT += core gui widgets # 确保 widgets 模块被包含

CONFIG += link_pkgconfig
PKGCONFIG += opencv4

QT += multimedia multimediawidgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
CameraWorker.cpp \
main.cpp \
mainwindow.cpp

HEADERS += \
CameraWorker.h \
mainwindow.h

FORMS += \
mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

——————————–CameraWorker.h—————————
#ifndef CAMERAWORKER_H
#define CAMERAWORKER_H

#include
#include
#include
#include
#include

class CameraWorker : public QObject {
Q_OBJECT

public:
CameraWorker(QObject *parent = nullptr);
~CameraWorker();
void startCamera(int deviceIndex);
void stopCamera();

signals:
void frameCaptured(const QImage &image);

private:
cv::VideoCapture capture;
QMutex mutex;
bool isRunning;
void process();
};

#endif // CAMERAWORKER_H

————————-CameraWorker.cpp———————————
#include “CameraWorker.h”
#include // 包含 QDebug 以使用 qDebug()
#include

CameraWorker::CameraWorker(QObject *parent) : QObject(parent), isRunning(false) {}

CameraWorker::~CameraWorker() {
stopCamera();
}

void CameraWorker::startCamera(int deviceIndex) {
if (capture.isOpened()) return;

capture.open(deviceIndex);
if (!capture.isOpened()) {
qDebug() << "无法打开摄像头"; // 这里可以正常使用 qDebug() return; } capture.set(cv::CAP_PROP_FRAME_WIDTH, 640); // 设置宽度 capture.set(cv::CAP_PROP_FRAME_HEIGHT, 480); // 设置高度 capture.set(cv::CAP_PROP_FPS, 15); // 设置帧率 capture.set(cv::CAP_PROP_EXPOSURE, -4); // 设置曝光(根据需要调整) capture.set(cv::CAP_PROP_GAIN, 0); // 设置增益(根据需要调整) QThread::msleep(100); // 暂停以让设置生效 isRunning = true; QThread *thread = QThread::create([this]() { process(); }); connect(thread, &QThread::finished, this, &CameraWorker::deleteLater); thread->start();
}

void CameraWorker::stopCamera() {
QMutexLocker locker(&mutex);
isRunning = false;
capture.release();
}

void CameraWorker::process() {
while (true) {
{
QMutexLocker locker(&mutex);
if (!isRunning) break;
}

cv::Mat frame;
capture >> frame;
if (frame.empty()) continue;

cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
QImage image(frame.data, frame.cols, frame.rows, frame.step[0], QImage::Format_RGB888);
emit frameCaptured(image);
QThread::msleep(33); // 限制帧率
}
}

———————-mainwindow.h—————————————–
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include
#include
#include “CameraWorker.h” // 添加这一行以包含 CameraWorker
#include

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow {
Q_OBJECT

public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();

private slots:
void updateCameraFrame(const QImage &image);

private:
Ui::MainWindow *ui;
CameraWorker *cameraWorker; // 确保这个声明是正确的
QThread *cameraThread;
};

#endif // MAINWINDOW_H

——————————mainwindow.cpp————————-
#include “mainwindow.h”
#include “ui_mainwindow.h”

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow), cameraWorker(new CameraWorker) {
ui->setupUi(this);

// 创建线程
cameraThread = new QThread;
cameraWorker->moveToThread(cameraThread);

connect(cameraThread, &QThread::started, [this]() {
cameraWorker->startCamera(0); // 打开默认摄像头
});
connect(cameraThread, &QThread::finished, cameraWorker, &CameraWorker::deleteLater);
connect(cameraWorker, &CameraWorker::frameCaptured, this, &MainWindow::updateCameraFrame);

cameraThread->start();
}

MainWindow::~MainWindow() {
cameraThread->quit();
cameraThread->wait();
delete ui;
}

void MainWindow::updateCameraFrame(const QImage &image) {
ui->cameraLabel->setPixmap(QPixmap::fromImage(image)); // 假设你在 UI 中有一个 QLabel 名为 cameraLabel
}

————————–main.cpp——————————
#include “mainwindow.h”
#include

int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

————————-.ui————————————-
添加名为 cameraLabel 的 QLabel 的控件

发表评论

邮箱地址不会被公开。 必填项已用*标注