Home > Back-end >  wxPython - Panel Size for the labels
wxPython - Panel Size for the labels

Time:09-17

While I'm trying to understand how the WXPython library works, I got to my first issue.

The main issue that I'm having is when i run the code my labels are one over the other on the right panel, while running the following code.

import wx
from wx.core import Font, Position, Size

# class MyTree
# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyTree(wx.TreeCtrl):
    """
    Our customized TreeCtrl class.
    """
    def __init__(self, parent, id, position, size, style):
        """
        Initialize our tree.
        """
        wx.TreeCtrl.__init__(self, parent, id, position, size, style)
       
        root = self.AddRoot('Programmer')
        
        os = self.AppendItem(root, 'Ultra Script 1')
        pl = self.AppendItem(root, 'Ultra Script 2')
        tk = self.AppendItem(root, 'Ultra Script 3')
           
        cl = self.AppendItem(pl, 'Random Scripts')
        sl = self.AppendItem(pl, 'Miscelanious')

        self.AppendItem(os, 'Script1')
        self.AppendItem(os, 'Script2')
        self.AppendItem(os, 'Script3')
        self.AppendItem(os, 'Script4')
        self.AppendItem(cl, 'Script1')
        self.AppendItem(cl, 'Script2')
        self.AppendItem(cl, 'Script3')
        self.AppendItem(sl, '1')
        self.AppendItem(sl, '2')
        self.AppendItem(sl, '3')
        self.AppendItem(sl, '4')
        self.AppendItem(tk, 'Script1')
        self.AppendItem(tk, 'Script2')
        self.AppendItem(tk, 'Script3')
        self.AppendItem(tk, 'Script4 ')
        self.AppendItem(tk, 'Script5')

#---------------------------------------------------------------------------
        
class MyFrame(wx.Frame):
    """
    Our customized window class.
    """
    def __init__(self, parent, id, title):
        """
        Initialize our window.
        """
        wx.Frame.__init__(self, parent, id, title,
                          wx.DefaultPosition, wx.Size(800, 600))

        #self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        # Create a splitter window.
        self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE)
        
        # Create the left panel.
        leftPanel = wx.Panel(self.splitter, -1)
        
        # Create our tree and put it into the left panel.
        self.tree = MyTree(leftPanel, 1,
                           wx.DefaultPosition,
                           wx.DefaultSize,
                           wx.TR_HIDE_ROOT |
                           wx.TR_HAS_BUTTONS)
        self.tree.SetBackgroundColour('#3DB2FF')

        # Bind the OnSelChanged method to the tree.
        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=1)

        # Create the right panel.
        rightPanel = wx.Panel(self.splitter, -1, style=wx.SUNKEN_BORDER)
        rightPanel.SetBackgroundColour('#79B4B7')
        
        # Create a widget to display static text 
        # and store it in the right panel.
        self.display = wx.StaticText(rightPanel, -1, '',
                                     style=wx.ALIGN_LEFT)
        
        # Put the left and right panes into the split window.
        self.splitter.SplitVertically(leftPanel, rightPanel, 200)

        # Minimum size of subwindow.
        self.splitter.SetMinimumPaneSize(1)         

        #------------

        # Create a box sizer that will contain the left panel contents.
        leftBox = wx.BoxSizer(wx.VERTICAL)
        
        # Add the tree to the box sizer.
        leftBox.Add(self.tree, 1, wx.EXPAND)
        
        # Set the size of the right panel to that required by the tree.
        leftPanel.SetSizer(leftBox)
        
        # Create the right box sizer that will contain the panel's contents.
        rightBox = wx.BoxSizer(wx.VERTICAL)
        
        # Add the display widget to the right panel.
        rightBox.Add(self.display, 0, wx.ALL, 1)

        label = wx.BoxSizer(wx.VERTICAL)
        self.text = wx.StaticText(self.display, label = "This is amazing. ", pos = (0,5))

        # Set the size of the right panel to that 
        # required by the display widget.
        rightPanel.SetSizer(rightBox)
        #------------
        
        # Create the window in the centre of the screen.
        self.Centre()

    #-----------------------------------------------------------------------
        
    def OnSelChanged(self, event):
        """
        Method called when selected item is changed.
        """
        
        # Get the selected item object.
        item =  event.GetItem()
        
        # Display the selected item text in the text widget.
        self.display.SetLabel(self.tree.GetItemText(item))

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    """
    Our application class.
    """
    def OnInit(self):
        """
        Initialize by creating the split window with the tree.
        """
        
        frame = MyFrame(None, -1, 'Simple Window')
        frame.Show(True)
        self.SetTopWindow(frame)
        
        return True

#---------------------------------------------------------------------------
    
if __name__ == '__main__':
    app = MyApp(0)
    app.MainLoop()

I'm still new to this library so if anyone knows how to fix it, I'd appreaciate it!

CodePudding user response:

The parent of self.text in your code is self.display. That cannot happen, because self.display is a StaticText, not a container. If you just add the self.text info the sizer of the right panel, then it will work:

    # label is unused: label = wx.BoxSizer(wx.VERTICAL)
    self.text = wx.StaticText(rightPanel, label = "This is amazing. ")
    rightBox.Add(self.text)

