Question

Level: Beginner

I am developing a GUI with wxPython on Windows OS. I have some problems with arranging the panels. I GUI looks like below image (Of course the menu bar and the title bar is omitted in the image).

enter image description here

I would take some time to explain how I create this GUI. First I get the screen size with the wx.DisplaySize(). Then I adjust my panels accordingly using pos=(). There are main 4 panels named panel-1 to panel-4. Each of this panels contains subpanels. The number of subpanels is not a contstant. I use a for loop to create and add subpanels to panels. The subpanels are added to a sizer and then the sizers are ultimately applied to the corresponding panels. My screen size according to wx.DisplaySize() is 1680x1050. Currently everything is working good.

Problems:

  1. But as soon as I run my code on a machine with screen size 1366x768 the panels are not positioned correctly! How can I make my GUI to auto adjust the panel's arrangement according to the screen size change. I plan to use my GUI on a variety of screen sizes from tablets to large screen LCDs. I guess I have to create a sizer that add these panels named as panel-1 to panel4 to some main arbitrary panel? Or is there any better approach?

  2. Currently I am have disabled the resize option of the frame. Because when I resize the frame (when option is enabled) the main window gets resized but the components (panels, buttons) inside the main windows don't get resized. How can I enable this feature so that when the main window is resized the components inside are also resized accordingly?

There maybe an error in my approach in creating this kind of GUI. I look forward any suggestions that can create this kind of GUI in a simplified way! Thanks for your time.

PS: I can paste the code if required but I don't think it is important as it will just increase the post length and as I have tried to explain my problem in quite a detail. However my code is working good for the screen size 1680x1050.

Was it helpful?

Solution

You cannot use absolute positioning across different screen sizes. The wxPython toolkit provides sizers that will help you solve this problem. If all your widgets are within sizers, they will automatically resize appropriately. Here's one implementation that is very similar to your design:

import wx

########################################################################
class SubPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent, number):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("red")

        label = "Sub panel-%s" % number
        lbl = wx.StaticText(self, label=label)

        sizer = wx.BoxSizer()
        sizer.Add(lbl, 0, wx.ALL|wx.CENTER, 5)
        self.SetSizer(sizer)

########################################################################
class ColorPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent, number, color, sub_panels):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour(color)

        label = "Panel-%s" % number
        lbl = wx.StaticText(self, label=label)

        v_sizer = wx.BoxSizer(wx.VERTICAL)
        for i in range(sub_panels):
            p = SubPanel(self, i+1)
            v_sizer.Add(p, 0, wx.ALL|wx.EXPAND|wx.CENTER, 10)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(v_sizer, 0, wx.ALL, 5)
        sizer.Add(lbl, 0, wx.ALL|wx.CENTER, 5)
        self.SetSizer(sizer)

########################################################################
class MainPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        hsizer = wx.BoxSizer(wx.HORIZONTAL)
        v_sizer = wx.BoxSizer(wx.VERTICAL)

        colors = [("green", 3),
                  ("yellow", 2),
                  ("light blue", 2),
                  ("purple", 2)]
        count = 1
        for color, subpanel in colors:
            panel = ColorPanel(self, count, color, subpanel)
            hsizer.Add(panel, 1, wx.EXPAND)
            count += 1

        orange_panel = ColorPanel(self, count, "orange", 0)
        v_sizer.Add(hsizer, 1, wx.EXPAND)
        v_sizer.Add(orange_panel, 1, wx.EXPAND)

        self.SetSizer(v_sizer)

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

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Panels!", size=(600,400))
        panel = MainPanel(self)
        self.Show()

#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top