0

I can't figure out what I'm doing wrong. I just made the jump from Tkinter to wxPython and I'm trying to figure out BoxSizers. I'd look this question up, but I don't even know what to look up. This panel is filling the space of a Frame, it's supposed to show a line of text with a progressbar underneath it and that's all supposed to take up the bottom 1/5 of the panel or so, centered horizontally (eventually I'm going to add a background image behind it). But what happens is I only see the text and only about 40% down from the top, aligned to the left edge of the window. Here's the code:

class KhPanel(wx.Panel):

def __init__(self, parent, configSet, selectWindow):
    wx.Panel.__init__(self, parent=parent)
    self.frame = parent
    self.configSet = configSet
    whichWindow = getattr(self, selectWindow)
    whichWindow()

def configWindow(self):
    gaugeWidth = (1/5)*self.configSet["width"]
    gaugeHeight = (1/10)*self.configSet["height"]
    gaugeMax = 100
    topBuffer = (8/10)*self.configSet["height"]
    itemSep = (1/16)*self.configSet["height"]

    vSizer = wx.BoxSizer(wx.VERTICAL)
    textSizer = wx.BoxSizer(wx.HORIZONTAL)
    progressSizer = wx.BoxSizer(wx.HORIZONTAL)

    configText = wx.StaticText(self, label="STUFF", style=wx.ALIGN_CENTER)
    configProgressBar = wx.Gauge(self, range=gaugeMax, size=(gaugeWidth, gaugeHeight))

    textSizer.Add(configText, 1, wx.ALIGN_CENTER, 0)
    progressSizer.Add(configProgressBar, 1, wx.ALIGN_CENTER, 1)
    vSizer.Add(textSizer, 1, wx.TOP, topBuffer)
    vSizer.Add(progressSizer, 1, wx.TOP, itemSep)

    self.SetSizer(vSizer)
    vSizer.Fit(self)
    return

If you need the info, configSet.width and height are the width and height of the parent window (currently 340 x 270). And selectWindow, in this case, is "configWindow"

linus72982
  • 1,418
  • 2
  • 16
  • 31

2 Answers2

0

Running this code, the gaugeWidth and gaugeHeight are both getting set to zero, which is why the progressbar is not showing. This is due to the fact that you are doing integer math here, so 1 divided by 5 is 0. Same with 1/10. Just change those lines to:

gaugeWidth = (1/5.0)*self.configSet["width"]
gaugeHeight = (1/10.0)*self.configSet["height"]

Then the gauge will appear. Here's some fully runnable code, slightly modified from your unrunnable original:

import wx

class KhPanel(wx.Panel):

    def __init__(self, parent, configSet):
        wx.Panel.__init__(self, parent=parent)
        self.frame = parent
        self.configSet = configSet
        self.configWindow()


    def configWindow(self):
        gaugeWidth = (1/5.0)*self.configSet["width"]
        gaugeHeight = (1/10.0)*self.configSet["height"]
        gaugeMax = 100
        topBuffer = (8/10)*self.configSet["height"]
        itemSep = (1/16)*self.configSet["height"]

        vSizer = wx.BoxSizer(wx.VERTICAL)
        textSizer = wx.BoxSizer(wx.HORIZONTAL)
        progressSizer = wx.BoxSizer(wx.HORIZONTAL)

        configText = wx.StaticText(self, label="STUFF", style=wx.ALIGN_CENTER)
        configProgressBar = wx.Gauge(self, range=gaugeMax, size=(gaugeWidth, gaugeHeight))

        textSizer.Add(configText, 1, wx.ALIGN_CENTER, 0)
        progressSizer.Add(configProgressBar, 1, wx.ALIGN_CENTER, 1)
        vSizer.Add(textSizer, 1, wx.TOP, topBuffer)
        vSizer.Add(progressSizer, 1, wx.TOP, itemSep)

        self.SetSizer(vSizer)
        vSizer.Fit(self)

class MyFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title="Test")
        config = {'width':340, 'height':270}
        panel = KhPanel(self, config)

        self.Show()

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    app.MainLoop()
Mike Driscoll
  • 32,629
  • 8
  • 45
  • 88
  • You're right, that was the problem. I did the same for the topBuffer and itemSep and now those are working, too, though I still have some tweaking as the progressbar ends up on top and I'm not sure why and the widgets aren't centered horizontally which is what I thought ALIGN_CENTER did. Ahh well, I can fuss around with those. Why does Python need the .0 at the end of integers like that? Does the .0 tell it that the answer will be a floating point? Rule #1 of debugging: test your variables -- lesson learned for the 500th time. Thanks! – linus72982 Mar 06 '15 at 17:39
  • Yes, it is telling Python to use floating point division. You can enable floating point division be default by using `from __future__ import division` - http://stackoverflow.com/questions/1267869/how-can-i-force-division-to-be-floating-point-in-python. You might find this article useful for centering widgets - http://www.blog.pythonlibrary.org/2015/02/19/wxpython-101-how-to-center-a-widget/ – Mike Driscoll Mar 06 '15 at 17:47
0

Incorporating Mike Driscoll's correction above, I changed the way I spaced it and it works out to be less work. I took out the horizontal sizers as I discovered they weren't needed unless I was going to space two things on the same row and I added stretch spacers instead of enormous borders. Here's the new code and it looks exactly how I wanted it:

def configWindow(self):
    gaugeWidth = (4/5.0)*self.configSet["width"]
    gaugeHeight = (1/10.0)*self.configSet["height"]
    gaugeMax = 100

    vSizer = wx.BoxSizer(wx.VERTICAL)
    configText = wx.StaticText(self, label="STUFF")
    configProgressBar = wx.Gauge(self, range=gaugeMax, size=(gaugeWidth, gaugeHeight))

    vSizer.AddStretchSpacer(7)
    vSizer.Add(configText, 1, wx.ALIGN_CENTER, 0)
    vSizer.Add(configProgressBar, 1, wx.ALIGN_CENTER, 0)
    vSizer.AddStretchSpacer(1)

    self.SetSizer(vSizer)
    return
linus72982
  • 1,418
  • 2
  • 16
  • 31