I am trying to create a wx.CollapsiblePane on a wx.Notebook page which is successfully done using the minimal code example below. However, when the pane is unfolded, the frame fails to resize. However, if instead of creating a Notebook I make a simple Panel (see the commented line in the code), the frame does resize as expected. Any ideas why it doesn't work on a Notebook?
EDIT: I had a chance to test it on Windows and it works (wx 3.0.0.0 and 2.8). There only seems to be a problem in Linux (Ubuntu 13.10 with wx 2.8.12.1).
import wx
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
self.panel = wx.Panel(self)
# Notebook setup
self.nb = wx.Notebook(self.panel)
#self.nb = wx.Panel(self.panel) # uncomment this for a working example
self.pagepanel = wx.Panel(self.nb)
self.nb.AddPage(self.pagepanel, 'page')
# add something to the Notebook page
checkbox = wx.CheckBox(self.pagepanel, -1, 'box 1')
# add CollapsiblePane to the Notebook page
colpane = wx.CollapsiblePane(self.pagepanel)
colpane.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnPaneChanged)
# add something to the CollapsiblePane
win = colpane.GetPane()
checkbox2 = wx.CheckBox(win, -1, 'box 2')
# Set CollapsiblePane sizer
colpanesizer = wx.BoxSizer(wx.VERTICAL)
colpanesizer.Add(checkbox2, -1)
win.SetSizer(colpanesizer)
colpanesizer.SetSizeHints(win)
colpane.Collapse()
# set Notebook page sizer
pagesizer = wx.BoxSizer(wx.VERTICAL)
pagesizer.Add(checkbox)
pagesizer.Add(colpane)
self.pagepanel.SetSizerAndFit(pagesizer)
# set the whole Panel sizer
panelsizer = wx.BoxSizer()
panelsizer.Add(self.nb)
self.panel.Layout()
self.panel.SetSizerAndFit(panelsizer)
# set Frame size
self.Fit()
def OnPaneChanged(self, event):
# redo the layout
self.pagepanel.Layout()
self.pagepanel.Fit()
self.panel.Layout()
self.panel.Fit()
self.Fit()
app = wx.App()
frame = MyFrame()
frame.Center()
frame.Show()
app.MainLoop()
colpanesizer.Add(checkbox2, -1) should be colpanesizer.Add(checkbox2)
Try:
import wx
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
self.panel = wx.Panel(self)
# Notebook setup
self.nb = wx.Notebook(self.panel)
#self.nb = wx.Panel(self.panel) # uncomment this for a working example
self.pagepanel = wx.Panel(self.nb)
self.nb.AddPage(self.pagepanel, 'page')
# add something to the Notebook page
checkbox = wx.CheckBox(self.pagepanel, -1, 'box 1')
# add CollapsiblePane to the Notebook page
colpane = wx.CollapsiblePane(self.pagepanel)
colpane.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnPaneChanged)
# add something to the CollapsiblePane
win = colpane.GetPane()
checkbox2 = wx.CheckBox(win, -1, 'box 2')
# Set CollapsiblePane sizer
colpanesizer = wx.BoxSizer(wx.VERTICAL)
colpanesizer.Add(checkbox2)
win.SetSizer(colpanesizer)
colpanesizer.SetSizeHints(win)
colpane.Collapse()
# set Notebook page sizer
pagesizer = wx.BoxSizer(wx.VERTICAL)
pagesizer.Add(checkbox)
pagesizer.Add(colpane)
self.pagepanel.SetSizerAndFit(pagesizer)
# set the whole Panel sizer
panelsizer = wx.BoxSizer()
panelsizer.Add(self.nb)
self.panel.Layout()
self.panel.SetSizerAndFit(panelsizer)
# set Frame size
self.Fit()
def OnPaneChanged(self, event):
# redo the layout
self.pagepanel.Layout()
self.pagepanel.Fit()
self.panel.Layout()
self.panel.Fit()
self.Fit()
app = wx.App()
frame = MyFrame()
frame.Center()
frame.Show()
app.MainLoop()
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to make that when selecting an element in the ComboBox print a message that is in the tuple in the TextCtrl, depending on the item I chose
When I did it the way I investigated, I throw an error.
import wx
#Mods
Nom_Mods = ["Alca v3", "Barcelone v1", "Anti-Fed (French)", "Elegance v3"]
Info_Mods = ["(ZL + Joystick2) To Open Menu\n(B) To close Menu\nCreate by KillerGamer81"]
#EndMods
class PageOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sz = wx.BoxSizer(wx.VERTICAL)
#Controls
self.Listade_Menus = wx.ComboBox(self, -1, pos=(10,80), size=(173,22), choices = Nom_Mods, style= wx.CB_READONLY)
Cuadro_de_info = wx.TextCtrl(self, -1, "", pos=(200,80), size=(175,80), style = wx.TE_MULTILINE|wx.TE_NO_VSCROLL|wx.TE_READONLY)
class MainFrame(wx.Frame):
def __init__(self):
no_sys_menu = wx.DEFAULT_FRAME_STYLE & (~wx.RESIZE_BORDER) & (~wx.MAXIMIZE_BOX)
wx.Frame.__init__(self, None, title="ProyectoU", style=no_sys_menu, size=(400,225))
ico = wx.Icon('Recursos/icono.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(ico)
# Here we create a panel and a notebook on the panel
p = wx.Panel(self)
nb = wx.Notebook(p)
# create the page windows as children of the notebook
page1 = PageOne(nb)
# add the pages to the notebook with the label to show on the tab
nb.AddPage(page1, "Inyec/Conec")
# 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)
if __name__ == "__main__":
app = wx.App()
MainFrame().Show()
app.MainLoop()
The first error, would be a indentation error!
The problem is that you are not Binding to the ComboBox event i.e. when you make a selection an event will fire, which must be caught and acted upon.
You need to catch that event and put the currently selected text from the combobox (or whatever) into the textctrl. Currently you are making no attempt to do that.
Here is what I assume you want.
import wx
#Mods
Nom_Mods = ["Alca v3", "Barcelone v1", "Anti-Fed (French)", "Elegance v3"]
Info_Mods = ["(ZL + Joystick2) To Open Menu\n(B) To close Menu\nCreate by KillerGamer81"]
#EndMods
class PageOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sz = wx.BoxSizer(wx.VERTICAL)
#Controls
self.Listade_Menus = wx.ComboBox(self, -1, pos=(10,80), size=(173,22), choices = Nom_Mods, style= wx.CB_READONLY)
#Bind a callback to the event emitted by the Combobox selection
self.Listade_Menus.Bind(wx.EVT_COMBOBOX, self.Nom_Mods_Selected)
self.Cuadro_de_info = wx.TextCtrl(self, -1, "", pos=(200,80), size=(175,80), style = wx.TE_MULTILINE|wx.TE_NO_VSCROLL|wx.TE_READONLY)
# When a selection is made populate the textctrl with the selected text
def Nom_Mods_Selected(self, event):
self.Cuadro_de_info.SetValue(self.Listade_Menus.GetStringSelection())
class MainFrame(wx.Frame):
def __init__(self):
no_sys_menu = wx.DEFAULT_FRAME_STYLE & (~wx.RESIZE_BORDER) & (~wx.MAXIMIZE_BOX)
wx.Frame.__init__(self, None, title="ProyectoU", style=no_sys_menu, size=(400,225))
ico = wx.Icon('Recursos/icono.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(ico)
# Here we create a panel and a notebook on the panel
p = wx.Panel(self)
nb = wx.Notebook(p)
# create the page windows as children of the notebook
page1 = PageOne(nb)
# add the pages to the notebook with the label to show on the tab
nb.AddPage(page1, "Inyec/Conec")
# 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)
if __name__ == "__main__":
app = wx.App()
MainFrame().Show()
app.MainLoop()
I'm bulding a wxpython GUI.
When I'm running the code all the components are in the left-top corner, on top of each other.
When I resize the window, they align as planned.
The window before resize
The window after resize
How can I fix this?
my code:
class Screen(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(900,500))
self.SetBackgroundColour("#E4F1FE")
self.Show(True)
self.InitUI()
def InitUI(self):
pnlMain = wx.Panel(self, size=(900,500))
# Setup Font
font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
font.SetPointSize(9)
# Setup horizontal box sizer
self.bsMain = wx.BoxSizer(wx.HORIZONTAL)
self.bsMain.SetDimension(0,0,900,500)
# Setup LEFT box sizer
self.bsLeft = wx.BoxSizer(wx.VERTICAL)
self.bsLeft.SetMinSize((3*(self.GetSize()[0]/4),self.GetSize()[1]))
# Make add button
btnAdd = wx.Button(pnlMain, label="+", size=(50,50))
# Add all the components to the LEFT sizer
self.bsLeft.Add(btnAdd, flag = wx.ALIGN_BOTTOM | wx.ALIGN_LEFT )
# Setup RIGHT bsMain sizer
self.bsRight = wx.BoxSizer(wx.VERTICAL)
self.bsRight.SetMinSize((self.GetSize()[0]/4,self.GetSize()[1]))
# Make users headline
stUsers = wx.StaticText(pnlMain, label="USERS")
stUsers.SetFont(font)
# Make users list control
lcUsers = wx.ListCtrl(pnlMain,style=wx.LC_REPORT|wx.SUNKEN_BORDER)
lcUsers.Show(True)
lcUsers.InsertColumn(0,"user")
lcUsers.InsertColumn(1,"status")
# Add all the components to the RIGHT sizer
self.bsRight.Add((-1,10))
self.bsRight.Add(stUsers, flag=wx.LEFT | wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTRE, border=5)
self.bsRight.Add((-1,10))
self.bsRight.Add(lcUsers, flag=wx.EXPAND)
# Add the vertical sizers to the horizontal sizer
self.bsMain.Add(self.bsLeft)
self.bsMain.Add(self.bsRight)
# Add the vertical sizer to the panel
pnlMain.SetSizer(self.bsMain)
This is a common problem for new wxPython programmers. The solution is almost always a call to the top level sizer's Layout method. Occasionally you'll need to call the top-level parent's Layout instead. In your case, either will work. You can add:
pnlMain.Layout()
or
self.bsMain.Layout()
to the bottom of InitUI method and it should force your widgets to redraw in their correct locations. I've seen some widgets behave badly because they start out with a zero size until their shown. In those cases, I have usually needed to use wx.CallAfter to call Layout. Anyway, here's a complete example using your code:
import wx
class Screen(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(900,500))
self.SetBackgroundColour("#E4F1FE")
self.Show(True)
self.InitUI()
def InitUI(self):
pnlMain = wx.Panel(self, size=(900,500))
# Setup Font
font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
font.SetPointSize(9)
# Setup horizontal box sizer
self.bsMain = wx.BoxSizer(wx.HORIZONTAL)
self.bsMain.SetDimension(0,0,900,500)
# Setup LEFT box sizer
self.bsLeft = wx.BoxSizer(wx.VERTICAL)
self.bsLeft.SetMinSize((3*(self.GetSize()[0]/4),self.GetSize()[1]))
# Make add button
btnAdd = wx.Button(pnlMain, label="+", size=(50,50))
# Add all the components to the LEFT sizer
self.bsLeft.Add(btnAdd, flag = wx.ALIGN_BOTTOM | wx.ALIGN_LEFT )
# Setup RIGHT bsMain sizer
self.bsRight = wx.BoxSizer(wx.VERTICAL)
self.bsRight.SetMinSize((self.GetSize()[0]/4,self.GetSize()[1]))
# Make users headline
stUsers = wx.StaticText(pnlMain, label="USERS")
stUsers.SetFont(font)
# Make users list control
lcUsers = wx.ListCtrl(pnlMain,style=wx.LC_REPORT|wx.SUNKEN_BORDER)
lcUsers.Show(True)
lcUsers.InsertColumn(0,"user")
lcUsers.InsertColumn(1,"status")
# Add all the components to the RIGHT sizer
self.bsRight.Add((-1,10))
self.bsRight.Add(stUsers, flag=wx.LEFT | wx.EXPAND | wx.ALIGN_CENTER | wx.ALIGN_CENTRE, border=5)
self.bsRight.Add((-1,10))
self.bsRight.Add(lcUsers, flag=wx.EXPAND)
# Add the vertical sizers to the horizontal sizer
self.bsMain.Add(self.bsLeft)
self.bsMain.Add(self.bsRight)
# Add the vertical sizer to the panel
pnlMain.SetSizer(self.bsMain)
self.bsMain.Layout()
if __name__ == '__main__':
app = wx.App(False)
frame = Screen(None, 'Layout')
app.MainLoop()
Note: I've rarely needed to call Refresh. I think Layout does so automatically.
I tried to do a collapsible FoldPanelBar inside of a ScrollPanel. But it is not loading the contents of the FoldPanelBar. The list control UI inside the fold panel is not even loading. I tried replacing with a regular panel, but the result is the same. Could you please let me know if I am missing something here?
import wx
from wx.lib import scrolledpanel
import wx.lib.agw.foldpanelbar as fpb
class MyPanel(wx.lib.scrolledpanel.ScrolledPanel):
def __init__(self, parent):
wx.lib.scrolledpanel.ScrolledPanel.__init__(self, parent=parent, size=parent.GetSize(), style = wx.ALL|wx.EXPAND)
self.SetAutoLayout(1)
self.SetupScrolling()
csStyle = fpb.CaptionBarStyle()
csStyle.SetFirstColour(wx.Colour(190, 190, 190, 255))
csStyle.SetSecondColour(wx.Colour(167, 232, 146, 255))
csStyle.SetCaptionFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.BOLD))
m_pnl = fpb.FoldPanelBar(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize,
fpb.FPB_VERTICAL)
item = m_pnl.AddFoldPanel("Set 1", collapsed=True, cbstyle=csStyle)
self.listContainer = wx.ListCtrl(item)
self.listContainer.InsertColumn(0, 'Column1', width=250)
self.listContainer.InsertColumn(1, 'Column2', width=150)
self.listContainer.InsertColumn(2, 'Column3')
m_pnl.AddFoldPanelWindow(item, self.listContainer)
btnGo = wx.Button(item, wx.ID_ANY, "Go", size=(50,-1))
m_pnl.AddFoldPanelWindow(item, btnGo)
item = m_pnl.AddFoldPanel("Set 2", collapsed=True, cbstyle=csStyle)
self.listContainer2 = wx.ListCtrl(item, style=wx.LC_REPORT)
self.listContainer2.InsertColumn(0, 'Column1', width=250)
self.listContainer2.InsertColumn(1, 'Column2', width=150)
self.listContainer2.InsertColumn(2, 'Column3')
m_pnl.AddFoldPanelWindow(item, self.listContainer2)
self.pnl = m_pnl
if __name__ == '__main__':
app = wx.App(False)
frame = wx.Frame(None, size=(650, 400), style=wx.DEFAULT_FRAME_STYLE)
panel = MyPanel(frame)
frame.Show()
app.MainLoop()
I see two issues with your example. First, the columns will not show in normal list mode of wx.ListCtrl. Set the LC_REPORT style as follows:
self.listContainer = wx.ListCtrl(item, style=wx.LC_REPORT)
Secondary, there is no proper layouting/sizing happening here.
# ...
panel = MyPanel(frame)
# Add sizer information for the scrolled panel
szmain = wx.BoxSizer(wx.VERTICAL)
szmain.Add(panel.pnl, 1, wx.EXPAND|wx.ALL, 4)
panel.SetSizer(szmain)
By applying these changes on wxPython classic 3.0.2 (MSW) at least the controls are layouted so that they fill the frame.
I have created a pop up window, but the TextCtrl is not fully expanded to fill up the window. It works great if I use StaticText instead, (but if content too large then I would need the scroll bar, that is why I am using TextCtrl now). Please provide some guidance.
self.description = WindowPopup(self, wx.SIMPLE_BORDER, content)
btn = event.GetEventObject()
dw = wx.DisplaySize()[0]
width = self.description.GetSize()[0]
y = btn.ClientToScreen((0,0))[1]
height = btn.GetSize()[1]
x = dw - width - 20 - 10
self.description.Position((x, y), (0, height))
self.description.Show(True)
class WindowPopup(wx.PopupWindow):
""" Pops up a window to provide description for the selection """
def __init__(self, parent, style, content):
wx.PopupWindow.__init__(self, parent, style)
self.SetSize((700, 287))
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
st = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE | wx.TE_READONLY)
st.SetValue(content)
sizer.Add(st, 0, wx.EXPAND)
panel.SetSizer(sizer)
I suspect your problem is that the panel is not as big as the popupwindow ... so even though the textfield is expanding to fill its sizer area it is not filling the popup its self.
try using something like
def __init__(...):
...
self.SetMinSize((700,287))
sizer2 = wx.BoxSizer()
sizer2.Add(panel)
self.SetSizer(sizer2)
also make sure that you are calling layout on it at some point (note this is totally untested... so it may need some tweeks, or even worse just be wrong...)
The actual answer is:
sizer = wx.BoxSizer(wx.VERTICAL)
st = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE | wx.TE_READONLY, size = (500, 174))
st.SetValue(content)
self.SetSize((500, 174))
sizer.Add(st, 0, wx.EXPAND)
self.SetSizer(sizer)
self.Layout()
self.Show(True)
Credits to Joran for noticing Layout().
PopupWindow does not require an additional panel, because the window itself can have sizer set to it. This has been realized by using the wxPython Widget Inspection Tool.
Make sure TextCtrl and PopupWindow have the same size.
I am trying to pass the tuple of the the checked strings in one panel to the textCtrl widget in another panel. I thought that if I polled the panel class containing the checklistbox widget for the checked boxes and set that equal to an attribute of the panel class containing the TextCtrl widget I could do things in the TextCtrl widget based on the boxes that are checked
I also tried using pubsub but I was having difficulty and wasn't sure if this was the case that you would use it or not.
As a disclaimer I am new to object oriented programming and python. I am making progress in learning object oriented programming but there are still things that are a bit fuzzy for me.
Here is my code:
#! /usr/bin/python
# Trying to do things in a separate panel based on
# events that happen in another panel
import wx
# ----- Functions
# ----- Classes
class chkbxPanel(wx.Panel):
# This class defines the panel that will
# contain the checkbox
def __init__(self, parent):
wx.Panel.__init__(self,parent=parent, id=-1)
# Widgets
List = ['one','two','three']
Prompt = 'Please Make a Choice'
self.ChkBx = wx.CheckListBox(self,id=-1,choices=List,size=(-1,200))
self.PromptChkBx = wx.StaticText(self,id=-1,label=Prompt)
# Page Sizers
self.panel_vertSizer=wx.BoxSizer(wx.VERTICAL)
self.panel_vertSizer.Add(self.PromptChkBx,proportion=0,flag=wx.ALIGN_LEFT)
self.panel_vertSizer.Add(self.ChkBx,proportion=0,flag=wx.ALIGN_LEFT)
# Invoke Sizer
self.SetSizer(self.panel_vertSizer)
# Make 'self' (the panel) shrink to the minimum size
# required by the controls
self.Fit()
# end __init__
# ----- Functions
class resultsPanel(wx.Panel):
# This class define the panel that will
# contain the textctrl
def __init__ (self,parent):
wx.Panel.__init__(self,parent=parent,id=-1)
# Widgets
ResultsPanelTitle = 'Results:'
self.ResultsTitle = wx.StaticText(self, id=-1, label= ResultsPanelTitle)
self.Results = wx.TextCtrl(self, id=-1,size=(300,500),style=(wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_DONTWRAP))
self.CheckedBxs = ()
lenofcb = len(self.CheckedBxs)
typeofcb = type(self.CheckedBxs)
self.Results.AppendText('How Many Boxes are Checkd:\n')
self.Results.AppendText(str(lenofcb)+'\n')
self.Results.AppendText(str(typeofcb)+'\n')
# Page Sizer
self.panel_vertSizer = wx.BoxSizer(wx.VERTICAL)
self.panel_vertSizer.Add(self.ResultsTitle,proportion=0, flag=wx.ALIGN_LEFT)
self.panel_vertSizer.Add(self.Results, proportion=0, flag=wx.ALIGN_LEFT)
# Invoke Sizer
self.SetSizer(self.panel_vertSizer)
# Make 'self' (the panel) shrink to the minimum size
# required by the controls
self.Fit()
# end __init__
# ----- Functions
# ----- Main Frame
class MainFrame(wx.Frame):
# A 2-Control Class With BoxSizers
def __init__(self):
# Configure the Figure
titleText = 'Wx Question'
wx.Frame.__init__( self, None, title=titleText
,size=(600,300), style=wx.DEFAULT_FRAME_STYLE)
# First Frame Control automatically expands to the
# Frame's client size
frame_panel = wx.Panel(self)
# Create the Controls
LeftPanel = chkbxPanel(frame_panel)
RightPanel = resultsPanel(frame_panel)
RightPanel.CheckedBxs = LeftPanel.ChkBx.GetCheckedStrings()
RightPanel.CheckedBxs = ('one','two')
# Create Sizers and add the controls
panelCtrls_horzSizer = wx.BoxSizer(wx.HORIZONTAL)
panelCtrls_horzSizer.Add(LeftPanel)
panelCtrls_horzSizer.Add(RightPanel)
framePanel_vertSizer = wx.BoxSizer(wx.VERTICAL)
framePanel_vertSizer.Add(panelCtrls_horzSizer)
frame_panel.SetSizer(framePanel_vertSizer)
frame_panel.Fit()
self.SetSize((600,600))
# Main if statement
if __name__ == '__main__':
app = wx.PySimpleApp(redirect=False)
appFrame = MainFrame().Show()
app.MainLoop()
Thank you for any help
You could do your event binding in the parent class as it has access to both panels
#! /usr/bin/python
# Trying to do things in a separate panel based on
# events that happen in another panel
import wx
# ----- Functions
# ----- Classes
class ChkbxPanel(wx.Panel):
# This class defines the panel that will
# contain the checkbox
def __init__(self, parent):
wx.Panel.__init__(self, parent=parent, id=-1)
# Widgets
choices = ['one', 'two', 'three']
prompt = 'Please Make a Choice'
self.chkBx = wx.CheckListBox(self, choices=choices, size=(-1, 200))
self.PromptChkBx = wx.StaticText(self, label=prompt)
# Page Sizers
self.panel_vertSizer = wx.BoxSizer(wx.VERTICAL)
self.panel_vertSizer.Add(self.PromptChkBx, proportion=0,
flag=wx.ALIGN_LEFT)
self.panel_vertSizer.Add(self.chkBx, proportion=0, flag=wx.ALIGN_LEFT)
# Invoke Sizer
self.SetSizer(self.panel_vertSizer)
# Make 'self' (the panel) shrink to the minimum size
# required by the controls
self.Fit()
# end __init__
# ----- Functions
class ResultsPanel(wx.Panel):
# This class define the panel that will
# contain the textctrl
def __init__ (self, parent):
wx.Panel.__init__(self, parent=parent, id=-1)
# Widgets
resultsPanelTitle = 'Results:'
self.resultsTitle = wx.StaticText(self, label=resultsPanelTitle)
self.results = wx.TextCtrl(self, size=(300, 500),
style=(wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_DONTWRAP))
self.CheckedBxs = ()
lenofcb = len(self.CheckedBxs)
typeofcb = type(self.CheckedBxs)
self.results.AppendText('How Many Boxes are Checkd:\n')
self.results.AppendText(str(lenofcb) + '\n')
self.results.AppendText(str(typeofcb) + '\n')
# Page Sizer
self.panel_vertSizer = wx.BoxSizer(wx.VERTICAL)
self.panel_vertSizer.Add(self.resultsTitle, proportion=0, flag=wx.ALIGN_LEFT)
self.panel_vertSizer.Add(self.results, proportion=0, flag=wx.ALIGN_LEFT)
# Invoke Sizer
self.SetSizer(self.panel_vertSizer)
# Make 'self' (the panel) shrink to the minimum size
# required by the controls
self.Fit()
# end __init__
# ----- Functions
# ----- Main Frame
class MainFrame(wx.Frame):
# A 2-Control Class With BoxSizers
def __init__(self):
# Configure the Figure
titleText = 'Wx Question'
wx.Frame.__init__(self, None, title=titleText
, size=(600, 300), style=wx.DEFAULT_FRAME_STYLE)
# First Frame Control automatically expands to the
# Frame's client size
frame_panel = wx.Panel(self)
# Create the Controls
leftPanel = ChkbxPanel(frame_panel)
self.rightPanel = ResultsPanel(frame_panel)
# Create Sizers and add the controls
panelCtrls_horzSizer = wx.BoxSizer(wx.HORIZONTAL)
panelCtrls_horzSizer.Add(leftPanel)
panelCtrls_horzSizer.Add(self.rightPanel)
framePanel_vertSizer = wx.BoxSizer(wx.VERTICAL)
framePanel_vertSizer.Add(panelCtrls_horzSizer)
frame_panel.SetSizer(framePanel_vertSizer)
frame_panel.Fit()
self.SetSize((600, 600))
leftPanel.chkBx.Bind(wx.EVT_CHECKLISTBOX, self.onCheckBox)
def onCheckBox(self, event):
checked = event.EventObject.CheckedStrings
self.rightPanel.results.AppendText(
'Checked: {0}, Qty checked: {1}\n'.format(checked, len(checked)))
# Main if statement
if __name__ == '__main__':
app = wx.App(redirect=False)
appFrame = MainFrame().Show()
app.MainLoop()
I removed all comments, whitespace to reduces lines. And added comments where I changed/added code. (1),(2),(3)
import wx
class chkbxPanel(wx.Panel):
def __init__(self, parent, resultsPanel):
wx.Panel.__init__(self,parent=parent, id=-1)
List = ['one','two','three']
Prompt = 'Please Make a Choice'
self.ChkBx = wx.CheckListBox(self,id=-1,choices=List,size=(-1,200))
### (1) Bind CHECKLISTBOX event (which is triggered when checkbox is toggled: checked/unchecked)
self.ChkBx.Bind(wx.EVT_CHECKLISTBOX, lambda e: resultsPanel.changed(self.ChkBx.GetCheckedStrings()))
###
self.PromptChkBx = wx.StaticText(self,id=-1,label=Prompt)
self.panel_vertSizer=wx.BoxSizer(wx.VERTICAL)
self.panel_vertSizer.Add(self.PromptChkBx,proportion=0,flag=wx.ALIGN_LEFT)
self.panel_vertSizer.Add(self.ChkBx,proportion=0,flag=wx.ALIGN_LEFT)
self.SetSizer(self.panel_vertSizer)
self.Fit()
class resultsPanel(wx.Panel):
def __init__ (self,parent):
wx.Panel.__init__(self,parent=parent,id=-1)
ResultsPanelTitle = 'Results:'
self.ResultsTitle = wx.StaticText(self, id=-1, label= ResultsPanelTitle)
self.Results = wx.TextCtrl(self, id=-1,size=(300,500),style=(wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_DONTWRAP))
self.panel_vertSizer = wx.BoxSizer(wx.VERTICAL)
self.panel_vertSizer.Add(self.ResultsTitle,proportion=0, flag=wx.ALIGN_LEFT)
self.panel_vertSizer.Add(self.Results, proportion=0, flag=wx.ALIGN_LEFT)
self.SetSizer(self.panel_vertSizer)
self.Fit()
### (2): Called when checkbox is toggled with checkbox strings as parameter. See (1)
def changed(self, checked_strings):
self.Results.AppendText('How Many Boxes are Checkd:\n')
self.Results.AppendText(str(len(checked_strings))+'\n')
self.Results.AppendText(str(checked_strings)+'\n')
###
class MainFrame(wx.Frame):
def __init__(self):
titleText = 'Wx Question'
wx.Frame.__init__(self, None, title=titleText ,size=(600,300), style=wx.DEFAULT_FRAME_STYLE)
frame_panel = wx.Panel(self)
### (3): Changed creation order. Passed resultsPanel instance to chkbxPanel creator
RightPanel = resultsPanel(frame_panel)
LeftPanel = chkbxPanel(frame_panel, RightPanel)
###
RightPanel.CheckedBxs = LeftPanel.ChkBx.GetCheckedStrings()
RightPanel.CheckedBxs = ('one','two')
panelCtrls_horzSizer = wx.BoxSizer(wx.HORIZONTAL)
panelCtrls_horzSizer.Add(LeftPanel)
panelCtrls_horzSizer.Add(RightPanel)
framePanel_vertSizer = wx.BoxSizer(wx.VERTICAL)
framePanel_vertSizer.Add(panelCtrls_horzSizer)
frame_panel.SetSizer(framePanel_vertSizer)
frame_panel.Fit()
self.SetSize((600,600))
if __name__ == '__main__':
app = wx.PySimpleApp(redirect=False)
appFrame = MainFrame().Show()
app.MainLoop()