user908759
user908759

Reputation: 1355

wxPython hide and show panel

I am creating a Python application that requires a login on start up. I want to have a main panel that will hold my login panel and on successful login the login panel will hide and the main wx.Notebook will show. The following code works, but if in the login panel I re-size the application, after I successfully login and go to the main wx.Notebook the wx.Notebook does not fit the size of the screen. If I resize again while in the main wx.Notebook the main wx.Notebook will fit the window. How do I get the main wx.Notebook to automatically re-size to the window?

Main.py

import wx
import os
from titlePanel import titlePanel
from OneLblOneCB_HorzBoxSizer_Panel import OneLblOneCB_HorzBoxSizer_Panel
from OneLblOneMultiTxt_HorzBoxSizer_Panel import OneLblOneMultiTxt_HorzBoxSizer_Panel
from OneLblOneSingleTxt_HorzBoxSizer_Panel import OneLblOneSingleTxt_HorzBoxSizer_Panel
from OneLblTxtFile_HorzBoxSizer_Panel import OneLblTxtFile_HorzBoxSizer_Panel
from OneBtn_HorzBoxSizer_Panel import OneBtn_HorzBoxSizer_Panel
from LoginPanel import LoginPanel
from ProjectsPanel import ProjectsPanel
from EvDB import EvDB

