HowToUseMultipleToolbars

From Dabo Wiki
Jump to: navigation, search

Using multiple toolbars in other places than right bellow the title bar is relatively common. For example on a panel to gather panel related functionality, on to of a grid for navigation and other grid related tasks. However, not many people seem to know that wxPython and thus Dabo (on the wx version series) supports this usage. At least in OS X and MS Windows (XP).

Please note this is untested in Linux.

The example is a little long but hopefully it will inspire you to the power of Toolbars in sizers.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import dabo
import dabo.ui as dui
dabo.ui.loadUI("wx")


class Panel1(dui.dPanel):
    def initProperties(self):
        self.RegID = "panel1"

    def afterInit(self):
        sv = self.Sizer = dui.dSizer('v', DefaultBorder=10)
        lblPanel = dui.dLabel(self, Caption="Panel 1 - No Toolbar")
        sv.append(lblPanel)

        hs = dui.dSizer('h')
        lbl = dui.dLabel(self, Caption="Label")
        txt = dui.dTextBox(self)
        hs.append(lbl, border=10, borderSides='right')
        hs.append(txt)
        sv.append(hs)

        btnWhatever = dui.dButton(self, Caption="Whatever")
        sv.append(btnWhatever)
        sv.layout()

        btnWhatever.bindEvent(dabo.dEvents.Hit, self.onBtnWhatever)

    def onBtnWhatever(self, evt):
        print "Whatever"


class PanelWithToolbar(dui.dPanel):
    def initProperties(self):
        self.RegID = "panel2"
        self.Visible = False

    def afterInit(self):
        sv = self.Sizer = dui.dSizer('v')
        # Create Toolbar
        tb = dui.dToolBar(self)

        if self.Application.Platform == "Mac": iconSize = (32, 32) ## Yes Mac HIG specifies 32x32
        else: iconSize = (22, 22)
        iconPath = "themes/tango/%sx%s" % iconSize
        tb.SetToolBitmapSize(iconSize)

        tb.appendButton(u"First", pic="%s/actions/go-first.png" % iconPath,
                        OnHit=self.Form.onFirst, tip=u"First record")
        tb.appendButton(u"Previous", pic="%s/actions/go-previous.png" % iconPath,
                        OnHit=self.Form.onPrior, tip=u"Previous record")
        tb.appendButton(u"Next", pic="%s/actions/go-next.png" % iconPath,
                        OnHit=self.Form.onNext, tip=u"Next record")
        tb.appendButton(u"Last", pic="%s/actions/go-last.png" % iconPath,
                        OnHit=self.Form.onLast, tip=u"Last record")
        sv.append(tb, layout='x')

        lblPanel = dui.dLabel(self, Caption="Panel 2 - Contacts")
        sv.append(lblPanel, border=20, borderSides=('left', 'top'))

        hs = dui.dSizer('h')
        lbl = dui.dLabel(self, Caption="Contact:")
        txt = dui.dTextBox(self)
        hs.append(lbl, border=10, borderSides='right')
        hs.append(txt)
        sv.append(hs, border=20, borderSides=('left', 'top'), layout='x')

        btnWhatever = dui.dButton(self, Caption="Whatever")
        sv.append(btnWhatever, border=20, borderSides=('left', 'top'))
        sv.layout()

        btnWhatever.bindEvent(dabo.dEvents.Hit, self.Form.onBtnWhatever2)


class MainForm(dui.dForm):
    def afterInit(self):
        # Create Toolbar
        self.ToolBar = tb = dui.dToolBar(self)
        if self.Application.Platform == "Mac": iconSize = (32, 32) ## Yes Mac HIG specifies 32x32
        else: iconSize = (22, 22)
        iconPath = "themes/tango/%sx%s" % iconSize
        tb.SetToolBitmapSize(iconSize)

        tb.appendButton('Click Me', "%s/actions/document-open.png" % iconPath,
                        OnHit=self.onAppTbButton)

    def afterInitAll(self):
        self.Sizer = dui.dSizer('v')
        self.topPanel = dui.dPanel(self)
        self.Sizer.append1x(self.topPanel)
        vs = self.topPanel.Sizer = dui.dSizer('v')
        vs.append1x(Panel1(self))
        vs.append1x(PanelWithToolbar(self))

        hs = dui.dSizer('h', DefaultBorder=15, DefaultBorderLeft=True,
                        DefaultBorderBottom=True)
        btn1 = dui.dButton(self.topPanel, Caption='Toggle Panel 1')
        btn2 = dui.dButton(self.topPanel, Caption='Toggle Panel 2')
        hs.append(btn1)
        hs.append(btn2)
        vs.append(hs)
        self.layout()

        btn1.bindEvent(dabo.dEvents.Hit, self.panel1Toggle)
        btn2.bindEvent(dabo.dEvents.Hit, self.panel2Toggle)

    def onAppTbButton(self, evt):
        print "Application toolbar button click"

    def onFirst(self, evt): print 'First'
    def onPrior(self, evt): print 'Previous'
    def onNext(self, evt):  print 'Next'
    def onLast(self, evt):  print 'Last'

    def onBtnWhatever2(self, evt):
        print "Whatever 2 defined on MainForm"

    def panel1Toggle(self, evt):
        panel1 = self.getObjectByRegID("panel1")
        panel1.Visible = not panel1.Visible
        self.layout()

    def panel2Toggle(self, evt):
        panel2 = self.getObjectByRegID("panel2")
        panel2.Visible = not panel2.Visible
        self.layout()


if __name__ == '__main__':
    app = dabo.dApp()
    app.MainFormClass = MainForm
    app.start()

Discussion: If set on a panel the Toolbar's parent must be the panel - in fact this is the same as any other widget.

It is interesting to note that forms are the natural mediators between dabo controls and bizobjects, thus offer a lot of bizobj related functionality that should be explored. A conclusion is that most code should be defined at the form level and not at panel level. A good example of this is the bizobj navigation supplied by the panel2 toolbar.

Also note that conceptually the Toolbar in fact behaves just like any other sizer element!