【问题标题】:wxPython conditionally display and hidewxPython 有条件地显示和隐藏
【发布时间】:2015-01-26 21:26:56
【问题描述】:

我是 wxPython 的新手,想用它来构建一个简单的动态 UI,有条件地显示和隐藏一些下拉框,这可以在 jQuery 中轻松完成。

因此,从我的第一级组合框,如果用户选择“Op1_1”,将出现第二级组合框 A。另一方面,如果选择“Op1_2”,则在同一位置,将生成不同的二级组合框B。

  1. 问题 1:我可以在 飞,但它的位置不正确。从附图中,你 可以看到它总是在左上角。有没有办法重新定位?
  2. 问题2:如果生成了第一个第二个combo-box A,那么用户选择'Op1_2',理论上combo-box B会替换combo-box A。但是我遇到了错误wxGridBagSizer::Add(): An item is already at that position。如何销毁以前构建的盒子?
  3. 问题3:有没有办法整合wxPython和jQuery,可以让我的生活更轻松......

import wx

class landing_frame(wx.Frame):

    def __init__(self, parent, title):    
        super(landing_frame, self).__init__(parent, title=title, 
            size=(450, 350))
        self.font1 = wx.Font(18, wx.DECORATIVE, wx.ITALIC, wx.BOLD) 
        self.InitUI()
        self.Centre()
        self.Show()     

    def InitUI(self):

        self.panel = wx.Panel(self)
        self.sizer = wx.GridBagSizer(5, 5)

        self.text1 = wx.StaticText(self.panel, label="Welcome!")
        self.sizer.Add(self.text1, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=15)

        line = wx.StaticLine(self.panel)
        self.sizer.Add(line, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.BOTTOM, border=10)

        self.text2 = wx.StaticText(self.panel, label="First Level Dropdown")
        self.sizer.Add(self.text2, pos=(2, 0), flag=wx.LEFT, border=10)

        self.sampleList = ['Op1_1', 'Op1_2']
        self.combo = wx.ComboBox(self.panel, 30, choices=self.sampleList)
        self.combo.Bind(wx.EVT_COMBOBOX, self.EvtComboBox)
        self.sizer.Add(self.combo, pos=(2, 1), span=(1, 2), flag=wx.TOP|wx.EXPAND, border=5)

        self.panel.SetSizer(self.sizer)


    def EvtComboBox(self, event):
        self.user_choice = event.GetString()
        if self.user_choice == "Op1_1": 
            self.sampleList_ss1 = ['Op2_1_1', 'Op2_1_2', 'Op2_1_3']
            self.combo_ss1 = wx.ComboBox(self.panel, 31, choices=self.sampleList_ss1)
            self.combo_ss1.Bind(wx.EVT_COMBOBOX, self.EvtComboBox)
            self.sizer.Add(self.combo_ss1, pos=(3, 1), span=(1, 2), flag=wx.TOP|wx.EXPAND, border=5)
            self.panel.SetSizer(self.sizer)

        if self.user_choice == "Op1_2": 
            self.sampleList_ss2 = ['Op2_2_1', 'Op2_2_2', 'Op2_2_3']
            self.combo_ss2 = wx.ComboBox(self.panel, 31, choices=self.sampleList_ss2)
            self.combo_ss2.Bind(wx.EVT_COMBOBOX, self.EvtComboBox)
            self.sizer.Add(self.combo_ss2, pos=(3, 1), span=(1, 2), flag=wx.TOP|wx.EXPAND, border=5)
            self.panel.SetSizer(self.sizer)



if __name__ == '__main__':
    app = wx.App(redirect=False, filename="mylogfile.txt")
    landing_frame(None, title="Test")
    app.MainLoop()

【问题讨论】:

    标签: jquery python wxpython


    【解决方案1】:
    1. 尝试调用 self.panel.Layout()。不需要再做 self.panel.SetSizer(self.sizer) 了。
    2. 您可以调用 wx.Sizer.Remove(window)。 wx.Sizer 也有一个替换功能,但我不确定它如何与 GridBagSizer 一起使用。您还可以创建所有组合框,隐藏或禁用不需要的组合框,并根据需要更改其内容(wx.ComboBox 派生自 wx.ControlWithItems,并具有成员函数 Clear、Delete、Append、Insert)。如果您决定删除组合框,则首先将其从 sizer 中移除,然后调用 Destroy。
    3. 没有。

    【讨论】:

    • 感谢您的回答!关于 Q3,有什么方法可以改善动态 wxPython Gui?
    【解决方案2】:

    您可以使用的一种方法是创建第二个组合并将其隐藏。 当在第一个组合中进行选择时,显示第二个组合并更改其选择以适合。

    import wx
    
    
    class landing_frame(wx.Frame):
    
        def __init__(self, parent, title):
            super(landing_frame, self).__init__(parent, title=title,
                                                size=(450, 350))
            self.font1 = wx.Font(18, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
            self.InitUI()
            self.Centre()
            self.Show()
    
        def InitUI(self):
    
            self.panel = wx.Panel(self)
            self.sizer = wx.GridBagSizer(5, 5)
    
            self.text1 = wx.StaticText(self.panel, label="Welcome!")
            self.sizer.Add(
                self.text1, pos=(0, 0),
                flag=wx.TOP | wx.LEFT | wx.BOTTOM, border=15)
    
            line = wx.StaticLine(self.panel)
            self.sizer.Add(
                line, pos=(1, 0), span=(1, 5),
                flag=wx.EXPAND | wx.BOTTOM, border=10)
    
            self.text2 = wx.StaticText(self.panel, label="First Level Dropdown")
            self.sizer.Add(self.text2, pos=(2, 0), flag=wx.LEFT, border=10)
    
            self.sampleList = ['', 'Op1_1', 'Op1_2']
            self.combo1 = wx.ComboBox(self.panel, choices=self.sampleList)
            self.combo1.Bind(wx.EVT_COMBOBOX, self.on_combo1)
            self.sizer.Add(
                self.combo1, pos=(2, 1), span=(1, 2), flag=wx.TOP | wx.EXPAND,
                border=5)
    
            self.combo2 = wx.ComboBox(self.panel)
            self.combo2.Bind(wx.EVT_COMBOBOX, self.on_combo2)
            self.sizer.Add(
                self.combo2, pos=(3, 1), span=(1, 2), flag=wx.TOP | wx.EXPAND,
                border=5)
    
            self.panel.SetSizer(self.sizer)
            self.Layout()
            wx.CallAfter(self.combo2.Show, False)
    
        def on_combo1(self, event):
            self.user_choice = event.GetString()
            if self.user_choice == '':
                self.combo2.Show(False)
                self.combo2.Clear()
                return
            self.combo2.Show(True)
    
            if self.user_choice == "Op1_1":
                self.combo2.SetItems(('Op2_1_1', 'Op2_1_2', 'Op2_1_3'))
    
            elif self.user_choice == "Op1_2":
                self.combo2.SetItems(('Op2_2_1', 'Op2_2_2', 'Op2_2_3'))
    
        def on_combo2(self, event):
            print '2nd combo choice: {}'.format(event.GetString())
    
    
    if __name__ == '__main__':
        app = wx.App(redirect=False)
        landing_frame(None, title="Test")
        app.MainLoop()
    

    【讨论】:

    • 感谢您提供解决方案。有没有更好的方法来用其他类型的元素(如text enter box)替换第二个combo box?另外,有什么建议可以更好地使wxPython GUI 更加动态?
    猜你喜欢
    • 2022-08-11
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    相关资源
    最近更新 更多