2010-01-04 3 views
1

activex dll에서 com 개체를 동적으로 만들어야하며 각 개체가 이벤트 처리기로 처리해야하는 이벤트를 발생시킬 수 있습니다.어떻게 파이썬에서 VB의 컨트롤 배열을 모방 하는가?

이 작업은 win32com.client.Dispatchwin32com.client.WithEvents으로 쉽게 수행 할 수 있으며 "개별"클래스의 이벤트 처리기를 각 개체와 연결할 수 있습니다. 그래서 같이 : 나는 얼마나 많은 개체를 알 수 없기 때문에,

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

내가 한 번만 이벤트 핸들러를 코딩 할 : 나는 동적으로 객체를 생성하는 경우

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) 

그러나 목록에 말할 수 나는 실행 시간까지 만들 것입니다. 그리고 이벤트 처리기 내부에서 이벤트를 발생시킨 객체를 얻는 방법을 모르겠습니다.

VB6에서는 컨트롤 배열을 사용하는 activex 컨트롤을 사용했으며 이벤트 처리기는 이벤트를 발생시킨 컨트롤의 "인덱스"값을 가져옵니다.

비슷한 점이 파이썬에서 가능하다고 생각하십니까?
python 데코레이터가 작동하는지 모르겠지만 com 객체의 각 인덱스에 대해 MyEventHandlerClass를 "장식"하는 데 사용할 수 있습니까?

답변

0

그것은 당신이 클래스 객체가 아닌 클래스 인스턴스를 전달해야한다는 처리 win32com의 이벤트의 주요 결함이다.

동적 new.classobj를 사용하여 클래스를 생성하여, 그러나, win32com 사용하여 클래스 상태를 첨부 할 수 있습니다

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)을 사용하는 것이 좋습니다.

+0

예! 이 작품 .. 덕분에 Ryan 나는 또한 comtypes 모듈을 살펴 보겠습니다 .. win32com과는 조금 다른 것처럼 보입니다. – sarshad

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)) 

이벤트가 배열 (다만 지수)의 모든 컨트롤에 액세스 할 필요가있는 경우

, 당신은 핸들러에 listOfObjects 통해 반복하고, 이벤트를 제기하는 객체 결정하여 컨트롤 배열을 모방 할 수 있습니다. 예를 들어, RadioButton_CheckChanged() 이벤트의 모습 때문에 .. :

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

이벤트에 대한 win32com의 큰 결함은 인스턴스가 아닌 호출 가능을 전달해야한다는 것입니다. 그러나 필요한 상태의 클래스 인스턴스를 반환하는 래핑 된 "팩토리"함수를 전달할 수 있습니다. –

+0

@coonj : 불행히도 .. WithEvents() 함수는 객체 참조가 아닌 클래스 인스턴스의 이름을 필요로하므로 작동하지 않습니다. 하지만 당신의 아이디어는'obj_index' 변수에 인덱스 값을 갖는 새로운 클래스를 전달할 수 있다면 효과가 있다고 생각합니다. 그게 가능하니? 나는 어딘가에서 클래스가 파이썬에서도 객체라는 것을 기억한다. 그래서 나는 그들이 생성 될 수 있다고 생각하지만 구문이 무엇인지 알 수 없다. – sarshad

관련 문제