Python Forum
[WxPython] setting two buttons next to each other
Thread Rating:
  • 2 Vote(s) - 2 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[WxPython] setting two buttons next to each other
#1
I am fluent in tkinter, but i wanted to dip a little into wxpython.

I am trying common layout tasks and struggling. This one is just simply setting 2 buttons next to each other. However the buttons overlap i am guessing. I think my understanding of boxsizer is the issue, but i am not sure.

import wx

app = wx.App()
root = wx.Frame(None) 
panel = wx.Panel(root)
btn = wx.Button(panel, label='press me 1')
btn.Bind(wx.EVT_BUTTON, lambda x:print('pressed 1'))

btn2 = wx.Button(panel, label='press me 2')
btn2.Bind(wx.EVT_BUTTON, lambda x:print('pressed 2'))

box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(btn, 0, wx.EXPAND)
box.Add(btn2, 0, wx.ALIGN_CENTER_HORIZONTAL)

root.Show()
app.MainLoop()
While i am on the subject the App, Frame, and Panel i find even more confusing. Tkinter you just have root, and put the parent window in. I would of assumed the same for wxpython. Hwoever the window for a widget has to be a panel, not what i might assume would be a frame instead. But yet need the frame too. It seriously took me 20 minutes to find out why a seg fault was because frame required None as an argument.
Recommended Tutorials:
Reply
#2
Yep! Frame needs to know if there a parent or not.

have to add sizer to panel.
panel.SetSizer(box)

Also can be done without a panel.
import wx

app = wx.App()
root = wx.Frame(None)
btn = wx.Button(root, label='press me 1')
btn.Bind(wx.EVT_BUTTON, lambda x:print('pressed 1'))

btn2 = wx.Button(root, label='press me 2')
btn2.Bind(wx.EVT_BUTTON, lambda x:print('pressed 2'))

box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(btn, 0, wx.EXPAND)
box.Add(btn2, 2, wx.ALIGN_CENTER_HORIZONTAL)
root.SetSizer(box);

root.Show()
app.MainLoop()
99 percent of computer problems exists between chair and keyboard.
Reply
#3
thanks :) When i think of frame, im thinking of tkinter frame. I could of sworn i tried it and failed without panel.

So obviously the widgets are packed in order in which they are added from left to right. So how might you move these buttons to the right side of the window?
import wx

app = wx.App()
root = wx.Frame(None) 
btn = wx.Button(root, label='press me 1')
btn.Bind(wx.EVT_BUTTON, lambda x:print('pressed 1'))

btn2 = wx.Button(root, label='press me 2')
btn2.Bind(wx.EVT_BUTTON, lambda x:print('pressed 2'))

box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(btn)
box.Add(btn2)
root.SetSizer(box)

root.Show()
app.MainLoop()
In my mindset, something like this
box.Add(btn2, 0, wx.ALIGN_CENTER_HORIZONTAL)
would set the second button to the center of the frame
Recommended Tutorials:
Reply
#4
BoxSizer works with space it has. So it can be very tricky to keep it align right.
Example will work until you add more items.
import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "MyFrame")
        self.buttons = [wx.Button(self, wx.ID_ANY, "press me number one"),
            wx.Button(self, wx.ID_ANY, "press me 2"),
            wx.Button(self, wx.ID_ANY, "press me three")]

        self.buttons[0].Bind(wx.EVT_BUTTON, lambda x:print('pressed 1'))
        self.buttons[1].Bind(wx.EVT_BUTTON, lambda x:print('pressed 2'))
        self.buttons[2].Bind(wx.EVT_BUTTON, lambda x:print('pressed 3'))

        self.vbox = wx.BoxSizer(wx.VERTICAL)
        for button in self.buttons:
            self.vbox.Add(button, 0, wx.ALIGN_CENTER)

        self.SetSizer(self.vbox)
        self.Show()

