Search code examples
pythonwxpython

Radio button display and selection issue in wxPython


I am creating multi-column lists which are all equal in length and also generating number of radio buttons equal to the length of list. I have couple of issues:

1] Display issue: In following fig., I get radio buttons. enter image description here

But when I scroll down this is what happens. enter image description here

Following is a snippet of my code to generate it Please assist me to fix this issue so that I get full list of radio buttons displayed properly.

w = 0
for i in range(1,len(lut_code)):
    w += 30
    rb_G = wx.RadioButton(scroll1, -1, "G", (500,w), style=wx.RB_GROUP)
    rb_F = wx.RadioButton(scroll1, -1, "F", (540,w))
    rb_P = wx.RadioButton(scroll1, -1, "P", (580,w))

2] Selection of radio button: When I want to select a single radio button from a row, a complete row is selected instead and it gets blue in color like in following fig. enter image description here

Is it because of my use of wx.ListCtrl to display these columns? What would be the fix or alternative method to only select radio button of choice instead of selecting whole row?


Solution

  • Took me some time to figure this out. I think you are actually drawing the radio buttons on the frame by specifying the position! This will obviously not work in this case because your listCtrl comes to the foreground when you try to select a radio button.

    If you notice the radio buttons are not correctly aligned according to the list items. The gap between the buttons is greater than the gap between rows of the list.

    The problem with using list_ctrl is you cannot put widgets like radio buttons in them.

    I would suggest you to use something like wx.ScrolledWindow for this. Put each row into a sizer and stack these sizers vertically.

    UPDATE:

    import wx
    
    class Frame ( wx.Frame ):
    
        def __init__( self, parent ):
            wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Test", pos = wx.DefaultPosition, size = wx.Size( -1,-1 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
    
            sizer0 = wx.BoxSizer( wx.VERTICAL )
    
            self.scrolledWindow = wx.ScrolledWindow( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.HSCROLL|wx.VSCROLL )
            self.scrolledWindow.SetScrollRate( 5, 5 )
            grid_sizer = wx.GridSizer( 0, 8, 0, 0 )
    
            self.head1 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"Code", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head1.Wrap( -1 )
            grid_sizer.Add( self.head1, 0, wx.ALL, 5 )
    
            self.head2 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"Classification", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head2.Wrap( -1 )
            grid_sizer.Add( self.head2, 0, wx.ALL, 5 )
    
            self.head3 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"A", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head3.Wrap( -1 )
            grid_sizer.Add( self.head3, 0, wx.ALL, 5 )
    
            self.head4 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"B", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head4.Wrap( -1 )
            grid_sizer.Add( self.head4, 0, wx.ALL, 5 )
    
            self.head5 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"C", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head5.Wrap( -1 )
            grid_sizer.Add( self.head5, 0, wx.ALL, 5 )
    
            self.head6 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"D", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head6.Wrap( -1 )
            grid_sizer.Add( self.head6, 0, wx.ALL, 5 )
    
            self.head7 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"Cond.", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head7.Wrap( -1 )
            grid_sizer.Add( self.head7, 0, wx.ALL, 5 )
    
            self.head8 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"Update", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.head8.Wrap( -1 )
            grid_sizer.Add( self.head8, 0, wx.ALL, 5 )
    
            self.column11 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"86", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.column11.Wrap( -1 )
            grid_sizer.Add( self.column11, 0, wx.ALL, 5 )
    
            self.column12 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"Urban", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.column12.Wrap( -1 )
            grid_sizer.Add( self.column12, 0, wx.ALL, 5 )
    
            self.column13 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"68", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.column13.Wrap( -1 )
            grid_sizer.Add( self.column13, 0, wx.ALL, 5 )
    
            self.column14 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"80", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.column14.Wrap( -1 )
            grid_sizer.Add( self.column14, 0, wx.ALL, 5 )
    
            self.column15 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"86", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.column15.Wrap( -1 )
            grid_sizer.Add( self.column15, 0, wx.ALL, 5 )
    
            self.column16 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, u"89", wx.DefaultPosition, wx.DefaultSize, 0 )
            self.column16.Wrap( -1 )
            grid_sizer.Add( self.column16, 0, wx.ALL, 5 )
    
            self.column17 = wx.StaticText( self.scrolledWindow, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
            self.column17.Wrap( -1 )
            grid_sizer.Add( self.column17, 0, wx.ALL, 5 )
    
            radio1Choices = [ u"G", u"P", u"F" ]
            self.radio1 = wx.RadioBox( self.scrolledWindow, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, radio1Choices, 3, wx.RA_SPECIFY_COLS )
            self.radio1.SetSelection( 0 )
            grid_sizer.Add( self.radio1, 0, wx.ALL, 5 )
    
    
            self.scrolledWindow.SetSizer( grid_sizer )
            self.scrolledWindow.Layout()
            grid_sizer.Fit( self.scrolledWindow )
            sizer0.Add( self.scrolledWindow, 1, wx.EXPAND |wx.ALL, 5 )
    
            # Bind the radio box select event to a function
            self.radio1.Bind( wx.EVT_RADIOBOX, self.on_selected )
    
    
            self.SetSizer( sizer0 )
            self.Layout()
            self.Maximize()
            self.Centre( wx.BOTH )
            self.Show()
    
        def on_selected(self, event):
            # Depending upon the option selected the values of A,B,C,D are changed
            if  self.radio1.GetStringSelection() == 'P': 
                self.column13.SetLabel('25')
                self.column14.SetLabel('27')
                self.column15.SetLabel('34')
                self.column16.SetLabel('12')
            elif self.radio1.GetStringSelection() == 'F':
                self.column13.SetLabel('56')
                self.column14.SetLabel('70')
                self.column15.SetLabel('49')
                self.column16.SetLabel('54')
            else:
                self.column13.SetLabel('78')
                self.column14.SetLabel('83')
                self.column15.SetLabel('69')
                self.column16.SetLabel('100')
    
    
    if __name__ == "__main__":
            app = wx.App()
            Frame(None)
            app.MainLoop()
    

    I wrote this sample code to show you how you can do it. It's a bit crude but I hope you get the picture.

    You might also want to check the answer in this post:Adding a button to every row in ListCtrl WxPython. It might be a better choice.