When we use sizers, we do not use pos=(X,Y), because the sizer will perform the sizing and placement.

CodePudding user response:

As Petr points out self.text needs to be put into the rightPanel and added to the sizer for that panel.
Using a vertical BoxSizer does leave an awful lot of wasted space to the right. So you might consider using a simple GridSizer defined with 2 columns, 1 for the tree label and the other for your descriptive text.

Your amended code:

import wx

# class MyTree
# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyTree(wx.TreeCtrl):
    """
    Our customized TreeCtrl class.
    """
    def __init__(self, parent, id, position, size, style):
        """
        Initialize our tree.
        """
        wx.TreeCtrl.__init__(self, parent, id, position, size, style)
       
        root = self.AddRoot('Programmer')
        
        os = self.AppendItem(root, 'Ultra Script 1')
        pl = self.AppendItem(root, 'Ultra Script 2')
        tk = self.AppendItem(root, 'Ultra Script 3')
           
        cl = self.AppendItem(pl, 'Random Scripts')
        sl = self.AppendItem(pl, 'Miscellaneous')

        self.AppendItem(os, 'Script1')
        self.AppendItem(os, 'Script2')
        self.AppendItem(os, 'Script3')
        self.AppendItem(os, 'Script4')
        self.AppendItem(cl, 'Script1')
        self.AppendItem(cl, 'Script2')
        self.AppendItem(cl, 'Script3')
        self.AppendItem(sl, '1')
        self.AppendItem(sl, '2')
        self.AppendItem(sl, '3')
        self.AppendItem(sl, '4')
        self.AppendItem(tk, 'Script1')
        self.AppendItem(tk, 'Script2')
        self.AppendItem(tk, 'Script3')
        self.AppendItem(tk, 'Script4 ')
        self.AppendItem(tk, 'Script5')

#---------------------------------------------------------------------------
        
class MyFrame(wx.Frame):
    """
    Our customized window class.
    """
    def __init__(self, parent, id, title):
        """
        Initialize our window.
        """
        wx.Frame.__init__(self, parent, id, title,
                          wx.DefaultPosition, size=(800, 600))

        #self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        # Create a splitter window.
        self.splitter = wx.SplitterWindow(self, -1, style=wx.SP_LIVE_UPDATE)
        
        # Create the left panel.
        leftPanel = wx.Panel(self.splitter, -1)
        
        # Create our tree and put it into the left panel.
        self.tree = MyTree(leftPanel, 1,
                           wx.DefaultPosition,
                           wx.DefaultSize,
                           wx.TR_HIDE_ROOT |
                           wx.TR_HAS_BUTTONS)
        self.tree.SetBackgroundColour('#3DB2FF')

        # Bind the OnSelChanged method to the tree.
        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=1)

        # Create the right panel.
        rightPanel = wx.Panel(self.splitter, -1, style=wx.SUNKEN_BORDER)
        rightPanel.SetBackgroundColour('#79B4B7')
        
        # Create a widget to display static text 
        # and store it in the right panel.
        self.display = wx.StaticText(rightPanel, -1, '')
        
        # Put the left and right panes into the split window.
        self.splitter.SplitVertically(leftPanel, rightPanel, 200)

        # Minimum size of subwindow.
        self.splitter.SetMinimumPaneSize(1)         

        # Create a box sizer that will contain the left panel contents.
        leftBox = wx.BoxSizer(wx.VERTICAL)
        
        # Add the tree to the box sizer.
        leftBox.Add(self.tree, 1, wx.EXPAND)
        
        # Set the size of the right panel to that required by the tree.
        leftPanel.SetSizer(leftBox)
        
        # Create the right box sizer that will contain the panel's contents.
        rightBox = wx.GridSizer(rows=1, cols=2, vgap=5, hgap=5)
        #rightBox = wx.BoxSizer(wx.VERTICAL)
        
        # Add the display widget to the right panel.
        rightBox.Add(self.display, 0, wx.ALL, 10)

        lab = "This is amazing.\n"
        lab  = "This label can be multiline\n"
        lab  = "and provide help text\n"
        lab  = "or a detailed explanation of the chosen item"
        
        self.text = wx.StaticText(rightPanel, label = lab)

        # Add the text widget to the right panel.
        rightBox.Add(self.text, 0, wx.ALL, 10)

        # Set the size of the right panel to that 
        # required by the display widget.
        rightPanel.SetSizer(rightBox)
        #------------
        
        # Create the window in the centre of the screen.
        self.Centre()

    #-----------------------------------------------------------------------
        
    def OnSelChanged(self, event):
        """
        Method called when selected item is changed.
        """
        
        # Get the selected item object.
        item =  event.GetItem()
        
        # Display the selected item text in the text widget.
        self.display.SetLabel(self.tree.GetItemText(item))
#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    """
    Our application class.
    """
    def OnInit(self):
        """
        Initialize by creating the split window with the tree.
        """
        
        frame = MyFrame(None, -1, 'Simple Window')
        frame.Show(True)
        self.SetTopWindow(frame)
        
        return True

#---------------------------------------------------------------------------
    
if __name__ == '__main__':
    app = MyApp()
    app.MainLoop()

enter image description here

  • Related