2017-04-10 1 views
1

우분투 14.04, MATE 데스크탑, 파이썬 2.7, 파이썬 -wxgtk2.8 2.8.12.1에서 아래 코드를 combotest.py으로 게시하려고합니다. 내가 콤보 상자를 클릭하고 해당 이벤트 핸들러에게 직접 OnUpdateComboBox 불을 변경하는 경우wx.PostEvent는 이벤트 핸들러에서 호출되면 이벤트를 발생시키지 않습니까?

combotest

, 나는이 표준 출력에 인쇄되는 : 응용 프로그램은 다음과 같이이다

OnUpdateComboBox <wx._controls.ComboBox; proxy of <Swig Object of type 'wxComboBox *' at 0x909caf0> > MyComboBox 

내가 알고 그 :

http://wxpython-users.1045709.n5.nabble.com/SetValue-on-spinctrl-doesn-t-send-update-event-td2289628.html

일반 정책은 사용자가 만든 컨트롤의 값을 변경하면 이벤트가 발생하고 프로그래밍 방식으로 변경 한 내용은 변경되지 않습니다. 그래서 나는 선택의 여지가 노력하고있어,

을 이벤트를 SetValue 매크로에 계획이 변경된 전송해서는 안 -과 해당 핸들러 해고 - 콤보 상자에서 버튼을 클릭 할 때. 그리고 WxPython - trigger checkbox event while setting its value in the code에서 권장하는대로 나는 버튼 코드에 의해 프로그래밍 방식으로 선택이 변경되면 wx.PostEvent()을 호출하여 combobox 이벤트 핸들러를 강제 호출하려고합니다.

I 버튼을 클릭하면, 나는 그것의 핸들러 BtnClickHandler이 전화를받을 않으며, 예상대로 새로운 항목으로 콤보 상자의 선택을 변경 볼 수 있습니다 - 그것은, 독립형 또는 wx.CallAfter() 단순히 결코 관계없이 경우, wx.PostEvent()를 호출하지만 OnUpdateComboBox으로 전화합니다.

단추 이벤트 핸들러에서 프로그래밍 방식으로 선택을 변경하면 어떻게 combobox 이벤트 핸들러를 호출 할 수 있습니까? 아니면이 버그입니까?

편집 : 내가 할 수있는 BtnClickHandler에서 내가 직접 함수를 호출 할 수 있습니다 밝혀 :

self.OnUpdateComboBox(oevt) 

을 ... 다음 핸들러가 호출 얻을 것이다 -하지만 뭔가 그냥이에 대한 느낌이 좋지 않습니다 ...

또한 self.combo_box.GetLastPosition()이 (가) 콤보 상자에 5 개의 항목이 있더라도 2를 반환하는 이유는 무엇입니까?!

combotest.py

import wxversion 
wxversion.select("2.8") 
import wx, wx.html 
import sys 

class Frame(wx.Frame): 
    def __init__(self, *args, **kwds): 
    kwds["style"] = wx.DEFAULT_FRAME_STYLE 
    wx.Frame.__init__(self, *args, **kwds) 

    self.label = wx.StaticText(self, wx.ID_ANY, "Click the button to change combobox below: ") 
    self.bt_main = wx.Button(self, label="Click ME") 
    self.bt_main.Bind(wx.EVT_BUTTON, self.BtnClickHandler) 
    self.combo_box = wx.ComboBox(self, wx.ID_ANY, choices=["AAA", "BBB", "CCC", "DDD", "EEE"], style=wx.CB_DROPDOWN | wx.CB_READONLY, name="MyComboBox") 
    self.combo_box.SetSelection(0) # this does not call event 
    wx.PostEvent(self.combo_box, wx.CommandEvent(wx.EVT_COMBOBOX.typeId)) #neither does this 
    self.Bind(wx.EVT_COMBOBOX, self.OnUpdateComboBox, self.combo_box) 

    sizer_vmain_app = wx.BoxSizer(wx.VERTICAL) 
    sizer_vmain_app.Add(self.label, proportion=0, flag=wx.EXPAND, border=0) 
    sizer_vmain_app.Add(self.bt_main, proportion=0, flag=0, border=0) 
    sizer_vmain_app.Add(self.combo_box, proportion=0, flag=0, border=0) 

    self.SetSizer(sizer_vmain_app) 
    self.Layout() 

    def OnUpdateComboBox(self, event): 
    widget = event.GetEventObject() 
    print("OnUpdateComboBox " + repr(widget) + " " + widget.GetName()) 

    def BtnClickHandler(self, event): 
    print("BtnClickHandler " + repr(self.combo_box.GetLastPosition())) 
    newsel = (self.combo_box.GetSelection() + 1) % (self.combo_box.GetLastPosition()+1) # GetLastPosition is 2, even with 5 items in box?! 
    self.combo_box.SetSelection(newsel) # this does not call event 
    oevt = wx.CommandEvent(commandType=wx.EVT_COMBOBOX.typeId) 
    oevt.SetEventObject(self.combo_box) 
    wx.PostEvent(self.combo_box, oevt) # does nothing 
    wx.CallAfter(wx.PostEvent, self.combo_box, oevt) # does nothing 

