QObject::moveToThread() 打开相机

来源:互联网 发布:张家港软件动漫产业园 编辑:程序博客网 时间:2024/04/29 04:26

这也许是Qt推荐的方法吧。

The QThread class provides a platform-independent way to manage threads.

QThread类提供了一个跨平台的方式管理线程

A QThread object manages one thread of control within the program.QThreads begin executing inrun(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.

一个QThread对象在程序中管理一个线程。QThread在run()中开始执行,默认的,run()通过调用exec()开始了事件循环,在这个线程内部运行着event loop。

You can use worker objects by moving them to the thread using QObject::moveToThread().

可以将工作对象通过 QObject::moveToThread(). 放置到一个线程中去。

方法如下:1、定义一个工作对象类 继承自 QObject,定义好槽与信号,2、在控制对象中 实例化 QThread 及 工作对象类,将该对象实例 moveToThread 。3、链接信号与槽

  class Worker : public QObject  {      Q_OBJECT  public slots:      void doWork(const QString ¶meter) {          QString result;          /* ... here is the expensive or blocking operation ... */          emit resultReady(result);      }  signals:      void resultReady(const QString &result);  };  class Controller : public QObject  {      Q_OBJECT      QThread workerThread;  public:      Controller() {          Worker *worker = new Worker;          worker->moveToThread(&workerThread);          connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);          connect(this, &Controller::operate, worker, &Worker::doWork);          connect(worker, &Worker::resultReady, this, &Controller::handleResults);          workerThread.start();      }      ~Controller() {          workerThread.quit();          workerThread.wait();      }  public slots:      void handleResults(const QString &);  signals:      void operate(const QString &);  };

The code inside the Worker's slot would then execute in a separate thread. However, you are free to connect the Worker's slots to any signal, from any object, in any thread. It is safe to connect signals and slots across different threads, thanks to a mechanism called queued connections.

在工作对象中的槽将会在一个新的线程中执行。可以将工作对象中的槽与来自任何线程中任何对象的任何信号链接。即使是跨线程的链接也是安全的,这种结果获益于queued connections机制。

在前面的那个调用相机的例子中,线程只是在while循环中拍图,告诉ui我把图拍好了,然后ui去把图显示,ui并没有告诉线程,我把图显示完了,你拍下一张吧。这种访问是不安全的 需要对 ho_img变量上锁。

如果采用现在的move to thread 方法就可以激活事件机制了, 线程拍好图 告诉 ui, ui得到信号后 显示图, 显示好了 再给线程 信号 我好了 你继续。

如果采用现在的move to thread 方法就可以激活事件机制了, 线程拍好图 告诉 ui, ui得到信号后 显示图, 显示好了 再给线程 信号 我好了 你继续。

1、dialog与myWork在不同的线程

2、myThread指针指向的线程 与 myWork lives in 线程一样

3、和前面的方法比,线程间的 信号 槽 链接 打通了,为以后做更大的扩展 提供了方便

代码

myWork.h

#ifndef MYWORK_H#define MYWORK_H#include <QObject>#include "HalconCpp.h"using namespace HalconCpp;class MyWork:public QObject{    Q_OBJECTpublic:    MyWork();public slots:    void imgGrab();signals:    void imgGrabedSignal();public:    HObject *pHo_Image;    HTuple  *pHv_AcqHandle;};#endif // MYWORK_H

myWork.cpp

#include "mywork.h"#include <QObject>#include <QDebug>#include <QThread>MyWork::MyWork(){}void MyWork::imgGrab(){    try    {        GrabImage(pHo_Image, *pHv_AcqHandle);    }    catch (HException &except)    {        if (except.ErrorCode() == H_ERR_FNF)        {            // Handle file not found error        }        else        {            // Pass on unexpected error to caller            throw except;        }    }    qDebug()<<"myWork slot"<<thread();    qDebug()<<"An image was grabed";    emit imgGrabedSignal();}

dialog.h

#ifndef DIALOG_H#define DIALOG_H#include <QDialog>#include <QThread>#include "mywork.h"#include "HalconCpp.h"using namespace HalconCpp;namespace Ui {class Dialog;}class Dialog : public QDialog{    Q_OBJECTpublic:    explicit Dialog(QWidget *parent = 0);    ~Dialog();private:    Ui::Dialog *ui;protected:    void resizeEvent(QResizeEvent*);    //从写resize事件public:    HObject ho_Image;    HTuple  hv_AcqHandle;    HTuple hv_Width, hv_Height, hv_WindosID;    QThread *myThread;    MyWork *myWork;    Hlong winID;public slots:    void imgShowUpdate();    void continueGrabStartAndStop(bool flagGrab);signals:    void again();};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"#include "ui_dialog.h"#include <QDebug>#include <QThread>#include "mywork.h"Dialog::Dialog(QWidget *parent) :    QDialog(parent),    ui(new Ui::Dialog){    ui->setupUi(this);    winID = (Hlong)ui->imgShowLabel->winId();    SetCheck("~father");    OpenWindow(0,0,(Hlong)ui->imgShowLabel->width(),(Hlong)ui->imgShowLabel->height(),winID,"","",&hv_WindosID);    SetCheck("father");    myThread = new QThread ;    myWork = new MyWork;    myWork->pHo_Image = &ho_Image;    myWork->pHv_AcqHandle = &hv_AcqHandle;    myWork->moveToThread(myThread);    connect(myThread,SIGNAL(started()),myWork,SLOT(imgGrab()));    connect(myWork,SIGNAL(imgGrabedSignal()),this,SLOT(imgShowUpdate()));    connect(this,SIGNAL(again()),myWork,SLOT(imgGrab()));    connect(ui->continueGrabCheckBox,SIGNAL(clicked(bool)),this,SLOT(continueGrabStartAndStop(bool)));}Dialog::~Dialog(){    delete ui;}void Dialog::imgShowUpdate(){    DispObj(ho_Image,hv_WindosID);    qDebug()<<"dialog slot in :"<<thread();    qDebug()<<"where is myThread:"<<myThread;    qDebug()<<"The image showed on, need next";    emit again();}void Dialog::continueGrabStartAndStop(bool flagGrab){    if(flagGrab)    {        OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false",            "default", "[0] Lenovo EasyCamera", 0, -1, &hv_AcqHandle);        GrabImage(&ho_Image, hv_AcqHandle);        GetImageSize(ho_Image,&hv_Width,&hv_Height);        SetPart(hv_WindosID,0,0,hv_Height-1,hv_Width-1);        myThread->start();    }    else    {        myThread->quit();        myThread->wait();        CloseFramegrabber(hv_AcqHandle);    }}void Dialog::resizeEvent(QResizeEvent *){    SetWindowExtents(hv_WindosID,0,0,(Hlong)ui->imgShowLabel->width(),(Hlong)ui->imgShowLabel->height());}


0 0
原创粉丝点击