How to do FoldPanelBar inside ScrollPanel in wxPython? - python

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.

Related

wxpython: Set application color (Default Properties)

I want to change the color for my whole pythonwx application. I found out that the currently used colors are noted down in wx.Frame.DefaultAttributes.colBg respectively.colFg. I checked with paint that these are really the used colors.
Now there is a wx.Frame.GetDefaultAttributes() but not wx.Frame.SetDefaultAttributes() method. But I still need to change the color and I do not think that setting every control manually is a desired solution.
I tried:
frame.DefaultProperties = customProperties
and
frame.DefaultProperties.colBg = customColor
but both throw a AttributeError ("can't set attribute"). Any help is appreciated.
The default properties are probably defined within whatever theme you have set for the desktop. I do not believe that there is a way to redefine these from within wxpython.
The easiest way that I have found to set a default colour scheme, is to set the colours for each of the children in an object, such as a panel.
In the following code, keep pressing the Encrypt button to see the results.
import wx
from random import randrange
class CipherTexter(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(1000, 600))
self.panel = wx.Panel(self)
cipherText = wx.StaticText(self.panel, label="Cipher Texter ", pos=(20, 30))
encryptorText = wx.StaticText(self.panel, label="Encryptor ", pos=(20, 70))
decryptorText = wx.StaticText(self.panel, label="Decryptor ", pos=(20, 100))
self.cipher = wx.TextCtrl(self.panel, -1, style=wx.TE_MULTILINE, size=(400,400), pos=(400, 30))
self.encryptor = wx.TextCtrl(self.panel, -1, size=(100,30), pos=(200, 70))
self.decryptor = wx.TextCtrl(self.panel, -1, size=(100,30), pos=(200, 100))
self.encrypt = wx.Button(self.panel, -1, "Encrypt", pos=(20, 140))
self.decrypt = wx.Button(self.panel, -1, "Decrypt", pos=(20, 180))
self.panel.SetBackgroundColour('white')
self.encrypt.Bind(wx.EVT_BUTTON, self.encryptNow)
self.decrypt.Bind(wx.EVT_BUTTON, self.decryptNow)
self.Show()
def AColour(self):
red = randrange(0,255)
green = randrange(0,255)
blue = randrange(0,255)
x = wx.Colour(red,green,blue)
return x
def encryptNow(self, event):
cfg_colour = self.AColour()
txt_colour = self.AColour()
children = self.panel.GetChildren()
for child in children:
child.SetBackgroundColour(cfg_colour)
child.SetForegroundColour(txt_colour)
print(cfg_colour)
def decryptNow(self, event):
pass
app = wx.App(False)
frame = CipherTexter(None, "The SS Cipher")
app.MainLoop()

wxPython - Add Image to ListCtrl in any other column except the first?

I try to add an image to my ListCtrl, to add it to the first column i pretty easy and was done pretty quick. But i want to have some in other columns. I thought that SetItemImage could be my solution but it wont work.
So how do i add images to other column except the first one?
Here is my code so far:
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title,size=(250, 250))
panel = wx.Panel(self, -1)
panel.SetBackgroundColour('white')
self.browserList=wx.ListCtrl(panel, pos=(20,20), size=(300,300),style = wx.LC_REPORT|wx.BORDER_SUNKEN)
self.browserList.InsertColumn(0, '', width=50)
self.browserList.InsertColumn(1, 'Column 1', width=200)
self.list=wx.ImageList(16,16)
self.browserList.SetImageList(self.list, wx.IMAGE_LIST_SMALL)
img = wx.Image('Test.png', wx.BITMAP_TYPE_ANY)
img = wx.Bitmap(img)
browserimg = self.list.Add(img)
self.browserList.InsertItem(browserimg, 0)
self.browserList.SetItem(0, 1, "First Entry")
# How to add a Image to it?
self.browserList.SetItemImage(0, 1, browserimg)
app = wx.App()
frame = MyFrame(None, -1, 'frame')
frame.Show()
app.MainLoop()

Button generating (wx.Python, Python)

I am developing a wxpython, i am looking for button generating, for example.
In text box enter the value how many button have to generate.
While submitting that, i have to show in panel as many as button
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Background Reset Tutorial",size=wx.Size(500,500))
# Add a panel so it looks the correct on all platforms
self.panel = wx.Panel(self, wx.ID_ANY)
self.txt = wx.TextCtrl(self.panel,id=wx.ID_ANY,pos=(185,40))
txtSizer = wx.BoxSizer(wx.HORIZONTAL)
self.btn = wx.Button(self.panel,id=wx.ID_ANY,label="Submit",pos=
(190,70),size=(100,30))
self.btn.Bind(wx.EVT_BUTTON,self.onSubmit)
def onSubmit(self,event):
gettxt = self.txt.GetValue()
I got the solution
def onBtn(self,event):
self.val = self.txtstring1.GetValue()
Blue = wx.Button(self,label="Blue",pos=(30,50))
Blue.Bind(wx.EVT_BUTTON,self.onBlue)
Green = wx.Button(self,label="Green",pos=(300,50))
Green.Bind(wx.EVT_BUTTON,self.onGreen)
for self.button_name in range(self.val):
self.btn = wx.Button(self, label=str(self.button_name),pos=(50,50))
self.btn.Bind(wx.EVT_BUTTON, lambda evt, temp=self.button_name:
self.OnButton(evt, temp))
self.widgetSizer.Add(self.btn, 0, wx.ALL|wx.CENTER, 5)

wx.CollapsiblePane in a wx.Notebook resizing

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()

wxPython: TextCtrl in pop up window

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.

Categories

Resources