Search code examples
wxpython

Toolbar tool - bitmap toggle


I am using wxpython 2.8 which may make things slightly more difficult.

I am trying to create a button in the toolbar which simply changes its bitmap if it is toggled. Anytime the toggle changes, the bitmaps changes to the appropriate icon.

Seeing as this capability does not appear to be built in and I don't want to mix my controls too closely with my views, I quickly tried this:

class ToggleToolBarBase(wx.ToolBarToolBase):
    """A ToolBar Button with bitmaps which is meant to be toggled."""

    def __init__(self, tbar=None, toolid=wx.ID_SEPARATOR, label="",
                 bmpOff=wx.NullBitmap, bmpOn=wx.NullBitmap,
                 kind=wx.ITEM_NORMAL, clientData=None,
                 shortHelpString="", longHelpString=""):
        # super(ToggleToolBarBase, self).__init__(self, tbar, toolid, label,
        #                                         bmpOff, bmpOn,
        #                                         kind, clientData,
        #                                         shortHelpString,
        #                                         longHelpString)
        # Which constructor can I use?
        super(ToggleToolBarBase, self).__init__()
        self.tbar = tbar
        self.bmpOff = bmpOff
        self.bmpOn = bmpOn
        self.toggle = False

    def Toggle(self):
        super(ToggleToolBarBase, self).Toggle()
        self.toggle = not self.toggle

    @property
    def toggle(self):
        return self._toggle

    @toggle.setter
    def toggle(self, value):
        self._toggle = value
        if value is False:
            self.SetNormalBitmap(self.bmpOff)
        elif value is True:
            self.SetNormalBitmap(self.bmpOn)
        self.tbar.Realize()
        self.tbar.Refresh()

All the toolbar.AddLabelTool() functions return ToolBarToolBase so I thought I could simply extend it, but no constructors work and it looks like it is just a proxy for the c++ class.

I tried a few other methods, but nothing seems to work correctly. Surely there must be a simple solution. I imagine this is implemented fairly often.


Solution

  • You are correct, the ToolBarToolBase is not intended for use in that way as part of the public API. It is more of an internal-use class that you are able to use in a limited fashion to get some info about the toolbar item. What is returned from the add tool methods is actually a platform-specific derived class that assists the wx class to interact with the native toolbar widget.

    To change bitmaps when a toggle tool (kind=wx.ITEM_CHECK) you will need to swap the images yourself in the event handler called when the tool is clicked. You can use something like theToolBar.SetToolNormalBitmap(id, new_bmp) You will probably need to call theToolBar.Realize() again on at least some of the platforms to get the toolbar to take the new image.