Cannot pass arguments to ActiveX COM object using

2019-03-04 06:07发布

问题:

I'm trying to write some Python code to talk to the Thorlabs APT ActiveX control. I'm basing my code on the code found on this page, but trying to use PyQt4 ActiveX container instead of the wxPython ActiveX container. It works for a very simple ActiveX methods, however, I get an error when trying to call a method that takes arguments.

This code works and shows the about box for Thorlabs APT:

import sys
from ctypes import *

from PyQt4 import QtGui
from PyQt4 import QAxContainer

class APTSystem(QAxContainer.QAxWidget):

    def __init__(self, parent):
        self.parent = parent
        super(APTSystem, self).__init__()

        self.setControl('{B74DB4BA-8C1E-4570-906E-FF65698D632E}')

        # calling this method works    
        self.AboutBox()

app = QtGui.QApplication(sys.argv)        
a = APTSystem(app)

When I replace self.AboutBox() with a method with arguments e.g.:

num_units = c_int()
self.GetNumHWUnitsEx(21, byref(num_units))

I get an error: TypeError: unable to convert argument 1 of APTSystem.GetNumHWUnitsEx from 'CArgObject' to 'int&'

I presume the argument type needs to be a ctypes type. Is there some ctypes magic that can solve this?

回答1:

Turns out I had the syntax quite wrong, worked it out by using the generateDocumentation() function as mentioned here, and some parameter help from here. The working code looks like:

import sys
from PyQt4 import QtGui
from PyQt4 import QAxContainer
from PyQt4.QtCore import QVariant

class APTSystem(QAxContainer.QAxWidget):

    def __init__(self, parent):

        super(APTSystem, self).__init__()

        # connect to control
        self.setControl('{B74DB4BA-8C1E-4570-906E-FF65698D632E}')

        # required by device
        self.dynamicCall('StartCtrl()')

        # args must be list of QVariants
        typ = QVariant(6)
        num = QVariant(0)
        args = [typ, num]

        self.dynamicCall('GetNumHWUnits(int, int&)', args)

        # only list items are updated, not the original ints!
        if args[1].toInt()[1]:
            print 'Num of HW units =', args[1].toInt()[0]

        self.dynamicCall('StopCtrl()')

app = QtGui.QApplication(sys.argv)        
a = APTSystem(app)

The second item in the args list contains the correct value, but num is never updated by the call.