PyQt:如何通过QAxWidget按引用发送参数
我正在尝试用PyQt在Python中与一个ActiveX COM对象进行交互。这种方法在Python中是可行的:
myobj.dynamicCall('SetAbsMovePos(int, double)', [0, 10])
但是,我无法通过引用发送参数。从文档中,我想调用的方法是:
int GetNumHWUnits (int lHWType, int& plNumUnits)
而基本的示例代码是:
QVariantList params = ...
int result = object->dynamicCall("GetNumHWUnits(int, int&)", params).toInt();
我推测在Python中,使用ctypes的等效代码应该是:
num = ctypes.c_int()
myobj.dynamicCall('GetNumHWUnits(int, int&)', [6, ctypes.byref(num)])
但是num
从来没有被更新。
在Python中,等效的代码是什么,或者有什么解决方法可以让我发送并读取一个类型为int&
的参数呢?
3 个回答
1
QVariant
是一个用来传递值的工具。
QVariant dynamicCall(const char *, QList<QVariant> & /GetWrapper/);
%MethodCode
Py_BEGIN_ALLOW_THREADS
sipRes = new QVariant(sipCpp->dynamicCall(a0, *a1));
Py_END_ALLOW_THREADS
// Update the input list with the (possibly) new values.
for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(a1Wrapper); ++i)
{
QVariant *v = new QVariant(a1->at(i));
PyObject *v_obj = sipConvertFromNewType(v, sipType_QVariant, NULL);
简单来说,QVariant
就像是一个包装盒,用来通过引用传递一个值。
这意味着如果你传递的是 c_int
,你实际上是把这个值包装了两次。建议你在第二个参数中传递一个真正的 QVariant
,而不是 c_int
。如果不这样做,PyQt 会自动把你的 c_int
处理成 QVariant
,然后调用 dynamicCall
。在这个调用过程中,新的 QVariant
会被更新,但它和原来的 c_int
没有联系,所以你的实例不会发生变化。
这样做应该可以正常工作:
num = QVariant(0)
myobj.dynamicCall('GetNumHWUnits(int, int&)', [6, num])
print repr(num.value())
2
你可以试着传递一个只有一个元素的列表:
def funct(a):
a[0] = 4
b = [3]
funct(b)
print b[0]
输出结果:4
1
我从PyQt的邮件列表中找到了这个解决方案。需要引用参数列表,因为只有这个列表会被更新;而原来的QVariant对象是不会更新的。回头看,这个道理似乎很明显!
typ = QVariant(6)
num = QVariant(0)
args_list = [typ, num]
self.dynamicCall('GetNumHWUnits(int, int&)', args_list)
print 'Num of HW units =', args_list[1].toInt()[0]
完整的代码示例可以在这篇帖子中找到。