wxPython:windows上使用多个sizer的问题,但在linux上运行良好

2024-09-30 14:21:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在写一个在linux上运行得很好的小应用程序,但是我在windows上有一些问题。下面是代码示例:

import wx
#####################################################################    
class Main(wx.Frame):
    def __init__(self):

        wx.Frame.__init__(self, None, title="StackOverflow",  pos=wx.DefaultPosition, size=(800,600))
        self.SetMinSize( self.GetSize() )

        p = wx.Panel(self)
        nb = wx.Notebook(p)

        page1 = AddToCollection(nb)
        page2 = CollectionStatistics(nb)
        nb.AddPage(page1, "Page 1")
        nb.AddPage(page2, "Page 2")

        # finally, put the notebook in a sizer for the panel to manage
        # the layout
        sizer = wx.BoxSizer()
        sizer.Add(nb, 1, wx.EXPAND)
        p.SetSizer(sizer)
#########################################################################
class CollectionStatistics(wx.Panel):
    def __init__(self, parent):          

        wx.Panel.__init__(self, parent)
#########################################################################
class AddToCollection(wx.Panel):
    def __init__(self, parent):          

        wx.Panel.__init__(self, parent)

        self.v1_qty_list = [str(x) for x in range(9)]
        self.v2_qty_list = [str(x) for x in range(9)]

        self.sizername = wx.GridBagSizer(5, 5)
        self.sizername.AddGrowableCol(0,0)

        self.name_txt = wx.StaticText(self, label="Enter Name :")
        self.sizername.Add(self.name_txt,(2,0),(1,1),wx.EXPAND)

        self.name = wx.TextCtrl(self,style=wx.TE_PROCESS_ENTER,value=u"")
        self.sizername.Add(self.name,(3,0),(1,1),wx.EXPAND)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnPressEnter, self.name)

        self.SetSizerAndFit(self.sizername)
        self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )
##########################################################################
    def OnPressEnter(self,event):
        self.selected_name = self.name.GetValue()
        self.AddToCol()
##########################################################################
    def AddToCol(self):

        self.sizerAdd = wx.GridBagSizer(5, 5)
        self.sizerAdd.AddGrowableCol(0, 0)

        self.name.Enable(False)

        ### Expansion
        self.expansion = wx.Choice(self, -1, choices=['test 1', 'test 2'])
        self.expansion.SetSelection(0)
        self.sizerAdd.Add(self.expansion,(5,0),(1,6),wx.EXPAND)

        ### Quantities txt
        self.v1_txt = wx.StaticText(self, label="V1 Quantity :")
        self.sizerAdd.Add(self.v1_txt,(7,0),(1,1),wx.EXPAND)

        self.v2_txt = wx.StaticText(self, label="V2 Quantity :")
        self.sizerAdd.Add(self.v2_txt,(8,0),(1,1),wx.EXPAND)

        ### Quantities choices
        self.v1_qty = wx.Choice(self, -1, choices=self.v1_qty_list)
        self.v1_qty.SetSelection(0)
        self.sizerAdd.Add(self.v1_qty,(7,5),(1,1),wx.EXPAND)

        self.v2_qty = wx.Choice(self, -1, choices=self.v1_qty_list)
        self.v2_qty.SetSelection(0)
        self.sizerAdd.Add(self.v2_qty,(8,5),(1,1),wx.EXPAND)

        ### Ok Button        
        self.Add_btn = wx.Button(self, -1, "Add")
        self.Add_btn.Bind(wx.EVT_BUTTON, self.OnAdd)
        self.sizerAdd.Add(self.Add_btn,(9,5),(1,1),wx.EXPAND)        

        ### Reset Button        
        self.Reset_btn = wx.Button(self, -1, "Reset")
        self.Reset_btn.Bind(wx.EVT_BUTTON, self.OnResetPanel)
        self.sizerAdd.Add(self.Reset_btn,(9,4),(1,1),wx.EXPAND)             

        self.SetSizerAndFit(self.sizerAdd)
        self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )     
