wXPython: Unable to get widget to enlarge/expand in size - dialog

I can't get the listctrl widget to expand.
example picture: http://img109.imageshack.us/img109/3171/22488459.jpg
This code simply creates a dialog box and creates a CheckListCtrlMixin which is a ListCtrl with check boxes.
import wx
import re, os, sys
from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent):
wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
CheckListCtrlMixin.__init__(self)
ListCtrlAutoWidthMixin.__init__(self)
class QueueDialog(wx.Dialog):
def __init__(self, parent, title):
super(QueueDialog, self).__init__(parent=parent,
title=title, size=(400, 500))
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
sb = wx.StaticBox(panel, label='Queue')
sbs = wx.StaticBoxSizer(sb, orient=wx.VERTICAL)
panel2 = wx.Panel(panel)
hbox3 = wx.BoxSizer(wx.VERTICAL)
hbox3.Add(panel2, proportion=1, flag=wx.EXPAND|wx.ALL)
listB = CheckListCtrl(panel2)
listB.InsertColumn(0, "Test", width=100)
listB.InsertColumn(1, "Status", wx.LIST_FORMAT_RIGHT)
dalist = ["heh", "ha", "hello"]
for name in dalist[0:3]:
index = listB.InsertStringItem(sys.maxint, name[0:-1])
sbs.Add(hbox3, proportion=1,flag=wx.EXPAND|wx.ALL)
panel.SetSizer(sbs)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
okButton = wx.Button(self, label='OK')
closeButton = wx.Button(self, label='Cancel')
hbox2.Add(okButton)
hbox2.Add(closeButton, flag=wx.LEFT, border=5)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(panel, proportion=1, flag=wx.EXPAND|wx.ALL, border=10)
vbox.Add(hbox2, flag= wx.ALIGN_CENTER|wx.BOTTOM, border=10)
self.SetSizer(vbox)
def OnClose(self, e):
self.Destroy()
class window(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 400))
e = QueueDialog(None, title='Queue')
e.ShowModal()
e.Destroy()
self.Centre()
self.Show(True)
app = wx.App(0)
window(None, -1, 'e')
app.MainLoop()

I don't know why you have the second panel, but it's really not needed and makes things more complex. Here's one version that works on my machine:
import wx
import re, os, sys
from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent):
wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
CheckListCtrlMixin.__init__(self)
ListCtrlAutoWidthMixin.__init__(self)
class QueueDialog(wx.Dialog):
def __init__(self, parent, title):
super(QueueDialog, self).__init__(parent=parent,
title=title, size=(400, 500))
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
sb = wx.StaticBox(panel, label='Queue')
sbs = wx.StaticBoxSizer(sb, orient=wx.VERTICAL)
hbox3 = wx.BoxSizer(wx.VERTICAL)
listB = CheckListCtrl(panel)
listB.InsertColumn(0, "Test", width=100)
listB.InsertColumn(1, "Status", wx.LIST_FORMAT_RIGHT)
hbox3.Add(listB, 1, wx.EXPAND)
dalist = ["heh", "ha", "hello"]
for name in dalist[0:3]:
index = listB.InsertStringItem(sys.maxint, name[0:-1])
sbs.Add(hbox3, proportion=1,flag=wx.EXPAND|wx.ALL)
panel.SetSizer(sbs)
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
okButton = wx.Button(self, label='OK')
closeButton = wx.Button(self, label='Cancel')
hbox2.Add(okButton)
hbox2.Add(closeButton, flag=wx.LEFT, border=5)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(panel, proportion=1, flag=wx.EXPAND|wx.ALL, border=10)
vbox.Add(hbox2, flag= wx.ALIGN_CENTER|wx.BOTTOM, border=10)
self.SetSizer(vbox)
def OnClose(self, e):
self.Destroy()
class window(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 400))
e = QueueDialog(None, title='Queue')
e.ShowModal()
e.Destroy()
self.Centre()
self.Show(True)
app = wx.App(0)
window(None, -1, 'e')
app.MainLoop()

Related

How to add vertical and horizontal scollbar to my MainFrame on wxpython

