如何删除wxpython中删除的窗口留下的空白?

时间:2015-03-17 18:09:04

标签: wxpython

我有一个名为StaticText的{​​{1}}列表。我想从text_Ani[]中删除其中一个(称为" sizer")。

我尝试了两个选项,每个选项都删除了对象,但留下了一个空白区域,我想删除它。

我尝试过的选项是:

GridBagSizer

sizer.Hide(self.text_Ani[id]) sizer.Remove(self.text_Ani[id])

其中sizer.Detach(self.text_Ani[id]) self.text_Ani[id].Destroy()是主窗口的名称。 所有这些都接着是致电:

self

某些网站上建议的对self.panel.Layout()wx.LayoutAlgorithm().LayoutWindow(self, self.panel)的额外通话似乎没有帮助。

总是留有空白。我如何摆脱空白?

编辑:这里的代码:

self.panel.Fit()

1 个答案:

答案 0 :(得分:1)

该代码不小,但它可以运行。我认为你有一个空白的主要原因是你根本没有递减self.iw。因此,您总是告诉您网格在不再存在的内容之后继续添加项目。我继续将self.iw-=3添加到remove_region方法的末尾来修复代码。我还在该方法中取消了一些内容,以使其更好地工作:

#!/usr/bin/python


import wx
import wx.lib.scrolledpanel



class region():

    #variables associated with the entire class (not each object)
    nreg=0

    def __init__(self,Ani=999.0e29,AZ=9.99):

        #Each region has a bunch of properties that will be extracted from the corresponding region arrays in the frame
        self.Ani=Ani
        self.AZ=AZ
        self.Axmin=[]
        self.Axmax=[]
        self.Aymin=[]
        self.Aymax=[]

        # self.text_Ani
        region.nreg+=1



