wxPython中的单选按钮显示和选择问题

1 投票
1 回答
1414 浏览
提问于 2025-04-18 12:07

我正在创建多个列的列表,这些列的长度都是相等的,同时也生成与列表长度相同数量的单选按钮。不过我遇到了一些问题:

1] 显示问题:在下面的图中,我可以看到单选按钮。enter image description here

但是当我向下滚动时,情况就变成这样了。enter image description here

下面是我用来生成这些内容的代码片段。请帮我解决这个问题,让我能正确显示完整的单选按钮列表。

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] 单选按钮的选择:当我想从一行中选择一个单选按钮时,结果却是整行都被选中了,并且变成蓝色,就像下面的图所示。enter image description here

这是因为我使用了wx.ListCtrl来显示这些列吗?有没有什么办法或者替代方法可以只选择我想要的单选按钮,而不是整行都被选中?

1 个回答

1

我花了一些时间才搞明白这个问题。我觉得你是在通过指定位置来绘制单选按钮,这样做在这种情况下显然是行不通的,因为当你尝试选择单选按钮时,列表控件会覆盖在前面。

如果你注意到,单选按钮并没有和列表项对齐。按钮之间的间距比列表行之间的间距要大。

使用列表控件的问题是,你不能在里面放置像单选按钮这样的控件。

我建议你使用类似 wx.ScrolledWindow 的东西。把每一行放进一个布局管理器,然后把这些布局管理器垂直堆叠起来。

更新:

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()

我写了这个示例代码来给你展示怎么做。虽然有点粗糙,但我希望你能明白我的意思。

你也可以看看这个帖子里的答案:在 ListCtrl WxPython 中为每一行添加一个按钮。这可能是个更好的选择。

撰写回答