Panels are dynamically added during the execution of the program. How do I add a Scrollbar to my MainFrame when it is initialized so that I can see the panels added below each other?
import wx
class MainFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super().__init__(None, *args, **kwargs)
self.Title = 'Wx App'
screen_width, screen_height = wx.GetDisplaySize()
win_width = min(screen_width, 1280)
win_height = min(screen_height, 800)
self.Size = (win_width, win_height)
self.panel = MainPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel)
self.SetSizer(sizer)
self.Center()
self.Show()
class MainPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
if __name__ == '__main__':
wx_app = wx.App()
MainFrame()
wx_app.MainLoop()
There may be a solution with wx.ScrolledWindow but a scrolled panel seems to work.
import wx
import wx.lib.scrolledpanel as scrolled
class MyForm(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial", size=(800,600))
self.panel = wx.Panel(self, wx.ID_ANY)
self.panel.SetBackgroundColour('green')
self.scrolled_panel = scrolled.ScrolledPanel(self.panel, -1, style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER, name="panel1")
self.scrolled_panel.SetAutoLayout(1)
self.scrolled_panel.SetupScrolling()
self.scrolled_panel.SetBackgroundColour('CYAN')
self.sizer = wx.BoxSizer(wx.VERTICAL)
text = wx.StaticText(self.scrolled_panel, wx.ID_ANY, 'My text')
self.sizer.Add(text)
panel_in1 = wx.Panel(self.scrolled_panel, wx.ID_ANY, wx.DefaultPosition, wx.Size(-1,250), style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
panel_in1.SetBackgroundColour('red')
self.sizer.Add(panel_in1,0,wx.EXPAND)
panel_in2 = wx.Panel(self.scrolled_panel, wx.ID_ANY, wx.DefaultPosition, wx.Size(-1,150), style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
panel_in2.SetBackgroundColour('grey')
self.sizer.Add(panel_in2,0,wx.EXPAND)
self.scrolled_panel.SetSizer(self.sizer)
panelSizer = wx.BoxSizer(wx.VERTICAL)
panelSizer.AddSpacer(50)
panelSizer.Add(self.scrolled_panel, 1, wx.EXPAND)
self.panel.SetSizer(panelSizer)
self.statusBar = self.CreateStatusBar( 1, wx.STB_SIZEGRIP, wx.ID_ANY )
self.Centre( wx.BOTH )
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm().Show()
app.MainLoop()

Resetting a wxPython app / destroying everything and starting from initial frame

I've read other answers here, but they all seem to deal with just closing an app altogether, making sure all processes and frames and such are destroyed in the process. What I want to do is a little different.
My app consists of three frames (StartFrame, ParaFrame, ResultFrame) as well as a custom class for storing and manipulating data. The basics are: StartFrame is just some text and a "start" button. "Start" creates an instance of ParaFrame, hides the StartFrame, and shows the ParaFrame instance. Paraframe has a bunch of widgets for the user to select a file and how to analyze it. When all the fields are entered, an "Analyze" button pops up, which (when clicked) instantiates the custom DataHandler class, sets its parameters according to the user selections, calls a DataHandler method which analyzes the data, hides itself, and instantiates+shows the ResultsFrame. Not surprisingly, the ResultsFrame shows the results of the analysis.
I want to add a "Start Over" control which will destroy everything (all the frames, panels, the DataHandler instance, etc.) and display a fresh StartFrame instance, or otherwise destroy everything except the already-instantiated-but-hidden StartFrame, showing that frame again, but I'm at a loss.
A simplified example follows:
import wx
class StartFrame(wx.Frame):
"""App start frame"""
FRAME_MIN_SIZE = (900,600)
def __init__(self, parent):
wx.Frame.__init__(self, parent=parent,
id=wx.ID_ANY, title="LOD Calculator", size=wx.Size(900,600),
style=wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.RESIZE_BORDER|wx.TAB_TRAVERSAL)
self.startpnl = wx.Panel(self)
self.startvsizer=wx.BoxSizer(wx.VERTICAL)
self.startbtnsizer=wx.BoxSizer(wx.HORIZONTAL)
self.btn = wx.Button(self.startpnl, wx.ID_ANY, "Start Analysis",\
size = (200,60))
self.btn.Bind(wx.EVT_BUTTON, self._OnStart)
self.startbtnsizer.AddStretchSpacer()
self.startbtnsizer.Add(self.btn, 0, wx.CENTER)
self.startbtnsizer.AddStretchSpacer()
self.startvsizer.AddStretchSpacer()
self.startvsizer.Add(self.startbtnsizer, wx.SizerFlags().Expand().Border(wx.ALL, 25))
self.startvsizer.AddStretchSpacer()
self.startpnl.SetSizerAndFit(self.startvsizer)
def _OnStart(self,event):
self.frm2 = ParaFrame(None)
self.Hide()
self.frm2.Show()
class ParaFrame(wx.Frame):
"""Data load frame"""
FRAME_MIN_SIZE = (950,800)
def __init__(self, parent):
wx.Frame.__init__(self, parent=parent,
id=wx.ID_ANY, title="LOD Calculator", size=wx.Size(950,800),
style=wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.RESIZE_BORDER|wx.TAB_TRAVERSAL)
self.mainpnl = wx.Panel(self)
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.vsizer = wx.BoxSizer(wx.VERTICAL)
self.analyzebtn = wx.Button(self.mainpnl, wx.ID_ANY, u"Analyze",\
wx.DefaultPosition, wx.DefaultSize, 0)
self.vsizer.AddStretchSpacer()
self.vsizer.Add(self.analyzebtn, 0, wx.ALL, 10)
self.vsizer.AddStretchSpacer()
self.mainsizer.AddStretchSpacer()
self.mainsizer.Add(self.vsizer, wx.SizerFlags().Expand().Border(wx.ALL, 25))
self.mainsizer.AddStretchSpacer()
self.mainpnl.SetSizerAndFit(self.mainsizer)
self.analyzebtn.Bind(wx.EVT_BUTTON, self._analyze)
def _analyze(self, event):
dhandler = DataHandler(self)
dhandler.data = "a bunch"
dhandler.data2 = " of data"
dhandler.data3 = " goes here"
dhandler._analyzeData()
self.resfrm = ResultFrame(self, dhandler.data, dhandler.data2)
self.Hide()
self.resfrm.Show()
class DataHandler:
def __init__(self,parent):
self.data = ''
self.data2 = ''
self.data3 = ''
def _analyzeData(self):
anastr = self.data + self.data2 + " gets analyzed"
print(anastr)
class ResultFrame(wx.Frame):
def __init__(self, parent, targets, dftables):
super(ResultFrame, self).__init__(parent, title="results", size=(1535,935))
self.targets = targets
self.dftables = dftables
self.InitUI()
self.Layout()
def InitUI(self):
self.mainpnl = wx.Panel(self)
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.vsizer = wx.BoxSizer(wx.VERTICAL)
self.restartbtn = wx.Button(self.mainpnl, wx.ID_ANY, u"Start Over",\
wx.DefaultPosition, wx.DefaultSize, 0)
self.vsizer.AddStretchSpacer()
self.vsizer.Add(self.restartbtn, 0, wx.ALL, 10)
self.vsizer.AddStretchSpacer()
self.mainsizer.AddStretchSpacer()
self.mainsizer.Add(self.vsizer, wx.SizerFlags().Expand().Border(wx.ALL, 25))
self.mainsizer.AddStretchSpacer()
self.mainpnl.SetSizerAndFit(self.mainsizer)
self.restartbtn.Bind(wx.EVT_BUTTON, self.OnRestart)
### this is where I try to destroy the ParaFrame instance and everything spawned by it, unsuccessfully
def OnRestart(self, event):
frm.frm2.Destroy()
frm.Show()
def main():
import wx.lib.mixins.inspection
app = wx.App()
frm = StartFrame(None)
frm.Show()
wx.lib.inspection.InspectionTool().Show(refreshTree=True)
app.MainLoop()
if __name__ == "__main__":
main()
As you can see, in the ResultFrame I have a "Start Over" button bound to a method in which I try to destroy the ParaFrame instance (and thus the DataHandler and ResultFrame instances spawned from it) by using frm.frm2.Destroy(), but get an error:
Traceback (most recent call last):
File "C:\Python\Scripts\stackexchange code.py", line 102, in OnRestart
frm.frm2.Destroy()
NameError: name 'frm' is not defined
If I change the line to just frm2.Destroy(), I get the same error, but stating name 'frm2' is not defined.
What am I doing wrong here, and how can I accomplish my goal? I'm still newish to OOP and quite new to wxPython, so any help is appreciate it. All I want is for that button to destroy everything and display the/an initial StartFrame again. Thank you :)
As long as you create each class without a parent, you can use self.Destroy() after creating the next frame in the chain, without it destroying any children. (Pass any data required as a parameter other than parent)
So your code, looks something like this:
import wx
class StartFrame(wx.Frame):
"""App start frame"""
FRAME_MIN_SIZE = (900,600)
def __init__(self, parent):
wx.Frame.__init__(self, parent=parent,
id=wx.ID_ANY, title="Load Calculator", size=wx.Size(900,600))
self.startpnl = wx.Panel(self)
self.startvsizer=wx.BoxSizer(wx.VERTICAL)
self.startbtnsizer=wx.BoxSizer(wx.HORIZONTAL)
self.btn = wx.Button(self.startpnl, wx.ID_ANY, "Start Analysis",\
size = (200,60))
self.btn.Bind(wx.EVT_BUTTON, self._OnStart)
self.startbtnsizer.AddStretchSpacer()
self.startbtnsizer.Add(self.btn, 0, wx.CENTER)
self.startbtnsizer.AddStretchSpacer()
self.startvsizer.AddStretchSpacer()
self.startvsizer.Add(self.startbtnsizer, wx.SizerFlags().Expand().Border(wx.ALL, 25))
self.startvsizer.AddStretchSpacer()
self.startpnl.SetSizerAndFit(self.startvsizer)
def _OnStart(self,event):
frm2 = ParaFrame(None)
frm2.Show()
self.Destroy()
class ParaFrame(wx.Frame):
"""Data load frame"""
FRAME_MIN_SIZE = (950,800)
def __init__(self, parent):
wx.Frame.__init__(self, parent=parent,
id=wx.ID_ANY, title="Load Calculator", size=wx.Size(900,600))
self.mainpnl = wx.Panel(self)
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.vsizer = wx.BoxSizer(wx.VERTICAL)
self.analyzebtn = wx.Button(self.mainpnl, wx.ID_ANY, u"Analyze",\
wx.DefaultPosition, wx.DefaultSize, 0)
self.vsizer.AddStretchSpacer()
self.vsizer.Add(self.analyzebtn, 0, wx.ALL, 10)
self.vsizer.AddStretchSpacer()
self.mainsizer.AddStretchSpacer()
self.mainsizer.Add(self.vsizer, wx.SizerFlags().Expand().Border(wx.ALL, 25))
self.mainsizer.AddStretchSpacer()
self.mainpnl.SetSizerAndFit(self.mainsizer)
self.analyzebtn.Bind(wx.EVT_BUTTON, self._analyze)
def _analyze(self, event):
dhandler = DataHandler(self)
dhandler.data = "a bunch"
dhandler.data2 = " of data"
dhandler.data3 = " goes here"
dhandler._analyzeData()
resfrm = ResultFrame(None, dhandler.data, dhandler.data2)
resfrm.Show()
self.Destroy()
class DataHandler:
def __init__(self,parent):
self.data = ''
self.data2 = ''
self.data3 = ''
def _analyzeData(self):
anastr = self.data + self.data2 + " gets analyzed"
print(anastr)
class ResultFrame(wx.Frame):
def __init__(self, parent, targets, dftables):
super(ResultFrame, self).__init__(parent, title="Results", size=(900,600))
self.targets = targets
self.dftables = dftables
self.InitUI()
self.Layout()
def InitUI(self):
self.mainpnl = wx.Panel(self)
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.vsizer = wx.BoxSizer(wx.VERTICAL)
self.restartbtn = wx.Button(self.mainpnl, wx.ID_ANY, u"Start Over",\
wx.DefaultPosition, wx.DefaultSize, 0)
self.vsizer.AddStretchSpacer()
self.vsizer.Add(self.restartbtn, 0, wx.ALL, 10)
self.vsizer.AddStretchSpacer()
self.mainsizer.AddStretchSpacer()
self.mainsizer.Add(self.vsizer, wx.SizerFlags().Expand().Border(wx.ALL, 25))
self.mainsizer.AddStretchSpacer()
self.mainpnl.SetSizerAndFit(self.mainsizer)
self.restartbtn.Bind(wx.EVT_BUTTON, self.OnRestart)
### this is where I try to destroy the ParaFrame instance and everything spawned by it, unsuccessfully
def OnRestart(self, event):
frm = StartFrame(None)
frm.Show()
self.Destroy()
def main():
app = wx.App()
frm = StartFrame(None)
frm.Show()
app.MainLoop()
if __name__ == "__main__":
main()

How to Switch Between Panels whitch Buttons

I can not navigate between the panels of my App through the buttons. I followed a lot of tutorials like this one but none solve my problem.
Thank for Help.
####################-----Principal Panel (first Panel)
import wx
from OtherPanel import OtherPanel
class MyPanel(wx.Panel):
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent = parent, size=(600, 500))
self.SetBackgroundColour(wx.Colour(250, 250, 250))
parent.Center()
self.histoPanel = OtherPanel(self)
self.home()
self.panel = wx.Panel(self)
def home(self):
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour(wx.Colour(250, 250, 250))
bS =wx.Button(self, -1,"Go some where ",(200,30), size=(150,150))
self.Bind(wx.EVT_BUTTON, self.Sy, bS)
bOthe = wx.Button(self, -1,"Go to OtherPanel",(400,30),(150,150))
self.Bind(wx.EVT_BUTTON, self.onOpenFrame,bOthe)
def onOpenFrame(self, event):
"""
Opens secondary frame
"""
self.Hide()
self.histoPanel.Show()
def Sy(self, event):
"""
I have another panel (panel 3)
"""
self.Hide()
#self.panel3.Show()
--Second Panel (another Panel)
this panel is displayed when you click on the button of the first panel
import wx
class OtherPanel(wx.Panel):
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent = parent)
self.panel = wx.Panel(self)
self.SetBackgroundColour(wx.Colour(250, 250, 250))
self.Center()
self.homeHist()
self.Show()
def homeHist(self):
bBack = wx.Button(self, -1, "", pos=(20,30), size=(50,50))
self.Bind(wx.EVT_BUTTON, self.onClose, bBack)
def onClose(self, event):
self.Close()
------My Frame---.
here is my Frame/Windows. he must wear all the panels in turn
import wx
from MyPanel import MyPanel
from OtherPanel import OtherPanel
class MyFrame(wx.Frame):
""""""
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, size = (600,500))
self.myPanel = MyPanel(self)
self.otherpanel = OtherPanel(self)
self.otherpanel.Hide()
self.menu()
self.CreateStatusBar(style= wx.BORDER_NONE)
self.SetBackgroundColour("gray")
self.SetStatusText("\tthank")
def menu(self):
menubar = wx.MenuBar()
fileMenu = wx.Menu()
menubar.SetBackgroundColour(wx.Colour(1, 1, 6))
fileMenu.AppendSeparator()
live = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+Q', '\tlive my app')
fileMenu.Append(live)
self.Bind(wx.EVT_MENU, self.Onexit, live)
menubar.Append(fileMenu, '\t&Menu')
self.SetMenuBar(menubar)
def Onexit(self, event):
self.Close(True)
def Bouton(self, event):
if self.myPanel.IsShown():
self.SetTitle("Panel Two Showing")
self.myPanel.Hide()
self.otherpanel.Show()
else:
self.SetTitle("Panel One Showing")
self.myPanel.Show()
self.otherpanel.Hide()
self.Layout()
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
frame.Show()
app.MainLoop()
In your MyPanel.__init__ you are creating an instance of OtherPanel assigned to self.histoPanel as a child of the MyPanel, and then MyPanel's event handlers are hiding itself, which in turn hides its children including the self.histoPanel. You're also creating some panels assigned to self.panel which don't seem to be used for anything.
The way you are doing it in the MyFrame class is much better. It creates both panels and hides one. Then in MyFrame.Bouton it hides one and shows the other, depending on the current state. So what you need to do is get rid of all the extra panels in MyPanel (self.histoPanel and also the various self.panels that are never used for anything) and then you just need to have the button event ask the parent frame to swap the panels instead of trying to do it itself.
Here is an example of what Robin is suggesting in his answer:
import wx
class MyPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
self.panel = wx.Panel(self)
self.btn = wx.Button(self.panel, label="Panel 1", size=(250,75))
self.btn.Bind(wx.EVT_BUTTON, self.switch)
vbox1 = wx.BoxSizer(wx.VERTICAL)
vbox1.Add(self.btn)
self.panel.SetSizer(vbox1)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(self.panel)
self.SetSizer(vbox)
self.Show()
def switch(self, event):
self.parent.Swap()
class MyOtherPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
self.panel = wx.Panel(self)
self.btn = wx.Button(self.panel, label="Panel 2", size=(175,250))
self.btn.Bind(wx.EVT_BUTTON, self.switch)
vbox1 = wx.BoxSizer(wx.VERTICAL)
vbox1.Add(self.btn)
self.panel.SetSizer(vbox1)
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(self.panel)
self.SetSizer(vbox)
self.Show()
self.panel.Hide()
def switch(self, event):
self.parent.Swap()
class PanelSwitcher(wx.Frame):
def __init__(self):
super().__init__(None)
vbox = wx.BoxSizer(wx.VERTICAL)
self.panel1 = MyPanel(self)
self.panel2 = MyOtherPanel(self)
vbox.Add(self.panel1)
vbox.Add(self.panel2)
self.SetSizer(vbox)
self.Show()
def Swap(self):
if self.panel1.panel.IsShown():
self.panel1.panel.Hide()
self.panel2.panel.Show()
else:
self.panel2.panel.Hide()
self.panel1.panel.Show()
self.Layout()
if __name__ == "__main__":
app = wx.App()
PanelSwitcher()
app.MainLoop()