if __name__ == "__main__": 
    app = wx.PySimpleApp(0) 
    wx.InitAllImageHandlers() 
    app_frame = Frame(None, wx.ID_ANY, "") 
    app.SetTopWindow(app_frame) 
    app_frame.Show() 
    app.MainLoop() 
+0

이 난 그냥 직접 핸들러를 호출하여 주위에 작업 한 무언가이다 - 확인 최근 phoenix dev 빌드 – user2682863

+0

내 대답이 문제를 해결 했습니까? – user2682863

답변

0

직접 이벤트 핸들러 함수를 호출하지 마십시오 - 특히이 같은. 더 나은 솔루션은 콤보 상자의 값이 변경 될 때 수행해야 할 작업을 수행하고 두 핸들러에서이 함수를 호출하는 함수를 만드는 것입니다.

또한 모든 것이 wx-3.0/3.1에서 작동하는지 알고 있으면 좋을 것입니다.

0

나는 해결책을 찾아 냈다. 프레임 대신 콤보 상자에 직접 바인딩하십시오. 다음은 작동 예제입니다 (wx phoenix 3.03.xyz dev ....)

class Frame(wx.Frame): 
    def __init__(self, *args, **kwds): 
     kwds["style"] = wx.DEFAULT_FRAME_STYLE 
     wx.Frame.__init__(self, *args, **kwds) 

     self.label = wx.StaticText(self, wx.ID_ANY, "Click the button to change combobox below: ") 
     self.bt_main = wx.Button(self, label="Click ME") 
     self.bt_main.Bind(wx.EVT_BUTTON, self.BtnClickHandler) 
     self.combo_box = wx.ComboBox(self, wx.ID_ANY, choices=["AAA", "BBB", "CCC", "DDD", "EEE"], 
            style=wx.CB_DROPDOWN | wx.CB_READONLY, name="MyComboBox") 
     # self.Bind(wx.EVT_COMBOBOX, self.OnUpdateComboBox, self.combo_box) 
     # bind directly to the widget 
     self.combo_box.Bind(wx.EVT_COMBOBOX, self.OnUpdateComboBox) 

     self.combo_box.SetSelection(0) 
     combo_event = wx.CommandEvent(wx.EVT_COMBOBOX.typeId) 
     combo_event.SetEventObject(self.combo_box) 
     wx.PostEvent(self.combo_box, combo_event) 


     sizer_vmain_app = wx.BoxSizer(wx.VERTICAL) 
     sizer_vmain_app.Add(self.label, proportion=0, flag=wx.EXPAND, border=0) 
     sizer_vmain_app.Add(self.bt_main, proportion=0, flag=0, border=0) 
     sizer_vmain_app.Add(self.combo_box, proportion=0, flag=0, border=0) 

     self.SetSizer(sizer_vmain_app) 
     self.Layout() 

    def OnUpdateComboBox(self, event): 
     widget = event.GetEventObject() 
     print("OnUpdateComboBox " + repr(widget) + " " + widget.GetName()) 

    def BtnClickHandler(self, event): 
     print("BtnClickHandler " + repr(self.combo_box.GetLastPosition())) 
     newsel = (self.combo_box.GetSelection() + 1) % (
     self.combo_box.GetLastPosition() + 1) # GetLastPosition is 2, even with 5 items in box?! 
     self.combo_box.SetSelection(newsel) # this does not call event 
     oevt = wx.CommandEvent(commandType=wx.EVT_COMBOBOX.typeId) 
     oevt.SetEventObject(self.combo_box) 
     wx.PostEvent(self.combo_box, oevt) # does nothing 
     wx.CallAfter(wx.PostEvent, self.combo_box, oevt) # does nothing 


if __name__ == "__main__": 
    app = wx.PySimpleApp(0) 
    wx.InitAllImageHandlers() 
    app_frame = Frame(None, wx.ID_ANY, "") 
    app.SetTopWindow(app_frame) 
    app_frame.Show() 
    app.MainLoop() 

편집 할 때

self.combox_box.GetLastPosition()가 커서 위치를 참조한다 사이드 참고 : 마지막 선택

관련 문제