class MyFrame(wx.Frame):
    def __init__(self, parent, ID, title):
        wx.Frame.__init__(self, parent, ID, title=title, size=(650,725))

        # Create Database Tables
        self.db = EvDB(self)
        self.db.createTbls()

        # Setting up the menu.
        filemenu= wx.Menu()

        ID_LOGIN = wx.NewId()
        ID_LOGOUT = wx.NewId()

        # wx.ID_ABOUT and wx.ID_EXIT are standard IDs provided by wxWidgets.
        menuOpen  = filemenu.Append(wx.ID_OPEN, "&Open"," Open and existing file")
        menuAbout  = filemenu.Append(wx.ID_ABOUT, "&About"," Information about this program")
        filemenu.AppendSeparator()
        menuLogin = filemenu.Append(ID_LOGIN, 'Login')
        menuLogout = filemenu.Append(ID_LOGOUT, 'Logout')
        filemenu.AppendSeparator()
        menuExit = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")

        # Creating the menubar.
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.

        # Set events.
        self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen )
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout )
        self.Bind(wx.EVT_MENU, self.OnLogin, menuLogin )
        self.Bind(wx.EVT_MENU, self.OnLogout, menuLogout )
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit )

        main = wx.Panel(self)
        self.mainLogin = LoginPanel(main,-1,addSpacers=1)
        self.mainLogin.Show()

        # Create a notebook on the panel
        self.nb = wx.Notebook(main)
        self.nb.Hide()

        # create the page windows as children of the notebook
        flowchartPg = wx.Panel(self.nb)
        entryPg = wx.ScrolledWindow(self.nb, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, style=wx.VSCROLL)
        entryPg.SetScrollRate( 5, 5 )
        projectsPg = ProjectsPanel(self.nb, -1)

        # add the pages to the notebook with the label to show on the tab
        self.nb.AddPage(projectsPg, "Projects")
        self.nb.AddPage(entryPg, "Entry")
        self.nb.AddPage(flowchartPg, "Flowchart")

        self.entTitle = titlePanel(entryPg, -1)
        self.entDescr = OneLblOneMultiTxt_HorzBoxSizer_Panel(entryPg,-1,
                       name="entDescr", lbl="Description")
        self.srcTypeList = ['None','Website', 'Youtube', 'PDF', 'Book']
        self.entSourceType = OneLblOneCB_HorzBoxSizer_Panel(entryPg,-1,
                   name="entSourceType", lbl="Source Type: ", cbList=self.srcTypeList, startVal='None')
        self.entSource = OneLblTxtFile_HorzBoxSizer_Panel(entryPg,-1,
                       name="entSource", lbl="Source: ")
        self.entSource.singleTxt.SetEditable(False)
        self.entSource._filename.Disable()
        self.entAuthor = OneLblOneSingleTxt_HorzBoxSizer_Panel(entryPg,-1,
                       name="entAuthor", lbl="Author: ", addSpacers=0)
        self.entAuthorCre = OneLblOneMultiTxt_HorzBoxSizer_Panel(entryPg,-1,
                       name="entAuthorCre", lbl="Author's Credentials: ")
        self.asPrjList = ['None','Project1', 'Project2', 'Project3', 'Project4']
        self.entAsProject = OneLblOneCB_HorzBoxSizer_Panel(entryPg,-1,
                   name="asProject", lbl="Assign to Project: ", cbList=self.asPrjList, startVal='None')
        self.saveOrEditList = ['New','Ev1', 'Ev2', 'Ev3', 'Ev4']
        self.entSaveOrEdit = OneLblOneCB_HorzBoxSizer_Panel(entryPg,-1,
                   name="saveOrEdit", lbl="New or Edit: ", cbList=self.saveOrEditList, startVal='New')
        self.entRemarks = OneLblOneMultiTxt_HorzBoxSizer_Panel(entryPg,-1,
                       name="sourceRemarks", lbl="Evidence Remarks: ")
        self.entRemarks.multiTxt.SetEditable(False)
        self.entAddBtn = OneBtn_HorzBoxSizer_Panel(entryPg, -1, name="entAddBtn", btn="Add")
        self.entSaveBtn = OneBtn_HorzBoxSizer_Panel(entryPg, -1, name="entSaveBtn", btn="Save")
        #self.loginTest = LoginPanel(entryPg, -1,addSpacers=1)
        self.entSaveBtn.button.Hide()

        # Bindings
        self.Bind(wx.EVT_COMBOBOX, self.SourceTypeEvtComboBox, self.entSourceType.cb)
        self.Bind(wx.EVT_COMBOBOX, self.AsProjectEvtComboBox, self.entAsProject.cb)
        self.Bind(wx.EVT_COMBOBOX, self.SaveOrEditEvtComboBox, self.entSaveOrEdit.cb)
        self.Bind(wx.EVT_BUTTON, self.EvtAddBtn, self.entAddBtn.button)
        self.Bind(wx.EVT_BUTTON, self.EvtSaveBtn, self.entSaveBtn.button)
        self.Bind(wx.EVT_BUTTON, self.EvtLoginBtn, self.mainLogin.loginBtns.LoginBtn)
        self.Bind(wx.EVT_BUTTON, self.EvtLogoutBtn, self.mainLogin.loginBtns.LogoutBtn)


        # Creating Sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        entryPgBox = wx.BoxSizer(wx.VERTICAL)

        # Adding Panels to BoxSizer entry panel sizer
        mainSizer.AddSpacer(10)
        mainSizer.Add(self.nb, 1, wx.ALL|wx.EXPAND)
        mainSizer.Add(self.mainLogin, 1, wx.ALL|wx.EXPAND)

        entryPgBox.AddSpacer(20)
        entryPgBox.Add(self.entAsProject, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entSaveOrEdit, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entTitle, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entDescr, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entSourceType, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entSource, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entAuthor, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entAuthorCre, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entRemarks, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)
        entryPgBox.Add(self.entAddBtn, 0, wx.EXPAND)
        entryPgBox.Add(self.entSaveBtn, 0, wx.EXPAND)
        entryPgBox.AddSpacer(10)


        # Setting Layouts
        entryPg.SetAutoLayout(True)
        entryPg.SetSizer(entryPgBox)
        entryPgBox.Fit(entryPg)


        main.SetAutoLayout(True)
        main.SetSizer(mainSizer)
        mainSizer.Fit(main)
        self.Layout()
        self.Show()

    def OnLogin(self,e):
        self.nb.Hide()
        self.mainLogin.Show()
        self.Layout()
        self.mainLogin.Layout()

    def OnLogout(self,e):
        self.mainLogin.Show()
        self.nb.Hide()
        self.Layout()
        self.mainLogin.Layout()

    def EvtLoginBtn(self,e):
        self.nb.Show()
        self.mainLogin.Hide()
        self.Layout()
        self.nb.Layout()

LoginPanel.py

