WxPython - вызвать событие флажка при установке его значения в коде - PullRequest
3 голосов
/ 19 марта 2012

Рассмотрим следующий фрагмент кода:

import wx

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.cb1 = wx.CheckBox(self, -1, "CheckBox 1")
        self.cb2 = wx.CheckBox(self, -1, "CheckBox 2")
        self.cb3 = wx.CheckBox(self, -1, "CheckBox 3")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.cb1, 0, wx.ADJUST_MINSIZE, 0)
        sizer.Add(self.cb2, 0, wx.ADJUST_MINSIZE, 0)
        sizer.Add(self.cb3, 0, wx.ADJUST_MINSIZE, 0)

        self.SetSizer(sizer)
        self.Layout()

        self.Bind(wx.EVT_CHECKBOX, self.OnCb1, self.cb1)
        self.Bind(wx.EVT_CHECKBOX, self.OnCb2, self.cb2)

    def OnCb1(self, evt):
        self.cb2.SetValue(evt.IsChecked())

    def OnCb2(self, evt):
        self.cb3.SetValue(evt.IsChecked())


if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    frame = MyFrame(None, -1, "")
    app.SetTopWindow(frame)
    frame.Show()
    app.MainLoop()

Здесь у меня есть 3 флажка, связанных вместе, поэтому cb2 проверяется, когда cb1, и cb3 проверяется, когда cb2.Однако, когда я устанавливаю значение cb2 в подпрограмме OnCb1, событие флажка cb2 не срабатывает, а флажок cb3 остается не отмеченным.Поэтому я хотел бы найти способ как-нибудь вызвать событие cb2 вручную, чтобы отметить все 3 поля одновременно, когда проверяется только cb1.Я был бы очень признателен, если бы кто-нибудь дал мне подсказку.

Ответы [ 3 ]

3 голосов
/ 21 апреля 2014

Использовать wx.PostEvent ... вот так:

class launcherWindow(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title='New Window')
        #now add the main body, start with a panel
        panel = wx.Panel(self)
        #instantiate a new dropdown
        self.productDropDown = wx.ComboBox(panel, size=wx.DefaultSize, style = wx.CB_READONLY)

        #get the products and product subtypes
        self.productDict = self.getProductsAndSubtypes()

        #setup subtypes first, just in case, since onProductSelection will reference this
        self.productSubtypeDropDown = wx.ComboBox(panel, size=wx.DefaultSize, style = wx.CB_READONLY)

        #add products
        for product in self.productDict.keys():
            self.productDropDown.Append(product)

        #bind selection event
        self.productDropDown.Bind(wx.EVT_COMBOBOX, self.onProductSelection)

        #set default selection
        self.productDropDown.SetSelection(0)

        #pretend that we clicked the product selection, so it's event gets called
        wx.PostEvent(self.productDropDown, wx.CommandEvent(wx.wxEVT_COMMAND_COMBOBOX_SELECTED))

        #now add the dropdown to a sizer, set the sizer for the panel, fit the panel, etc...

    def onProductSelection(self, event):
        productSelected = self.productDropDown.GetStringSelection()
        productSubtypes = self.productDict[productSelected]

        #clear any existing product subtypes, since each product may have different ones
        self.productSubtypeDropDown.Clear()

        for productSubtype in productSubtypes:
            self.productSubtypeDropDown.Append(productSubtype)

        #select the first item by default
        self.productSubtypeDropDown.SetSelection(0)
1 голос
/ 14 ноября 2015

Я не мог принять код nmz787 напрямую, и мне пришлось немного взломать его, но я наконец-то заставил его работать на

  • изменение состояния флажка и
  • имея флажок получить событие,

так же, как если бы пользователь щелкнул по нему.

Я думал, что выложу свой код на случай, если другие застрянут, пытаясь заставить это работать тоже. Поскольку он зависит только от флажка, а не от того, какой элемент управления вызывает его, я выделил его как независимую функцию «верхнего уровня», а не как метод для какого-либо класса.

def toggleCheckBox(cb):
    evt = wx.CommandEvent(commandType=wx.EVT_CHECKBOX.typeId)
    evt.SetEventObject(cb)
    cb.SetValue( not cb.GetValue())
    wx.PostEvent(cb, evt)

Я понятия не имею, зачем конструктору CommandEvent требовалось ключевое слово или есть более разумный и надежный способ получить требуемый typeId, но это сработало для меня.

0 голосов
/ 19 марта 2012

У меня нет опыта работы с wxPython, поэтому я не могу привести вам конкретный пример, но я знаю, что установка значения программно не вызовет командных событий для виджетов. Я предполагаю, что вам нужно будет вручную опубликовать событие для cb2 после того, как вы установите его значение. Вы можете просмотреть аналогичный вопрос здесь: wxPython: вызов события вручную

Что я могу предложить, так это создать подкласс wx.CheckBox и создать SetValueWithEvent() или аналогичный метод, который будет одновременно вызывать SetValue и публиковать событие wx. EVT_CHECKBOX.

PyQt имеет аналогичные ситуации, когда сигналы могут или не могут излучаться при программной установке значений в виджете. Иногда они дадут вам более одного сигнала, который вы можете прослушать в любом случае. К сожалению, основываясь только на моем ограниченном знакомстве с примерами wxPython, я думаю, что он намного более примитивен и немного менее питоничен. Так что вам, кажется, приходится делать что-то самостоятельно немного чаще.

...