————————.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
#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 的控件