class MainWindow(wx.Frame): #A "frame" is what we normally think of as a window, so we have called it MainWindow



    def __init__(self, parent, title):    
        super(   MainWindow, self).__init__(parent, title=title, size=(450, 350)   )

        self.dirname=""
        self.filename=""
        self.ibox=0
        self.iv=0 #the vertical depth on the LHS
        self.iw=0 #the vertical depth on the RHS
        self.Aregion_objects=[]
        self.test_vbox=wx.BoxSizer(wx.VERTICAL)


        #Various lists containing the various properties a user can input, one list for each property of the region object
        # self.Axmin=[]
        # self.Axmax=[]
        # self.Aymin=[]
        # self.Aymax=[]
        #
        # self.Ani=[] #array of ion number densities
        # self.AZ=[]

        #For each property that the user can input (of a region), we need an array holding the various text controls:
        self.text_Atitle=[]
        self.text_Ani=[]
        self.tc_Ani=[]
        self.text_AZ=[]
        self.tc_AZ=[]
        self.text_Axmin=[]
        self.tc_Axmin=[]
        self.text_Axmax=[]
        self.tc_Axmax=[]
        self.text_Aymin=[]
        self.tc_Aymin=[]
        self.text_Aymax=[]
        self.tc_Aymax=[]
        #buttons
        self.button_Aremove=[]

        # self.text_=[]
        # self.tc_=[]

        self.sizer = wx.GridBagSizer(5, 1)
        #also declare a sizer that will contain all the regions on the LHS (sizer2)
        self.sizer2 = wx.GridBagSizer(1, 1)
        #self.SetMinSize(self.GetSize()) #prevents the window from being made arbitrarily small
        self.SetClientSize( (900,900) )
        self.SetMinSize( (-1,-1) )
        self.InitGUI()
        self.Centre()
        # self.SetupScrolling()
        self.Show()     



    def InitGUI(self):



        # MENUS
        fileMenu = wx.Menu()  # create menu for file
        helpMenu = wx.Menu()  # create a menu for help

        # Items in the file menu
        menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open", " Open a configuration file")  # open a file
        menuSave = fileMenu.Append(wx.ID_SAVE, "&Save", " Save this configuration file")  # save config
        menuSaveAs = fileMenu.Append(wx.ID_SAVEAS, "&SaveAs", " Save this configuration file with a new name")  # save config

        # Items in the help menu
        menuAbout = helpMenu.Append(wx.ID_ABOUT, "&About","")  # add about menu item

        # Make a new menubar, which we will put the menus into
        menuBar = wx.MenuBar()
        menuBar.Append(fileMenu, "&File")  # Adding the "filemenu" to the MenuBar
        menuBar.Append(helpMenu, "&Help")

        # menuBar.Append(fileMenu, "&Save")
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.


        # MENU EVENTS - attach a function to the menuOpen
        self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
        self.Bind(wx.EVT_MENU, self.save_all, menuSave)
        self.Bind(wx.EVT_MENU, self.save_as, menuSaveAs)
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        screenSize = wx.DisplaySize()
        screenWidth = screenSize[0]
        screenHeight = screenSize[1]

        # self.panel = wx.self.panel(self)
        # self.panel = wx.lib.scrolledself.panel.Scrolledself.panel(self,-1, size=(screenWidth,400), pos=(0,0), style=wx.SIMPLE_BORDER)
        # self.panel = wx.lib.scrolledself.panel.Scrolledself.panel(self, size=(425,400))
        self.panel = wx.lib.scrolledpanel.ScrolledPanel(self)
        # self.panel.Layout()
        self.panel.SetupScrolling()

        font_title = wx.Font(10, wx.DECORATIVE, wx.NORMAL, wx.BOLD)

        #self.panel.SetBackgroundColour('#4f5049')

        #a sizer is a way of laying out widgets, it is not a window in itself.
        # This is why we create widgets in the self.panel (by using "self.panel" as the parent), then afterwards add the widget to the sizer.
        sizer = self.sizer #wx.GridBagSizer(5, 1)
        #also declare a sizer that will contain all the regions on the LHS (sizer2)
        sizer2 = self.sizer2 #wx.GridBagSizer(1, 1)
        # sizer = wx.BoxSizer()

        #make a horizontal box dividing the page into left and RHS. We will put the gridbagsizer into the
        #LHS and the target picture into the RHS of the hbox
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(sizer,2) #add the box to the current window (self)
        #add the sizer to the box
        # sizer.Add(hbox,pos=(0,0),border=1)

        ######### Target View
        # sb = wx.StaticBox(self.panel, label="Optional Attributes")
        # sizer = wx.StaticBoxSizer(sb, wx.HORIZONTAL)

        #make a vertical box that will contain the stuff on the RHS
        vbox_RHS = wx.BoxSizer(wx.VERTICAL)
        hbox.Add(vbox_RHS,2) #add the vbox into the hbox, so it now takes up the 2nd position in the hbox (the gridbagsizer took the first)

        text_view = wx.StaticText(self.panel, label="Target View")
        text_view.SetFont(font_title)
        vbox_RHS.Add(text_view, flag=wx.TOP|wx.LEFT|wx.BOTTOM,border=15)
        self.iw+=1

        button_redraw = wx.Button(self.panel, label="Redraw")
        self.Bind(wx.EVT_BUTTON, self.redraw_pic, button_redraw)
        vbox_RHS.Add(button_redraw)
        self.iw+=1


        button_add = wx.Button(self.panel, label="Add Region")
        self.Bind(wx.EVT_BUTTON, self.add_region, button_add)
        # self.Bind(wx.EVT_BUTTON, lambda evt, temp="blah": self.add_region(evt, temp) )
        vbox_RHS.Add(button_add)
        self.iw+=1

        vbox_RHS.Add(sizer2)


        button_check = wx.Button(self.panel, label="Check")
        self.Bind(wx.EVT_BUTTON, self.check_all, button_check)
        sizer.Add(button_check, pos=(self.iv, 0))
        self.iv+=1




        sizer.AddGrowableCol(2)

        self.panel.SetSizer(hbox)



    # GUI EVENTS
    def checkBtnClick(self, e):
        self.tc_info.SetValue("blahh")

    # MENU ITEM EVENTS
    def OnAbout(self, e):
        dlg = wx.MessageDialog(self, "A small text editor", "My test editor", wx.OK)  # create a dialog (dlg) box to display the message, and ok button
        dlg.ShowModal()  # show the dialog box, modal means cannot do anything on the program until clicks ok or cancel
        dlg.Destroy()  # destroy the dialog box when its not needed

    def OnExit(self, e):
        self.Close(True)  # on menu item select, close the app frame.

    def OnOpen(self, e):
        self.file_open()
        e.Skip()

    def OnSave(self, e):
        self.file_save()
        e.Skip()


    def file_open(self):
        with wx.FileDialog(self, "Choose a file to open", self.dirname, "", "*.*", wx.OPEN) as dlg:
            if dlg.ShowModal() == wx.ID_OK:
                directory, filename = dlg.GetDirectory(), dlg.GetFilename()
                self.tc_info.LoadFile( '/'.join((directory, filename)) )
                self.SetTitle(filename)

    def check_all(self, e):
        self.read_all()
        print "Warnings:\n\n",qmes


    #----------------------------------------------------------------------
    def redraw_pic(self, event):
        #blah
        print "Redraw called"

    def save_all(self,event):
        print "save_all called"
        if(self.filename==""):
            print "No filename chosen yet so defaulting to save as"
            self.save_as(event)
            return
        else:
            self.write_file()


    def write_file(self):
        #using this: http://learnpythonthehardway.org/book/ex16.html
        print "write_file called"
        target = open(self.filename, 'w')
        print "opened target: self.filename="+self.filename
        line1="hi"
        target.write(line1)

        target.close()


    def save_as(self, event):
        print "save_as called"
        saveFileDialog = wx.FileDialog(self, "Save As", "", "","Python files (*.py)|*.py",wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        saveFileDialog.ShowModal()
        saveFileDialog.GetPath()
        saveFileDialog.Destroy()
        self.filename=saveFileDialog.GetPath()
        print "saveFileDialog.GetPath()="+saveFileDialog.GetPath()
        self.write_file()


    def read_all(self):

        print "nppc=",self.nppc
        print "t_FWHM=",self.t_FWHM

    # def add_region(self,e):
    #     #blah
    #     print "add called"


    def remove_region(self,event,id):
        print "remove_region called with id="+str(id)
        print "remove: event.GetId()=",event.GetId()
        sizer=self.sizer2
        btn = event.GetEventObject()

        sizer.Hide(self.text_Atitle[id])
        sizer.Detach(self.text_Atitle[id])
        self.text_Atitle[id].Destroy()

        sizer.Hide(btn)
        sizer.Remove(btn)

        sizer.Hide(self.text_Ani[id])
        sizer.Detach(self.text_Ani[id])
        self.text_Ani[id].Destroy()
        sizer.Hide(self.tc_Ani[id])
        sizer.Detach(self.tc_Ani[id])
        self.tc_Ani[id].Destroy()

        # wx.LayoutAlgorithm().LayoutWindow(self, self.panel)
        sizer.Layout()
        # self.panel.Fit()
        event.Skip()
        self.iw-=3

    def add_region(self,event):
        print "add_region called"

        # i=self.ibox
        i=region.nreg
        sizer=self.sizer2
        reg=region(Ani=0.0,AZ=0.0)
        self.Aregion_objects.append(reg)
        print "add_region:iw=",self.iw

        font_title = wx.Font(10, wx.DECORATIVE, wx.NORMAL, wx.BOLD)

        text_title = wx.StaticText(self.panel, label="Region "+str(i))
        text_title.SetFont(font_title)
        self.text_Atitle.append(   text_title  )
        sizer.Add(self.text_Atitle[i], pos=(self.iw, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM,border=15)
        self.iw+=1

        new_button = wx.Button(self.panel, label="Remove")
        self.button_Aremove.append( new_button )
        # self.Bind(wx.EVT_BUTTON, self.remove_region, button_remove)

        sizer.Add(self.button_Aremove[i], pos=(self.iw, 0))
        new_button.Bind( wx.EVT_BUTTON, lambda evt, temp=i: self.remove_region(evt, temp) )
        self.iw+=1


        #--------------------------------------------------------------------------------------------
        #append a new entry onto the array text_Ani which is just the title for the ni of this region
        new_text=wx.StaticText(self.panel, label="ni"   )
        self.text_Ani.append(   new_text  )
        #set the properties of this new entry in the array text_Ani
        self.text_Ani[i].SetToolTip(wx.ToolTip("Ion number density in per-cubic-metre, e.g. 6.0e28"))
        #add the text to the sizer
        sizer.Add(self.text_Ani[i], pos=(self.iw, 0), flag=wx.LEFT, border=10)
        #also make of course a new text entry box (text control), by adding a new one onto the array
        new_tc=wx.TextCtrl(self.panel)
        self.tc_Ani.append(   new_tc  )
        #add the text box (tc) to the sizer
        sizer.Add(self.tc_Ani[i], pos=(self.iw, 1), span=(1, 3), flag=wx.TOP)
        self.iw+=1 #increase the integer that gives the current vertical depth in sizer2

        #Make sure to tell the panel to update its scrollbar, now that the panel contents have increased in size:
        self.panel.SetupScrolling()
        #Finally need this call to check if the panel has changed:
        self.panel.Layout()
        event.Skip()

if __name__ == '__main__':

    app = wx.App()
    MainWindow(None, title="")
    app.MainLoop()