class LoginPanel(wx.Panel):
    def __init__(self, parent, ID, addSpacers):
        wx.Panel.__init__(self, parent, ID)

        sizer = wx.BoxSizer(wx.VERTICAL)

        self.userNamePnl = OneLblOneSingleTxt_HorzBoxSizer_Panel(self,-1,
                       name="loginUser", lbl="Username: ", addSpacers=1)
        self.passwordPnl = OneLblOneSingleTxt_HorzBoxSizer_Panel(self,-1,
                       name="loginPass", lbl="Password: ", addSpacers=1)
        self.loginBtns = LoginBtnsPanel(self,-1)


        if addSpacers == 1:
            sizer.AddStretchSpacer()

        sizer.Add(self.userNamePnl,0,wx.EXPAND)
        sizer.AddSpacer(10)
        sizer.Add(self.passwordPnl,0,wx.EXPAND)
        sizer.AddSpacer(10)
        sizer.Add(self.loginBtns,0,wx.EXPAND)


        if addSpacers == 1:
            sizer.AddStretchSpacer()

        self.SetAutoLayout(True)
        self.SetSizer(sizer)
        sizer.Fit(self)

Upvotes: 3

Views: 12445

Answers (2)

user908759
user908759

Reputation: 1355

Got it! I was trying to redraw the frame with Layout(), but I needed to redraw the BoxSizer with Layout() I added the following code to the login button:

def EvtLoginBtn(self,e):
    self.nb.Show()
    self.mainLogin.Hide()
    self.mainSizer.Layout()

Upvotes: 2

user2963623
user2963623

Reputation: 2295

Call the Layout() method of the Frame and Panel like this

def EvtLoginBtn(self,e):
    self.nb.Show()
    self.mainLogin.Hide()
    self.Layout()
    self.nb.Layout()

The last call is probably not needed. Just check the program without it as well. The Layout() method redraws the Frame or Panel or whichever widget it is a method of.

UPDATE

Your code is obviously very big and has several other parts which I do not know. Anyways, here's something that I came up with, along the lines of the code you have provided, to show how you can do this. Hope this helps:

Main.py

import wx
from LoginPanel import LoginPanel

class MyFrame ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Something something", pos = wx.DefaultPosition, size = wx.Size( 300,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

        BoxSizer0 = wx.BoxSizer( wx.VERTICAL )

        # Add login panel
        self.login_panel = LoginPanel(self)
        BoxSizer0.Add(self.login_panel, 1, wx.EXPAND | wx.ALL, 0)

        # Add notebook panel and its pages
        self.nb = wx.Notebook( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.nb_subpanel1 = wx.Panel( self.nb, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        self.nb.AddPage( self.nb_subpanel1, u"something", False )
        self.nb_subpanel2 = wx.Panel( self.nb, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        self.nb.AddPage( self.nb_subpanel2, u"something else", False )

        BoxSizer0.Add( self.nb, 1, wx.EXPAND |wx.ALL, 0 )

        # Adds a logout button
        self.logout_button = wx.Button( self, wx.ID_ANY, u"Logout", wx.DefaultPosition, wx.DefaultSize, 0 )
        BoxSizer0.Add( self.logout_button, 0, wx.ALIGN_CENTER|wx.ALL, 5 )

        # Hide nb and logout button
        self.nb.Hide()
        self.logout_button.Hide()


        self.SetSizer( BoxSizer0 )
        self.Layout()

        self.Centre( wx.BOTH )
        self.Show()

        # Connect Events
        self.logout_button.Bind( wx.EVT_BUTTON, self.on_logout )

    # Virtual event handlers, override them in your derived class
    def on_logout( self, event ):
        self.nb.Hide()
        self.logout_button.Hide()
        self.login_panel.Show()
        self.Layout()

if __name__ == "__main__":
    app = wx.App()
    MyFrame(None)
    app.MainLoop()

LoginPanel.py

import wx

class LoginPanel ( wx.Panel ):

    def __init__( self, parent ):
        wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 300,300 ), style = wx.TAB_TRAVERSAL )

        BoxSizer01 = wx.BoxSizer( wx.VERTICAL )

        self.login_button = wx.Button( self, wx.ID_ANY, u"Login", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.login_button.SetDefault() 
        BoxSizer01.Add( self.login_button, 0, wx.ALIGN_CENTER|wx.ALL, 5 )


        self.SetSizer( BoxSizer01 )
        self.Layout()

        # Connect Events
        self.login_button.Bind( wx.EVT_BUTTON, self.on_login )


    # Virtual event handlers, overide them in your derived class
    def on_login( self, event ):
        self.Hide()
        self.Parent.nb.Show()
        self.Parent.logout_button.Show()
        self.Parent.Layout()

Upvotes: 1

Related Questions