wxglade list tree not showing properly

I am new to wxglade and trying to create a form to show tabs and split window. There are going to be tree lists on the left pane. The issue is that when I open the form, it shows the treelist but the list cannot be collapsed or expanded. When I go to 2nd tab and come back to the first, tree list is shown in small box.
import wx
# Define the tab content as classes:
class TabOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.SetSize((400, 300))
self.window_1 = wx.SplitterWindow(self, wx.ID_ANY)
self.window_1_pane_1 = wx.ScrolledWindow(self.window_1, wx.ID_ANY, style=wx.BORDER_RAISED | wx.TAB_TRAVERSAL)
#self.button_1 = wx.Button(self.window_1_pane_1, wx.ID_ANY, "button_1")
#t = wx.StaticText(self, -1, "This is the first tab", (100,100)) start list
il = wx.ImageList(16,16)
self.fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)))
self.fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16,16)))
self.fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16,16)))
self.tree = wx.TreeCtrl(self, style=wx.TR_DEFAULT_STYLE | wx.TR_EDIT_LABELS)
self.tree.AssignImageList(il)
root = self.tree.AddRoot("Server")
self.tree.SetItemData(root, None)
self.tree.SetItemImage(root, self.fldridx,wx.TreeItemIcon_Normal)
self.tree.SetItemImage(root, self.fldropenidx,wx.TreeItemIcon_Expanded)
tree = ["A","B","C","D","E","F","G","H"]
self.AddTreeNodes(root, tree)
self.tree.Expand(root)
def AddTreeNodes(self, parentItem, items):
for item in items:
if type(item) == str:
newItem = self.tree.AppendItem(parentItem, item)
self.tree.SetItemData(newItem, None)
#self.tree.SetItemImage(newItem, self.fileidx,wx.TreeItemIcon_Normal)
else:
newItem = self.tree.AppendItem(parentItem, item[0])
self.tree.SetItemPyData(newItem, None)
#self.tree.SetItemImage(newItem, self.fldridx,wx.TreeItemIcon_Normal)
self.tree.SetItemImage(newItem, self.fldropenidx,wx.TreeItemIcon_Expanded)
self.AddTreeNodes(newItem, item[1])
#end list
self.window_1_pane_2 = wx.Panel(self.window_1, wx.ID_ANY)
self.window_1_pane_1.SetMinSize((50, 256))
self.window_1_pane_1.SetBackgroundColour(wx.Colour(216, 216, 191))
self.window_1_pane_1.SetScrollRate(10, 10)
self.window_1.SetMinimumPaneSize(20)
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
#sizer_2.Add(self.button_1, 0, 0, 0)
sizer1 = wx.BoxSizer(wx.VERTICAL)
sizer1.Add(self.tree, 20, wx.EXPAND)
self.SetSizer(sizer1)
self.window_1_pane_1.SetSizer(sizer_2)
self.window_1.SplitVertically(self.window_1_pane_1, self.window_1_pane_2)
sizer_1.Add(self.window_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
class TabTwo(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
t = wx.StaticText(self, -1, "This is the second tab", (20,20))
class TabThree(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
t = wx.StaticText(self, -1, "This is the third tab", (20,20))
class TabFour(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
t = wx.StaticText(self, -1, "This is the last tab", (20,20))
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="wxPython tabs example #pythonspot.com")
# Create a panel and notebook (tabs holder)
p = wx.Panel(self)
nb = wx.Notebook(p)
# Create the tab windows
tab1 = TabOne(nb)
tab2 = TabTwo(nb)
tab3 = TabThree(nb)
tab4 = TabFour(nb)
# Add the windows to tabs and name them.
nb.AddPage(tab1, "Tab 1")
nb.AddPage(tab2, "Tab 2")
nb.AddPage(tab3, "Tab 3")
nb.AddPage(tab4, "Tab 4")
# Set noteboook in a sizer to create the layout
sizer = wx.BoxSizer()
sizer.Add(nb, 1, wx.EXPAND)
p.SetSizer(sizer)
if __name__ == "__main__":
app = wx.App(redirect=True)
MainFrame().Show()
app.MainLoop()
wx.TreeCtrl has built-in horizontal and vertical scroll bars. Therefore, I guess there is no need to use the wx.ScrolledWindow here. I simplify the code for class TabOne to the following:
class TabOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.SetSize((400, 300))
self.window_1 = wx.SplitterWindow(self, wx.ID_ANY)
il = wx.ImageList(16,16)
self.fldridx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)))
self.fldropenidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16,16)))
self.fileidx = il.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16,16)))
self.tree = wx.TreeCtrl(self.window_1, style=wx.TR_DEFAULT_STYLE | wx.TR_EDIT_LABELS)
self.tree.AssignImageList(il)
root = self.tree.AddRoot("Server")
self.tree.SetItemData(root, None)
self.tree.SetItemImage(root, self.fldridx,wx.TreeItemIcon_Normal)
self.tree.SetItemImage(root, self.fldropenidx,wx.TreeItemIcon_Expanded)
tree = ["A","B","C","D","E","F","G","H"]
self.AddTreeNodes(root, tree)
self.tree.Expand(root)
self.window_1_pane_2 = wx.Panel(self.window_1, wx.ID_ANY)
self.window_1.SetMinimumPaneSize(20)
self.window_1.SplitVertically(self.tree, self.window_1_pane_2)
sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
sizer_1.Add(self.window_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
def AddTreeNodes(self, parentItem, items):
for item in items:
if type(item) == str:
newItem = self.tree.AppendItem(parentItem, item)
self.tree.SetItemData(newItem, None)
#self.tree.SetItemImage(newItem, self.fileidx,wx.TreeItemIcon_Normal)
else:
newItem = self.tree.AppendItem(parentItem, item[0])
self.tree.SetItemPyData(newItem, None)
#self.tree.SetItemImage(newItem, self.fldridx,wx.TreeItemIcon_Normal)
self.tree.SetItemImage(newItem, self.fldropenidx,wx.TreeItemIcon_Expanded)
self.AddTreeNodes(newItem, item[1])
and now is working as expected.

How to refresh the main frame when the child dialog do someting

I want the main frame refresh to update the label When I click the "done" button on MyDialog, But now it doesn't work.
Does there anything wrong? Thanks.
This is the code:
MyDialog: the child dialog where there is a button on it to update the label of the main frame
MainFrame: the main Frame, there is a button on it to start my dialog
# -*- coding: utf-8 -*-
import wx
#Dialog
class MyDialog(wx.Dialog):
"""setting MyDialog."""
def __init__(self):
self.dlg_main = wx.Dialog.__init__(self, None, -1, title="setting", size=(300, 300))
self.btn_ok = wx.Button(self, label="done", pos=(30, 30), size=(50, 26))
self.Bind(wx.EVT_BUTTON, self.__OnButtonClick_save, self.btn_ok,)
def __OnButtonClick_save(self, event):
self.Destroy()
main = MainFrame()
**main.set_label_name('test')**
main.Destroy()
def start_dialog():
my_dialog = MyDialog()
my_dialog.ShowModal()
my_dialog.Destroy()
#Main Frame
class MainFrame(wx.Frame):
def __init__(self):
self.main_frame = wx.Frame.__init__(self, None, -1, title='simple', size=(400, 400))
self.Centre()
self.label_name = wx.StaticText(self, label="Hello,everyone", pos=(30, 30))
self.btn_set = wx.Button(self, label="set", pos=(30, 60))
self.Bind(wx.EVT_BUTTON, self.on_button_click, self.btn_set)
def set_label_name(self, str):
print(str)
self.label_name.SetLabel('hello, Boys')
def on_button_click(self, event):
start_dialog()
def show_main():
main = wx.App()
main_win = MainFrame()
main_win.Show()
main.MainLoop()
if __name__ == '__main__':
show_main()
I have got the method, thanks all!
The point is how to call the parent method, so , use self.parent.xxx to fix the problem.
The code like this:
# -*- coding: utf-8 -*-
import wx
#Dialog
class MyDialog(wx.Dialog):
"""setting MyDialog."""
def __init__(self, parent, title):
super(MyDialog, self).__init__(parent, title=title, size=(300, 300))
self.parent = parent
panel = wx.Panel(self)
btn_ok = wx.Button(panel, label="done", pos=(30, 30), size=(50, 26))
btn_ok.Bind(wx.EVT_BUTTON, self.__OnButtonClick_save)
def __OnButtonClick_save(self, event):
#THis is the different
self.parent.set_label_name('test')
self.Destroy()
def start_dialog():
my_dialog = MyDialog()
my_dialog.ShowModal()
my_dialog.Destroy()
#Main Frame
class MainFrame(wx.Frame):
def __init__(self):
self.main_frame = wx.Frame.__init__(self, None, -1, title='simple', size=(400, 400))
self.init_ui()
def init_ui(self):
self.label_name = wx.StaticText(self, label="Hello,everyone", pos=(30, 30))
btn_set = wx.Button(self, label="set", pos=(30, 60))
btn_set.Bind(wx.EVT_BUTTON, self.on_button_click)
self.Centre()
def set_label_name(self, str):
self.label_name.SetLabel('hello, Boys')
def on_button_click(self, event):
my_dialog = MyDialog(self, "setting")
my_dialog.ShowModal()
my_dialog.Destroy()
def show_main():
main = wx.App()
main_win = MainFrame()
main_win.Show()
main.MainLoop()
if __name__ == '__main__':
show_main()
Thanks for the idea in this answer Wxpython show dialog on main frame startup

Resources