如何在python中为win32com模仿vb的控件数组?

时间:2010-01-04 08:22:24

标签: python win32com

我需要从activex dll动态创建com对象,并且每个对象都可以引发应该使用事件处理程序处理的事件。

我可以使用win32com.client.Dispatchwin32com.client.WithEvents轻松完成此操作,并将“单独”类的事件处理程序与每个对象相关联。像这样:

class evt_1:
    def OnEvent(self):
        print "got event from object 1"

class evt_2:
    def OnEvent(self):
        print "got event from object 2"

obj_1 = win32com.client.Dispatch("mycom")
ev_1  = win32com.client.WithEvents(obj_1, evt_1)

obj_2 = win32com.client.Dispatch("mycom")
ev_1  = win32com.client.WithEvents(obj_2, evt_2)

但如果我动态创建对象,请在列表中说:

listOfObjects = []
for i in range(10):
    obj = win32com.client.Dispatch("mycom")
    listOfObjects.append(obj)
    ev = win32com.client.WithEvents(obj, MyEventHandlerClass)

我只想对事件处理程序进行一次编码,因为我不知道在运行时会创建多少个对象。而且我不知道如何从事件处理程序中获取引发事件的对象。

在VB 6中,我使用控制数组来使用activex控件,事件处理程序只是获取引发事件的控件的“索引”值。

你认为在python中可以做类似的事吗? 我不确定python装饰器的工作原理,但是它们是否可以用于为com对象的每个索引“装饰”MyEventHandlerClass?

2 个答案:

答案 0 :(得分:0)

在VB.NET中删除了控制数组,因此我认为它们不会在win32com中得到支持。 不确定这是否适合您,但是您可以将索引传递给EventHandler类吗?

class MyEventHandler:
    def __init__(self, index):
        self.obj_index = index

    def OnEvent(self):
        print "got event from object %d" % self.obj_index

listOfObjects = []
for i in range(10):
    obj = win32com.client.Dispatch("mycom")
    listOfObjects.append(obj)
    ev = win32com.client.WithEvents(obj, MyEventHandlerClass(i))

如果事件需要访问数组中的所有控件(而不仅仅是索引),则可以通过循环遍历EventHandler中的listOfObjects来模拟控件数组,并确定引发Event的哪个对象......所以例如,RadioButton_CheckChanged()事件看起来像:

def RadioButton_CheckChanged():
    for radiobutton in listOfRadioButtons:
        if radiobutton.Checked:
            # this is the one that was clicked on

答案 1 :(得分:0)

这是win32com事件处理的一个主要缺陷,你必须传入一个类对象而不是一个类实例。

您可以使用win32com将状态附加到您的类,但是,使用new.classobj动态创建类:

from win32com.client import Dispatch, WithEvents
from new import classobj

class MyEventHandler(object):
    def OnVisible(self, visible):
        print "got event from object %d" % self.obj_index

listOfObjects = []
for i in range(3):
    handler = classobj('Handler_%s' % i,(MyEventHandler,),{})
    handler.obj_index = i
    ie = Dispatch("InternetExplorer.Application")
    listOfObjects.append(ie)
    WithEvents(ie, handler)

listOfObjects[0].Visible = 1
listOfObjects[2].Visible = 1

输出:

got event from object 0
got event from object 2

如果您想以更加理智的方式执行此操作,您可能需要查看comtypes模块(请参阅event handling)。