1

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

我可以很容易地做到这一点,win32com.client.Dispatch并将win32com.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 吗?

4

2 回答 2

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 来模拟控件数组,并确定哪个对象引发了事件......例如,一个RadioButton_CheckChanged() 事件如下所示:

def RadioButton_CheckChanged():
    for radiobutton in listOfRadioButtons:
        if radiobutton.Checked:
            # this is the one that was clicked on
于 2010-01-04T14:04:49.980 回答
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模块(请参阅事件处理)。

于 2010-01-05T06:35:00.177 回答