简体   繁体   中英

wxPython how to set widget position inside statusbar

I would like to add two buttons inside the status bar, and I have them implemented as follows:

import wx

class MainFrame(wx.Frame):
    """Constructor"""

    def __init__(self, parent, id):
        wx.Frame.__init__(self, None)


        # self.status_bar = self.CreateStatusBar(3)
        self.status_bar = self.CreateStatusBar(3)

        self.status_bar.SetStatusText("some text", 0)

        self.button1 = wx.Button(self.status_bar, -1, "button 1")
        self.button2 = wx.Button(self.status_bar, -1, "button 2")
        self.status_bar.SetStatusWidths([-1, 200, 200])
        self.button1.SetPosition((self.status_bar.Size[0]-100, 0))
        self.button2.SetPosition((self.status_bar.Size[0]-200, 0))

        self.Refresh()
        self.Show()


if __name__ == "__main__":
    app = wx.App()
    MainFrame(None, -1)
    app.MainLoop()

The problem is that: I do not know how to properly set the positions of the buttons. For the above example, I have two slots for them already, but I can't put them in the slots. In stead, I have to use the "SetPosition" function to set the fix positions of the buttons, but once the window gets resized the button will stay there and will not be seen.

I was wondering if there is a easy way to set the position of the buttons inside the statusbar like we set the text using "self.status_bar.SetStatusText(self.button1, 1)" and "self.status_bar.SetStatusText(self.button2, 2)"

Thanks a lot!

===========================================================================

Thanks a lot to Mike Driscoll's answer, I have figured out the way to do it. I'll post my solution as follows in case any one needs it.

import wx

class MyStatusBar(wx.StatusBar):
    def __init__(self, parent):
        wx.StatusBar.__init__(self, parent)

        self.SetFieldsCount(3)
        self.SetStatusWidths([-1, 200, 200])
        self.sizeChanged = False
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_IDLE, self.OnIdle)

        # Field 0 ... just text
        self.SetStatusText("some text", 0)

        # Field for buttons
        self.button1 = wx.Button(self, 1001, "button 1")
        self.button2 = wx.Button(self, 1002, "button 2")

        # set the initial position of the checkbox
        self.Reposition()

    def OnSize(self, evt):
        evt.Skip()
        self.Reposition()  # for normal size events

        # Set a flag so the idle time handler will also do the repositioning.
        # It is done this way to get around a buglet where GetFieldRect is not
        # accurate during the EVT_SIZE resulting from a frame maximize.
        self.sizeChanged = True


    def OnIdle(self, evt):
        if self.sizeChanged:
            self.Reposition()


    # reposition the buttons
    def Reposition(self):
        rect1 = self.GetFieldRect(1)
        rect1.x += 1
        rect1.y += 1
        self.button1.SetRect(rect1)

        rect2 = self.GetFieldRect(2)
        rect2.x += 1
        rect2.y += 1
        self.button2.SetRect(rect2)

        self.sizeChanged = False


class MainFrame(wx.Frame):
    """Constructor"""

    def __init__(self, parent, id):
        wx.Frame.__init__(self, None)

        self.status_bar = MyStatusBar(self)
        self.SetStatusBar(self.status_bar)

        self.Refresh()
        self.Show()


if __name__ == "__main__":
    app = wx.App()
    MainFrame(None, -1)
    app.MainLoop()

The easiest way would be to subclass wx.StatusBar itself, add the buttons and then catch the wx.EVT_SIZE . This way you catch resize events and can reposition the widgets as needed.

The wxPython demo has an example where it has a checkbox widget with the following method:

# reposition the checkbox
def Reposition(self):
    rect = self.GetFieldRect(1)
    rect.x += 1
    rect.y += 1
    self.cb.SetRect(rect)
    self.sizeChanged = False

The self.GetFieldRect(1) refers to the checkbox widget. You can use something like this for yours except that you will need to keep track of two widget's positions and update accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM