0

I am having some difficulty placing 2 buttons centered in the bottom using flags. The output is this when I try, and I don't understand why they don't align to the bottom center.:

enter image description here

With the following code:

#!/usr/bin/python

# gui.py

import wx
import webbrowser

class PanelOne(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent)

class PanelTwo(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent)

class GUI(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(GUI, self).__init__(*args, **kwargs)

        self.poo()

    def poo(self):
        self.CreateStatusBar()
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        self.add_entry = wx.MenuItem(fileMenu, -1, '&Add Entry\tShift+A', 'Add employee')
        quit = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tEsc', 'Quit application')
        fileMenu.AppendItem(self.add_entry)
        fileMenu.AppendItem(quit)
        menubar.Append(fileMenu, '&Options')
        self.SetMenuBar(menubar)

        self.panel_one = PanelOne(self)
        self.panel_two = PanelTwo(self)
        self.panel_two.Hide()

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.panel_one, 1, wx.EXPAND)
        vbox.Add(self.panel_two, 1, wx.EXPAND)
        self.SetSizer(vbox)

        pv1box = wx.BoxSizer(wx.HORIZONTAL)
        self.panel_one.SetSizer(pv1box)

        self.chrome_button = wx.Button(self.panel_one, id=2, label='Gmail')
        self.outlook_button = wx.Button(self.panel_one, id=1, label='Outlook')

        pv1box.Add(self.chrome_button, flag=wx.ALIGN_BOTTOM | wx.ALIGN_CENTER | wx.ALIGN_RIGHT)
        pv1box.Add(self.outlook_button, flag=wx.ALIGN_BOTTOM | wx.ALIGN_CENTER | wx.ALIGN_RIGHT)


        self.SetSize((450, 300))
        self.SetTitle('Prototype')
        self.Centre()
        self.Show(True)


        self.Bind(wx.EVT_MENU, self.onQuit, quit)
        self.Bind(wx.EVT_KEY_DOWN, self.onESCQuit, quit)
        self.Bind(wx.EVT_MENU, self.onSwitchPanels, self.add_entry)
        self.chrome_button.Bind(wx.EVT_BUTTON, self.onClick)
        self.outlook_button.Bind(wx.EVT_BUTTON, self.onClick)


    def onQuit(self, e):

        dial = wx.MessageDialog(None, 'Are you sure to quit?', 'Question', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
        input = dial.ShowModal()

        if input == wx.ID_YES:
            self.Close()

    def onESCQuit(self, e):
        esc = e.GetKey()

        if esc == wx.WXK_ESCAPE:
            dial = wx.MessageDialog(None, 'Are you sure to quit?', 'Question', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
            input = dial.ShowModal()

            if input == wx.ID_YES:
                self.Close()

    def onSwitchPanels(self, event):
        if self.panel_one.IsShown():
            self.add_entry.SetText('Notifications')
            self.panel_one.Hide()
            self.panel_two.Show()
        else:
            self.add_entry.SetText('Add Entry')
            self.panel_one.Show()
            self.panel_two.Hide()

    def onClick(self, event):
        if event.Id == self.chrome_button.Id: 

            chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
            # Without this path it will open in Internet Explorer
            webbrowser.get(chrome_path).open('https://mail.google.com')
        else:
            chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
            # Without this path it will open in Internet Explorer
            webbrowser.get(chrome_path).open('https://outlook.live.com')


def main():

    app = wx.App()
    GUI(None)
    app.MainLoop()

if __name__ == '__main__':
    main()

1 Answer 1

1

There is a single sizer set to the frame, the two panels are parented to the frame so this sizer is positioning them on the frame ok. The two buttons are parented to each of the panels but the frame sizer is trying to position them on the frame when they are on the panels. The panels will need a sizer each so they can position the buttons on the panels.

you have

Frame
--->vbox -> set to frame
--->panel_one -> added to vbox
------->chrome_button -> added to vbox
--->panel_two -> added to vbox
------->outlook_button -> added to vbox

you need

Frame
--->vbox -> set to frame
--->panel_one -> added to vbox
------->p1vbox(new sizer) -> set to panel_one
------->chrome_button -> added to p1vbox
--->panel_two -> added to vbox
------->p2vbox(new sizer) -> set to panel_two
------->outlook_button -> added to p2vbox

With the new code add a stretch spacer either side of the buttons to make them position in the center.

    pv1box.AddStretchSpacer()
    pv1box.Add(self.chrome_button, flag=wx.ALIGN_BOTTOM | wx.ALIGN_CENTER | wx.ALIGN_RIGHT)
    pv1box.Add(self.outlook_button, flag=wx.ALIGN_BOTTOM | wx.ALIGN_CENTER | wx.ALIGN_RIGHT)
    pv1box.AddStretchSpacer()
Sign up to request clarification or add additional context in comments.

3 Comments

I have done so and made it so that both buttons are on the same panel, however they still won't center in the bottom :/
@javanewbie Added example of stretch spacer code to get the buttons to center with latest version of code.
Thank you very much. :) Your help and border=20 on both buttons gave me just the right layout I wanted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.