app = wx.App()
frame = MyFrame()
app.MainLoop()
Without wx.ALL it would lose center of window. But elements are center with each other.
Example will work until you add more items.
import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "MyFrame")
        self.buttons = [wx.Button(self, wx.ID_ANY, "press me number one"),
            wx.Button(self, wx.ID_ANY, "press me 2"),
            wx.Button(self, wx.ID_ANY, "press me three")]

        self.buttons[0].Bind(wx.EVT_BUTTON, lambda x:print('pressed 1'))
        self.buttons[1].Bind(wx.EVT_BUTTON, lambda x:print('pressed 2'))
        self.buttons[2].Bind(wx.EVT_BUTTON, lambda x:print('pressed 3'))

        self.hbox = wx.BoxSizer(wx.HORIZONTAL)
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        for button in self.buttons:
            self.vbox.Add(button, 0, wx.ALIGN_CENTER)

        self.hbox.Add(self.vbox, wx.ALL)

        self.SetSizer(self.hbox)
        self.Show()

app = wx.App()
frame = MyFrame()
app.MainLoop()

Another example.
import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "MyFrame")
        self.buttons = [wx.Button(self, wx.ID_ANY, "press me 1"),
            wx.Button(self, wx.ID_ANY, "press me 2"),]

        self.buttons[0].Bind(wx.EVT_BUTTON, lambda x:print('pressed 1'))
        self.buttons[1].Bind(wx.EVT_BUTTON, lambda x:print('pressed 2'))

        self.hbox = wx.BoxSizer(wx.HORIZONTAL)
        for button in self.buttons:
            self.hbox.Add(button)

        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.hbox, 0, wx.ALIGN_RIGHT)

        self.SetSizer(self.vbox)
        self.Show()

app = wx.App()
frame = MyFrame()
app.MainLoop()
99 percent of computer problems exists between chair and keyboard.
Reply
#5
why would you need two boxsizers? Confused
Recommended Tutorials:
Reply
#6
Horizontal boxsizer handle up and down alignment.
Vertical boxsizer handle left and right alignment.
99 percent of computer problems exists between chair and keyboard.
Reply
#7
The wxpython demo is excellent. You can download just the demo code from github here: https://github.com/wxWidgets/Phoenix.

Then run demo with 'python demo.py', from within the demo directory, don't need any attributes.

It contains demo code for most anything you can think of, and has three tabs (in a notebook) for each, description, code, and the actual demo.
Reply
#8
(Aug-14-2018, 02:55 PM)Windspar Wrote: Horizontal boxsizer handle up and down alignment.
Vertical boxsizer handle left and right alignment.
Hmm. Does that mean you would always have at least 2 boxsizers because you would always align it vertically and horizontally?
(Aug-14-2018, 03:36 PM)Larz60+ Wrote: The wxpython demo is excellent. You can download just the demo code from github here: https://github.com/wxWidgets/Phoenix.

Then run demo with 'python demo.py', from within the demo directory, don't need any attributes.

It contains demo code for most anything you can think of, and has three tabs (in a notebook) for each, description, code, and the actual demo.
wow, that is probably one of the best docs ive seen. thanks. Do you just use these as a template? Or at least when you started?
Recommended Tutorials:
Reply
#9
I do use them as templates, There's a small price that you have to pay, you need to figure out how to work around their 'run.py' module, I wrote a work around, I'll see if I can find it.

I love wxpython, since I switched to OpenSuse, I haven't been able to install the package, the pip install causes errors (I haven't spent a lot of time trying to remedy this, but it's high on my list, I'm finishing up a probability course as a review (MIT On-line), once I finish that, I think I will make this my next priority.

Being ex-tkinter, sizing is pretty simple, actually a breeze compared to tkinter, (you'll like it) There's a great writeup here: https://wxpython.org/Phoenix/docs/html/s...rview.html
Reply
#10
(Aug-14-2018, 03:43 PM)metulburr Wrote: Hmm. Does that mean you would always have at least 2 boxsizers because you would always align it vertically and horizontally?
Yes! Most likely you have even more.
99 percent of computer problems exists between chair and keyboard.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020