######################################################################
    def OnResetPanel(self,event):
        ### Kill all children
        self.expansion.Destroy()
        self.v1_txt.Destroy()
        self.v1_qty.Destroy()
        self.v2_txt.Destroy()
        self.v2_qty.Destroy()
        self.Add_btn.Destroy()
        self.Reset_btn.Destroy()
        ### Reinitialise sizer
        self.name.Enable(True)
        self.name.SetValue("") 
######################################################################
    def OnAdd(self,event):
        print 'Add'
        self.OnResetPanel(self)
######################################################################
######################################################################
if __name__ == "__main__":
    app = wx.App()
    Main().Show()
    app.MainLoop()

基本上,我在第一个sizer中有一个TextCtrl,它正在等待一个条目。一旦用户点击enter,第二个大小便会出现几个对象。在

windows上的问题似乎来自两个gridbagsizerssizername和{})的使用。按enter键(在__init__中的waitevent)之后,sizerAdd中定义的对象不会出现。当我扩展脚本运行的窗口时,这些对象会神奇地出现!在

有什么想法吗?在

编辑:代码现在可以运行了


Tags: nameselftxtaddinitdefv2expand
1条回答
网友
1楼 · 发布于 2024-09-30 14:21:40

我认为代码中的问题是AddToCol方法末尾的两行:

        self.SetSizerAndFit(self.sizerAdd)
        self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )     

此时,您正在将AddToCollection面板的大小从self.sizername更改为self.sizerAdd。但是,Enter Name:标签和文本框仍然在self.sizername大小规中。但是,这个sizer不是任何窗口的sizer,也没有添加到任何其他sizer中。在

通常,在wxPython中,每个sizer都应该设置为一个窗口的sizer,或者添加到另一个sizer中。另一个sizer将是一个窗口的sizer,或者包含在另一个sizer中,依此类推。在您的例子中,您的self.sizernamesizer最终都不是,在这种情况下,我会预料到不可预测的行为。如果你的代码可以在Linux上运行,那么我会说它是偶然的。在

我想你可以在这里做些什么:

  1. 添加self.sizerAdd作为self.sizername的子级。这可以通过将上面的两行替换为

            self.sizername.Add(self.sizerAdd,(4,0),(1,1),wx.EXPAND)
            self.sizername.Layout()
    
  2. AddToCol中,直接将小部件添加到self.sizername大小,而不是将它们添加到self.sizerAdd

  3. 创建一个垂直方向的wx.BoxSizer(),将其设置为AddToCollection面板的大小调整器,并将self.sizername和{}大小规添加到BoxSizer

在这三种情况下,在创建新的小部件之后,您需要在顶层sizer上调用^{}方法,无论是self.sizername还是顶层{}。选项1下的代码段已经包含此行。在

此外,您可能需要修改OnResetPanel()方法。如果选择了选项1或3,则需要从添加到其中的任何一个大小器中删除self.sizerAdd大小写器。例如,在选项1中,您将添加行

        self.sizername.Remove(self.sizerAdd)

另一种方法是让您的AddToCol方法在一个面板中创建所有的小部件,并将其添加到最后的主面板中。您的AddToCol方法将需要创建一个子面板,添加额外的控件作为此面板的子面板而不是主面板(self),将子面板的大小设置为self.sizerAdd,最后将此面板添加到self.sizername大小。在

^{4}$

然后您还需要更换线路

       self.sizername.Remove(self.sizerAdd)

OnResetPanel()中有两行:

       self.sizername.Remove(self.child_panel)
       self.child_panel.Destroy()

在上面的方法1中,有一件事让我感到不安,那就是我看到小部件在出现在正确的位置之前短暂地出现在左上角。这种适应性解决了这个问题,因此使GUI的行为变得更好一些。我无法重现你在评论中提到的黑区问题,但希望这种方法也能解决你的问题。在

相关问题 更多 >