2014-05-05 42 views
0

我正在爲在Mac OSX下的Qt佳能相機編程tethering,出於某種原因,我的sdk處理程序未被調用。當我想用相機拍攝時,一切都很順利,但是我的照片沒有下載,因爲EdsSetObjectEventHandler沒有被調用。佳能EDSDK處理程序不在mac上調用

但是由於某些原因,當我用相機拍攝時,然後重新啓動應用程序,然後下載一張照片。我的意見是我需要使用他們的事件循環,但我不知道如何。

我的應用程序不凍結只有處理程序不被調用。我可以拍很多照片(但只能照相機緩存)。

這是我的代碼。

初始化方法

void CameraControl::initEDS() 
{ 
    Q_D(CameraControl); 

    // Camera init 
    EdsUInt32 count = 0; 
    EdsDeviceInfo info; 

    EdsError err = EdsInitializeSDK(); 

    if(err != EDS_ERR_OK) 
     qFatal("Error: Could not initialize library!"); 

    EdsCameraListRef cameraList = NULL; 

    if(EdsGetCameraList(&cameraList) != EDS_ERR_OK) 
     qFatal("Error: Could not get camera list!"); 

    if(EdsGetChildCount(cameraList, &count) != EDS_ERR_OK) 
     qFatal("Error: Could not get number of cameras!"); 

    if(EdsGetChildAtIndex(cameraList, 0, &(d->m_camera)) != EDS_ERR_OK) 
     qFatal("Error: Could not get camera!"); 

    if(EdsGetDeviceInfo(d->m_camera, &info) != EDS_ERR_OK) 
     qFatal("Error: Could not get camera info!"); 

    EdsRelease(cameraList); 

    // Register handler - this are not called 
    if(EdsSetObjectEventHandler(d->m_camera, kEdsObjectEvent_All, handleObjectEvent, (EdsVoid*)this) != EDS_ERR_OK) 
    { 
     qFatal("Error: can't setup object handler"); 
    } 

    if(info.deviceSubType == 0) 
     d->m_isLegacy = true; 
    else 
     d->m_isLegacy = false; 

    // open session 
    if(EdsOpenSession(d->m_camera) != EDS_ERR_OK) 
     qFatal("Can't open session with camera"); 

    sleep(1); 

    EdsUInt32 saveTo = kEdsSaveTo_Host; 
    if(EdsSetPropertyData(d->m_camera, kEdsPropID_SaveTo, 0, sizeof(saveTo), &saveTo) != EDS_ERR_OK) 
     qFatal("Error: can't get property for saveTo"); 

    if(!d->m_isLegacy) 
    { 
     EdsCapacity capacity = {0x7FFFFFFF, 0x1000, 1}; 

     if(EdsSetCapacity(d->m_camera, capacity) != EDS_ERR_OK) 
     qFatal("Error: can't set capacity"); 
    } 

    // get property camera name 
    EdsUInt32 dataSize = 0; 
    EdsDataType dataType = kEdsDataType_Unknown; 
    EdsChar dataString[EDS_MAX_NAME]; 

    if(EdsGetPropertySize(d->m_camera, kEdsPropID_ProductName, 0, &dataType, &dataSize) != EDS_ERR_OK) 
     qFatal("Can't get property size"); 

    if(dataType == kEdsDataType_String) 
    { 
     qDebug() << "property is string"; 

     if(EdsGetPropertyData(d->m_camera, kEdsPropID_ProductName, 0, dataSize, &dataString) != EDS_ERR_OK) 
      qFatal("Can't get product name of camera"); 
    } 

} 

捕獲方法

void CameraControl::capture() 
{ 
    Q_D(CameraControl); 

    EdsError err; 
    if((err = EdsSendCommand(d->m_camera, kEdsCameraCommand_TakePicture, 0)) != EDS_ERR_OK) 
    { 
     QString str = QString("Error: can't shoot with camera - code: %1").arg(QString::number(err, 16)); 

     qDebug() << str; 
    } 
    else 
     qDebug() << "picture taken"; 
} 

處理程序方法

EdsError EDSCALLBACK handleObjectEvent(EdsUInt32 inEvent, EdsBaseRef inRef, EdsVoid* inContext) 
{ 
    EdsError err = EDS_ERR_OK; 
    CameraControl* control = static_cast<CameraControl*>(inContext); 

    qDebug() << "object handler called"; // never called 

    switch(inEvent) 
    { 
    case kEdsObjectEvent_DirItemRequestTransfer: 
     download(inRef, control); // download photo 
    default: 
     EdsRelease(inRef); 
    } 

    return EDS_ERR_OK; 
} 

甲尼永知道爲什麼會發生這種情況?感謝您的幫助。

回答

0

編輯 - 已解決

我找到解決這個。 當你使用EDSDK時,你需要平臺特定的事件循環運行,但問題是你需要它在主線程內,因爲所有的usb事件都在那裏。 所以問題aaised - 你需要平臺特定的事件循環,但在你需要的同一線程(在我的情況)Qt事件循環。

解決方案

你需要同時運行Mac事件循環時間的時間來處理新的事件。 所以我創建了processEvents()方法,並且這個方法有CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false),它處理隊列中的所有事件。

構造我的對象有新的計時器

Q_D(CameraControl); 
d->m_timer.setInterval(500); 
d->m_timer.setSingleShot(false); 
connect(&d->m_timer, &QTimer::timeout, this, &CameraControl::processEvents); 
d->m_timer.start(); 

定時器調用這個口法

void CameraControl::processEvents() 
{ 
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); 
} 

我希望這將幫助別人同樣的問題。

相關問題