如何在python中为win32com模拟vb的控制数组?
我需要从 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 吗?
I need to dynamically create com objects from an activex dll and each of the objects can raise events which should be handled with event handlers.
I can do this easily with win32com.client.Dispatch
and win32com.client.WithEvents
and associate a "separate" class of event handlers with each of the objects. Like so:
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)
But if I dynamically create the objects, lets say in a list:
listOfObjects = []
for i in range(10):
obj = win32com.client.Dispatch("mycom")
listOfObjects.append(obj)
ev = win32com.client.WithEvents(obj, MyEventHandlerClass)
I want to code the event handlers only once, since I don't know how many objects I would be creating until run time. And I don't know how to get the object that raised the event from inside the event handler.
In VB 6, I've used the activex control using control arrays, and the event handlers simply get an "index" value of the control that raised the event.
Do you think something similar can be done in python ?
I am not sure what python decorators work for, but can they be used to "decorate" the MyEventHandlerClass for each index of the com object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
win32com 事件处理的一个主要缺陷是您必须传递类对象而不是类实例。
但是,您可以使用 win32com 将状态附加到您的类,方法是使用
new.classobj
动态创建类:输出:
您可能需要查看 comtypes 模块(参见 事件处理)如果您想以更明智的方式执行此操作。
It's a major flaw of win32com's event handling that you have to pass in a class object rather than a class instance.
You can attach state to your classes using win32com, however, by creating classes dynamically using
new.classobj
:Output:
You might want to look into the comtypes module (see event handling) if you want to do this in a saner way.
控件数组在 VB.NET 中已被删除,因此我认为 win32com 不会支持它们。
不确定这是否适合您,但是您可以将索引传递给 EventHandler 类吗?
如果事件需要访问数组中的所有控件(而不仅仅是索引),您可以通过循环遍历 EventHandler 中的 listOfObjects 来模拟控件数组,并确定哪个对象引发了事件...例如, RadioButton_CheckChanged() 事件如下所示:
Control Arrays were removed in VB.NET so I don't think they would be supported in the win32com.
Not sure if this would work for you but can you pass the index to the EventHandler class?
If the event needs access to all of the controls in the array (not just the index), you can mimic a control array by looping through your listOfObjects in the EventHandler, and determining which object raised the Event... so for example, a RadioButton_CheckChanged() event would look like: