pycanon包不适用于佳能目前的ED SDK,因此我从头开始制作一个新的。进步是一步一步的,但现在我不得不抓住相机的事件,它会调用一个回调机制。它至少有两个问题,它们可能是相互关联的。
首先,这是我调用的回调函数:
def propertyChanged(*args):
print(args)
return window.propertyChanged(*args)
在头文件中,定义为:
#if defined( BUILD_EDSDK_DLL )
#define EDSAPI EDSEXPORT EDSSTDCALL
#else
#define EDSAPI EDSIMPORT EDSSTDCALL
#endif
/*-----------------------------------------------------------------------------
//
// Function: EdsSetPropertyEventHandler
//
// Description:
// Registers a callback function for receiving status
// change notification events for property states on a camera.
//
// Parameters:
// In: inCameraRef - Designate the camera object.
// inEvent - Designate one or all events to be supplemented.
// inPropertyEventHandler - Designate the pointer to the callback
// function for receiving property-related camera events.
// inContext - Designate application information to be passed by
// means of the callback function. Any data needed for
// your application can be passed.
// Out: None
//
// Returns: Any of the sdk errors.
-----------------------------------------------------------------------------*/
EdsError EDSAPI EdsSetPropertyEventHandler(
EdsCameraRef inCameraRef,
EdsPropertyEvent inEvnet,
EdsPropertyEventHandler inPropertyEventHandler,
EdsVoid* inContext );
它或多或少地起作用,因为它被(有时)适当的参数调用。错误的是,当我不在调试器中时,参数似乎被两个longInts抵消了。
查看下面列出的完整测试程序,尤其是run() - 方法。
我期望的是camera.setAEMode(5)
会触发回调。它没有,但camera.getBodyID()
它上面的两行是这样做的,而我不希望这样。我想这只是我对API工作的理解而不是我遇到的问题。
当执行camera.getBodyID()
(testCallback
为真)和propertyChanged中的断点时,我看到我用参数(257,3,0,129568680)调用,这是有意义的:
但是,如果在未调试时运行完全相同,则传递给propertyChanged的参数为(107020331,106511131,257,3)。
还有第二个问题:当我不指定回调函数时,程序运行正常。但是当我将True分配给testCallback
时,程序在从回调返回后崩溃(异常:访问冲突在未调试时读取0x0000002B,或者为了响应getBodyID()而触发PROPERTIES_UNAVAILABLE)。当程序运行时没有触发回调函数(# camera.getBodyID()
),但仍然分配它,然后python.exe在离开run() - 方法后崩溃,并且认为告诉微软有一个好主意。< / p>
我该怎么做才能使这项工作?
from PyQt5.Qt import * # @UnusedWildImport
from canonSDK import edSDK
from canonSDK.edSDK import EDSDK
import traceback
from canonSDK.EDSDKtypes import * # @UnusedWildImport
from ctypes import py_object
# copy of self of the main-window object;
# necessary since it is exceedingly hard to pass self thru the callback
window = None
def propertyChanged(*args):
print(args)
return window.propertyChanged(*args)
class RCmain(QWidget):
def __init__(self):
super().__init__()
global window
window = self
QVBoxLayout(self)
self.console = QTextBrowser()
self.layout().addWidget(self.console)
pnl = QFrame(); self.layout().addWidget(pnl)
pnl.setFixedHeight(30)
btn = QPushButton("run", parent = pnl)
btn.clicked.connect(self.run)
sys.excepthook = self.exceptionHook
def show(self):
super().show()
# initialize dll connection:
self.edsdk = EDSDK()
self.edsdk.initializeSDK()
self.camera = None
# show success by listing the connected cameras:
l = self.edsdk.getCameraList()
n = self.edsdk.getChildCount(l)
self.print(n, "cameras:")
for c in self.edsdk.cameras:
self.print(c.index, ":", c.name)
def close(self):
self.edsdk.terminateSDK()
if self.camera is not None:
self.camera.close()
super().close()
def exceptionHook(self, type, value, tback):
traceback.print_exception(type, value, tback)
def print(self, *args):
print(*args)
self.console.append(" ".join([str(a) for a in args]))
#WINFUNCTYPE (EdsError, EdsPropertyEvent, EdsPropertyID, EdsUInt32, EdsVoid)
def propertyChanged(self, inEvent, inPropertyID, inParam, inContext):
self.print(inEvent, inPropertyID, inParam, inContext)
self.print(EdsPropID(inPropertyID).name, "has changed") # EdsPropID is an IntEnum
return 0
def run(self):
# test sequence
camera = self.edsdk.getCamera(0)
testCallback = True
if testCallback:
self.edsdk.setPropertyEventHandler(camera.reference,
EdsPropertyEvents.All,
EdsPropertyEventHandler(propertyChanged))
self.print(camera.getProductName())
self.print(camera.getBodyID())
self.print(camera.getAEMode())
camera.setAEMode(5)
self.print(camera.getAEMode())
camera.startLiveView()
# camera.downloadEvfData() # 2b impl'd
camera.endLiveView()
self.camera = camera
if __name__ == '__main__':
import sys
edSDK.setDllPath('D:/python3/remote shooting/EDSDKv2.7/EDSDK/Dll')
app = QApplication(sys.argv)
w = RCmain()
w.show()
app.exec_()