我需要从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?
答案 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)。