I have this class which deals with listBox:
I tried to make a delete button for listBox items but it didn't work. The "deleteItem" function does now work.Without the marked parts it works good, but there is no delete option. Help someone?
class SettingProcess(wx.Frame):
itemsArr= []
# ----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Black list Proceses",size=(500, 600))
self.Centre()
# Add a panel so it looks the correct on all platforms
panel = wx.Panel(self, wx.ID_ANY,size=(500, 600))
self.index = 0
sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
lbl_process = wx.StaticText(panel, -1, "Process name")
lbl_process.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
self.txt_processname = wx.TextCtrl(panel, size=(140, -1))
self.txt_processname.SetValue("chrome.exe")
sizer.AddMany([lbl_process, self.txt_processname])
#------------- Files ListBox -------------------------------------
global ProcessListMain
self.files_listBox = wx.ListBox(panel, -1, (12, 130), (200, 240), ProcessListMain,
wx.LB_SINGLE | wx.LB_HSCROLL | wx.LB_ALWAYS_SB | wx.LB_SORT)
self.files_listBox.SetBackgroundColour(wx.Colour(255, 255, 128))
#------------- Set event handlers ---------------------------------
m_start = wx.Button(panel, wx.ID_CLOSE, "Add")
m_start.Bind(wx.EVT_BUTTON, self.OnAddButton)
sizer.Add(m_start, 0, wx.ALL, 10)
m_close = wx.Button(panel, wx.ID_CLOSE, "Close")
m_close.Bind(wx.EVT_BUTTON, self.onExit)
sizer.Add(m_close, 0, wx.ALL, 10)
**m_delete = wx.Button(panel, wx.ID_CLOSE, "Delete")
m_delete.Bind(wx.EVT_BUTTON, self.deleteItem)
sizer.Add(m_delete, 0, wx.ALL, 10)**
panel.SetSizer(sizer)
# ----------------------------------------------------------------------
def OnAddButton(self,str):
global ProcessListMain
#print "value is "+ str(self.txt_processname.GetValue())
ProcessListMain.append(self.txt_processname.GetValue())
self.files_listBox.Set(ProcessListMain)
def onExit(self, event):
self.Destroy()
***def deleteItem(self,event):
numOfItems=self.files_listBox.GetCount()
for i in range(numOfItems):
self.itemsArr[i]=self.files_listBox.GetString()
selectedItems=self.files_listBox.GetStringSelection()
self.files_listBox.clear()
for i in numOfItems :
if self.itemsArr[i]!=selectedItems:
self.files_listBox.append( self.itemsArr[i])***
Here is the version, courtesy of Robin Dunn's comment:
Note that I have also bound the textctrl so that just filling in a process name and pressing Enter, also acts like the Add button.
import wx
class SettingProcess(wx.Frame):
# ----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Black list Processes",size=(500, 600))
self.Centre()
# Add a panel so it looks the correct on all platforms
panel = wx.Panel(self, wx.ID_ANY,size=(500, 600))
self.index = 0
sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
lbl_process = wx.StaticText(panel, -1, "Process name")
lbl_process.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
self.txt_processname = wx.TextCtrl(panel, size=(140, -1), style=wx.TE_PROCESS_ENTER)
self.txt_processname.SetValue("chrome.exe")
self.txt_processname.Bind(wx.EVT_TEXT_ENTER, self.OnAddButton)
sizer.AddMany([lbl_process, self.txt_processname])
#------------- Files ListBox -------------------------------------
ProcessListMain = ['Process A','Process B','Process C','Process D','Process E']
self.files_listBox = wx.ListBox(panel, -1, (12, 130), (200, 240), ProcessListMain,
wx.LB_SINGLE | wx.LB_HSCROLL | wx.LB_ALWAYS_SB | wx.LB_SORT)
self.files_listBox.SetBackgroundColour(wx.Colour(255, 255, 128))
#------------- Set event handlers ---------------------------------
m_start = wx.Button(panel, -1, "Add")
m_start.Bind(wx.EVT_BUTTON, self.OnAddButton)
sizer.Add(m_start, 0, wx.ALL, 10)
m_close = wx.Button(panel, -1, "Close")
m_close.Bind(wx.EVT_BUTTON, self.onExit)
sizer.Add(m_close, 0, wx.ALL, 10)
m_delete = wx.Button(panel, -1, "Delete")
m_delete.Bind(wx.EVT_BUTTON, self.deleteItem)
sizer.Add(m_delete, 0, wx.ALL, 10)
panel.SetSizer(sizer)
# ----------------------------------------------------------------------
def OnAddButton(self,event):
Addproc = self.txt_processname.GetValue()
if Addproc:
self.files_listBox.Append(Addproc)
def onExit(self, event):
self.Destroy()
def deleteItem(self,event):
deleted_item = self.files_listBox.GetSelection()
self.files_listBox.Delete(deleted_item)
if __name__=='__main__':
app = wx.App()
frame = SettingProcess()
frame.Show()
app.MainLoop()
It's a bit more complicated than having duplicate Id's for your buttons, as I suggested earlier.
Try the following: (I have stuck with your global ProcessListMain but had to mock it up, as it isn't declared in your questions code)
import wx
class SettingProcess(wx.Frame):
itemsArr= []
# ----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Black list Processes",size=(500, 600))
self.Centre()
# Add a panel so it looks the correct on all platforms
panel = wx.Panel(self, wx.ID_ANY,size=(500, 600))
self.index = 0
sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
lbl_process = wx.StaticText(panel, -1, "Process name")
lbl_process.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
self.txt_processname = wx.TextCtrl(panel, size=(140, -1))
self.txt_processname.SetValue("chrome.exe")
sizer.AddMany([lbl_process, self.txt_processname])
#------------- Files ListBox -------------------------------------
global ProcessListMain
ProcessListMain = ['123','456','789','1123','2123']
self.files_listBox = wx.ListBox(panel, -1, (12, 130), (200, 240), ProcessListMain,
wx.LB_SINGLE | wx.LB_HSCROLL | wx.LB_ALWAYS_SB | wx.LB_SORT)
self.files_listBox.SetBackgroundColour(wx.Colour(255, 255, 128))
#------------- Set event handlers ---------------------------------
m_start = wx.Button(panel, -1, "Add")
m_start.Bind(wx.EVT_BUTTON, self.OnAddButton)
sizer.Add(m_start, 0, wx.ALL, 10)
m_close = wx.Button(panel, -1, "Close")
m_close.Bind(wx.EVT_BUTTON, self.onExit)
sizer.Add(m_close, 0, wx.ALL, 10)
m_delete = wx.Button(panel, -1, "Delete")
m_delete.Bind(wx.EVT_BUTTON, self.deleteItem)
sizer.Add(m_delete, 0, wx.ALL, 10)
panel.SetSizer(sizer)
# ----------------------------------------------------------------------
def OnAddButton(self,event):
global ProcessListMain
Addproc = self.txt_processname.GetValue()
ProcessListMain.append(Addproc)
self.files_listBox.Set(ProcessListMain)
def onExit(self, event):
self.Destroy()
def deleteItem(self,event):
global ProcessListMain
deleted_item = self.files_listBox.GetStringSelection()
numOfItems=self.files_listBox.GetCount()
itemsArr = []
for i in range(numOfItems):
x = self.files_listBox.GetString(i)
if x != deleted_item:
itemsArr.append(x)
ProcessListMain = itemsArr
self.files_listBox.Clear()
self.files_listBox.Set(ProcessListMain)
self.files_listBox.Update()
if __name__=='__main__':
app = wx.App()
frame = SettingProcess()
frame.Show()
app.MainLoop()
Related
I have two BoxSizers, the first one
sizer = wx.BoxSizer (wx.VERTICAL)
sizer.Add (self.grid2, 1, wx.EXPAND)
panel2.SetSizer (sizer)
and another vertical BoxSizers, to the left of the button grid, both BoxSizers interfere.
vbox1 = wx.FlexGridSizer (rows = 1, cols = 3, hgap = 5, vgap = 5)
buttonsBox1 = wx.BoxSizer (wx.VERTICAL)
buttonsBox1.Add (self.buttonoborved)
vbox1.Add (buttonsBox1)
vbox1.Add (self.grid2)
vbox1.Add (midPan1, wx.ID_ANY, wx.EXPAND | wx.ALL, 20)
panel2.SetSizer (vbox1)
An error occurs - Adding a window already in a sizer, detach it first!
How can they be called at the same time.
Edit:
That are two BoxSizer, one in other, but how can be put buttons in there.
import wx
import wx.grid
from wx.lib.scrolledpanel import ScrolledPanel
class TestPanel(ScrolledPanel):
def __init__(self, parent):
ScrolledPanel.__init__(self, parent, wx.ID_ANY, size=(640, 480))
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self._create_table(), 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(self.sizer)
self.SetupScrolling()
self.SetAutoLayout(1)
def _create_table(self):
_table = wx.grid.Grid(self, -1)
_table.CreateGrid(0, 2)
for i in range(1723): # Work normally If I use 1722 rows
_table.AppendRows()
_table.SetCellValue(i, 0, str(i))
return _table
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
title="Scroll table", size=(640, 480))
self.fSizer = wx.BoxSizer(wx.VERTICAL)
self.fSizer.Add(TestPanel(self), 1, wx.EXPAND)
self.SetSizer(self.fSizer)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()
It depends where you want to place the buttons but let's assume they should be at the bottom.
import wx
import wx.grid
from wx.lib.scrolledpanel import ScrolledPanel
class TestPanel(ScrolledPanel):
def __init__(self, parent):
ScrolledPanel.__init__(self, parent, wx.ID_ANY, size=(640, 480))
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self._create_table(), 1, wx.EXPAND | wx.ALL, 5)
self.b1 = wx.Button(self, -1, "Button 1")
self.b2 = wx.Button(self, -1, "Button 2")
self.b3 = wx.Button(self, -1, "Button 3")
button_sizer = wx.BoxSizer(wx.HORIZONTAL)
button_sizer.Add(self.b1)
button_sizer.Add(self.b2)
button_sizer.Add(self.b3)
self.sizer.Add(button_sizer)
self.SetSizer(self.sizer)
self.SetupScrolling()
self.SetAutoLayout(1)
def _create_table(self):
_table = wx.grid.Grid(self, -1)
_table.CreateGrid(0, 2)
for i in range(1723): # Work normally If I use 1722 rows
_table.AppendRows()
_table.SetCellValue(i, 0, str(i))
return _table
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
title="Scroll table", size=(640, 480))
self.fSizer = wx.BoxSizer(wx.VERTICAL)
self.fSizer.Add(TestPanel(self), 1, wx.EXPAND)
self.SetSizer(self.fSizer)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()
I've recently started using wxPython to build a GUI and I'm trying to create the following layout:
Button1 Button2 Button3
----------------------------------------
listbox | textctrl
The buttons should have a flexible width, expanding to fill the full width of the frame with a border between them (each buttons has a width (incl. border) of 1/3 frame). Their height should be set to a height in pixels.
The listbox should fill the frame vertically and have a set width of x pixels
The textctrol should be a textbox which expands to fill the width of the frame vertically as well as horizontally.
This is the code I have:
mainPanel = wx.Panel(self, -1)
parentBox = wx.BoxSizer(wx.VERTICAL)
menubar = wx.MenuBar()
filem = wx.Menu()
menubar.Append(filem, '&File')
self.SetMenuBar(menubar)
navPanel = wx.Panel(mainPanel, -1, size=(1000, 80))
navBox = wx.BoxSizer(wx.HORIZONTAL)
newSection = wx.Button(navPanel, self.ID_NEW, 'New')
renSection = wx.Button(navPanel, self.ID_RENAME, 'Rename')
dltSection = wx.Button(navPanel, self.ID_DELETE, 'Delete')
navBox.Add(newSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(renSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(dltSection, 1, wx.EXPAND | wx.ALL, 5)
navPanel.SetSizer(navBox)
contentPanel = wx.Panel(mainPanel, -1, size=(1000, 600))
contentBox = wx.BoxSizer(wx.HORIZONTAL)
self.listbox = wx.ListBox(contentPanel, -1, size=(300, 700))
self.settings = wx.TextCtrl(contentPanel, -1)
contentBox.Add(self.listbox, 0)
contentBox.Add(self.settings, 1, wx.EXPAND | wx.ALL, 5)
contentPanel.SetSizer(contentBox)
parentBox.Add(navPanel, 0, wx.EXPAND | wx.ALL, 5)
parentBox.Add(contentPanel, 1, wx.EXPAND | wx.ALL, 5)
mainPanel.SetSizer(parentBox)
Something is going wrong since what I see is not what I expect to see, anybody who can help me out?
It is working for me, I'm on win64, python 32bit 2.7.3.3, wx '2.8.12.1 (msw-unicode)'. The full working test example is:
import wx
class testframe(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'some title')
mainPanel = wx.Panel(self, -1)
parentBox = wx.BoxSizer(wx.VERTICAL)
menubar = wx.MenuBar()
filem = wx.Menu()
menubar.Append(filem, '&File')
self.SetMenuBar(menubar)
navPanel = wx.Panel(mainPanel, -1, size=(1000, 80))
navBox = wx.BoxSizer(wx.HORIZONTAL)
newSection = wx.Button(navPanel, -1, 'New')
renSection = wx.Button(navPanel, -1, 'Rename')
dltSection = wx.Button(navPanel, -1, 'Delete')
navBox.Add(newSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(renSection, 1, wx.EXPAND | wx.ALL, 5)
navBox.Add(dltSection, 1, wx.EXPAND | wx.ALL, 5)
navPanel.SetSizer(navBox)
contentPanel = wx.Panel(mainPanel, -1, size=(1000, 600))
contentBox = wx.BoxSizer(wx.HORIZONTAL)
self.listbox = wx.ListBox(contentPanel, -1, size=(300, 700))
self.settings = wx.TextCtrl(contentPanel, -1)
contentBox.Add(self.listbox, 0, wx.ALL, 5)
contentBox.Add(self.settings, 1, wx.EXPAND | wx.ALL, 5)
contentPanel.SetSizer(contentBox)
parentBox.Add(navPanel, 0, wx.EXPAND | wx.ALL, 5)
parentBox.Add(contentPanel, 1, wx.EXPAND | wx.ALL, 5)
mainPanel.SetSizer(parentBox)
parentBox.Fit(self)
app = wx.PySimpleApp()
app.frame = testframe()
app.frame.Show()
app.MainLoop()
Notice the addition of Fit() of the main sizer, and also 5px border added to the listbox.
When I try to use a sizer with the checklist box everything overlaps terribly. My goal is to have the checklistbox on the left and the input fields on the right of the window. I do not know whether the sizer is the solution but I thought it should offer a way to keep the checklistbox on the left and the input fields on the right. Ideally I would also have the ok button and cancel button centered underneath everything else.
import wx
import wx.lib.scrolledpanel
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, title='My Form')
# Add a panel so it looks correct on all platforms
self.panel = wx.Panel(self, wx.ID_ANY)
# panel2 = wx.lib.scrolledpanel.ScrolledPanel(self,-1, size=(200,400), pos=(0,28), style=wx.SIMPLE_BORDER)
# panel2.SetupScrolling()
# bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_OTHER, (16, 16))
# titleIco = wx.StaticBitmap(self.panel, wx.ID_ANY, bmp)
title = wx.StaticText(self.panel, wx.ID_ANY, 'My Title')
# bmp = wx.ArtProvider.GetBitmap(wx.ART_TIP, wx.ART_OTHER, (16, 16))
# inputOneIco = wx.StaticBitmap(self.panel, wx.ID_ANY, bmp)
labelOne = wx.StaticText(self.panel, wx.ID_ANY, 'Input 1')
inputTxtOne = wx.TextCtrl(self.panel, wx.ID_ANY, '')
# inputTwoIco = wx.StaticBitmap(self.panel, wx.ID_ANY, bmp)
labelTwo = wx.StaticText(self.panel, wx.ID_ANY, 'Input 2')
inputTxtTwo = wx.TextCtrl(self.panel, wx.ID_ANY,'')
# inputThreeIco = wx.StaticBitmap(self.panel, wx.ID_ANY, bmp)
# labelThree = wx.StaticText(self.panel, wx.ID_ANY, 'Input 3')
# inputTxtThree = wx.TextCtrl(self.panel, wx.ID_ANY, '')
# inputFourIco = wx.StaticBitmap(self.panel, wx.ID_ANY, bmp)
# labelFour = wx.StaticText(self.panel, wx.ID_ANY, 'Input 4')
# inputTxtFour = wx.TextCtrl(self.panel, wx.ID_ANY, '')
okBtn = wx.Button(self.panel, wx.ID_ANY, 'OK')
cancelBtn = wx.Button(self.panel, wx.ID_ANY, 'Cancel')
self.Bind(wx.EVT_BUTTON, self.onOK, okBtn)
self.Bind(wx.EVT_BUTTON, self.onCancel, cancelBtn)
finalSizer = wx.BoxSizer(wx.HORIZONTAL)
topSizer = wx.BoxSizer(wx.VERTICAL)
titleSizer = wx.BoxSizer(wx.HORIZONTAL)
inputOneSizer = wx.BoxSizer(wx.HORIZONTAL)
inputTwoSizer = wx.BoxSizer(wx.HORIZONTAL)
checkSizer = wx.BoxSizer(wx.HORIZONTAL)
# inputThreeSizer = wx.BoxSizer(wx.HORIZONTAL)
# inputFourSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
# titleSizer.Add(titleIco, 0, wx.ALL, 5)
titleSizer.Add(title, 0, wx.ALL, 5)
# inputOneSizer.Add(inputOneIco, 0, wx.ALL, 5)
inputOneSizer.Add(labelOne, 0, wx.ALL, 5)
inputOneSizer.Add(inputTxtOne, 1, wx.ALL|wx.EXPAND, 5)
# inputTwoSizer.Add(inputTwoIco, 0, wx.ALL, 5)
inputTwoSizer.Add(labelTwo, 0, wx.ALL, 5)
inputTwoSizer.Add(inputTxtTwo, 1, wx.ALL|wx.EXPAND, 5)
# inputThreeSizer.Add(inputThreeIco, 0, wx.ALL, 5)
# inputThreeSizer.Add(labelThree, 0, wx.ALL, 5)
# inputThreeSizer.Add(inputTxtThree, 1, wx.ALL|wx.EXPAND, 5)
# inputFourSizer.Add(inputFourIco, 0, wx.ALL, 5)
# inputFourSizer.Add(labelFour, 0, wx.ALL, 5)
# inputFourSizer.Add(inputTxtFour, 1, wx.ALL|wx.EXPAND, 5)
sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
'twelve', 'thirteen', 'fourteen']
lb = wx.CheckListBox(self, -1, (10, 10), (200,400), sampleList)
self.Bind(wx.EVT_LISTBOX, self.EvtListBox, lb)
self.Bind(wx.EVT_CHECKLISTBOX, self.EvtCheckListBox, lb)
lb.SetSelection(0)
self.lb = lb
checkSizer.Add(lb, 0, wx.ALL |wx.EXPAND | wx.LEFT, 5)
checkSizer.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 5)
btnSizer.Add(okBtn, 0, wx.ALL, 5)
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
topSizer.Add(titleSizer, 0, wx.CENTER)
# topSizer.Add(wx.StaticLine(self.panel,), 0, wx.ALL|wx.EXPAND, 5)
topSizer.Add(inputOneSizer, 0, wx.ALL|wx.EXPAND | wx.RIGHT, 5)
topSizer.Add(inputTwoSizer, 0, wx.ALL|wx.EXPAND | wx.RIGHT, 5)
# topSizer.Add(inputThreeSizer, 0, wx.ALL|wx.EXPAND, 5)
# topSizer.Add(inputFourSizer, 0, wx.ALL|wx.EXPAND, 5)
# topSizer.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 5)
topSizer.Add(btnSizer, 0, wx.ALL|wx.CENTER, 5)
# finalSizer.Add(lb, proportion=1, flag=wx.TOP | wx.EXPAND | wx.LEFT, border=5)
finalSizer.Add(checkSizer, 1, wx.EXPAND | wx.LEFT, 5)
# finalSizer.Add(inputTwoSizer, 1, wx.EXPAND | wx.LEFT, 5)
finalSizer.Add(topSizer, 1, wx.EXPAND | wx.RIGHT, 5)
self.panel.SetSizer(finalSizer)
finalSizer.Fit(self)
def EvtListBox(self, event):
self.log.WriteText('EvtListBox: %s\n' % event.GetString())
def EvtCheckListBox(self, event):
index = event.GetSelection()
label = self.lb.GetString(index)
status = 'un'
if self.lb.IsChecked(index):
status = ''
self.log.WriteText('Box %s is %schecked \n' % (label, status))
self.lb.SetSelection(index) # so that (un)checking also selects (moves the highlight)
def onOK(self, event):
# Do something
print 'onOK handler'
def onCancel(self, event):
self.closeProgram()
def closeProgram(self):
self.Close()
# Run the program
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = MyForm().Show()
# import wx.lib.inspection
# wx.lib.inspection.InspectionTool().Show()
app.MainLoop()
I have found its easier to seperate out concerns
import wx
import wx.lib.scrolledpanel
class SizerMixin:
def _hz(self,*widgets):
sz = wx.BoxSizer(wx.HORIZONTAL)
sz.AddMany(widgets)
return sz
def _label(self,label_text,*widgets,**kwargs):
label_size = kwargs.pop("label_size",100)
return self._hz(
(wx.StaticText(self,-1,label_text,size=(label_size,-1)),0,wx.ALIGN_CENTER_VERTICAL),
*widgets)
class MainPanel(wx.Panel,SizerMixin):
def __init__(self,parent):
wx.Panel.__init__(self,parent,-1)
self.CreateWidgets()
self.SetSizer(self.DoLayout())
self.Fit()
def DoLayout(self):
sb = wx.StaticBox(self,-1,"Main Title")
sz = wx.StaticBoxSizer(sb,wx.VERTICAL)
title = wx.StaticText(self,-1,"A Title Goes Here")
sz.Add(title,0,wx.ALIGN_CENTER|wx.EXPAND)
sz.Add(wx.StaticLine(self,-1),0,wx.EXPAND,5) #seperator
body_sizer = wx.BoxSizer(wx.HORIZONTAL)
rightSideInputs = wx.BoxSizer(wx.VERTICAL)
rightSideInputs.Add(self._label("Input 1:",self._widgets["input1"]),0,wx.EXPAND|wx.ALL,5)
rightSideInputs.Add(self._label("Input 2:",self._widgets["input2"]),0,wx.EXPAND|wx.ALL,5)
body_sizer.Add(self._widgets["checklist"],1,wx.EXPAND)
body_sizer.Add(rightSideInputs,1,wx.EXPAND)
sz.Add(body_sizer)
button_sizer = wx.StdDialogButtonSizer()
ok_btn = wx.Button(self,wx.ID_OK)
cancel_btn = wx.Button(self,wx.ID_CANCEL)
button_sizer.AddButton(ok_btn)
button_sizer.AddButton(cancel_btn)
button_sizer.Realize()
sz.Add(button_sizer)
return sz
def CreateWidgets(self):
sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
'twelve', 'thirteen', 'fourteen']
self._widgets = {
"input1":wx.TextCtrl(self,-1),
"input2":wx.TextCtrl(self,-1),
"checklist":wx.CheckListBox(self,-1,choices=sampleList)
}
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, title='My Form')
self.panel = MainPanel(self)
self.Layout()
self.Fit()
def EvtListBox(self, event):
self.log.WriteText('EvtListBox: %s\n' % event.GetString())
def EvtCheckListBox(self, event):
index = event.GetSelection()
label = self.lb.GetString(index)
status = 'un'
if self.lb.IsChecked(index):
status = ''
self.log.WriteText('Box %s is %schecked \n' % (label, status))
self.lb.SetSelection(index) # so that (un)checking also selects (moves the highlight)
def onOK(self, event):
# Do something
print 'onOK handler'
def onCancel(self, event):
self.closeProgram()
def closeProgram(self):
self.Close()
# Run the program
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = MyForm().Show()
# import wx.lib.inspection
# wx.lib.inspection.InspectionTool().Show()
app.MainLoop()
im having a little issue with NoteBook switching. When I switch notebook tabs, I will need to resize to make the wigdets display properly. I tried using self.Refresh() but that does not seem to do anything. If you have trouble understanding me, please run the following code, then switch tabs and resize, you will notice that there is problems, displaying things correctly. I do not know if this is a problem with wxPython but I think it is with my code.
IMAGE_NAME = []
IMAGE_DATA = []
IMAGEMORE_NAME=[]
IMAGEMORE_DATA=[]
import sys
import wx
def deletepic(self):
try:
self.parent.bitmap.Destroy()
except:
print sys.exc_info()
def sendnewpic(self):
if self.parent.bitmap: deletepic(self)
if IMAGE_DATA[self.image_listsel] != '':
try:
print IMAGE_DATA[self.image_listsel]
bmp = wx.Image(IMAGE_DATA[self.image_listsel], wx.BITMAP_TYPE_ANY).ConvertToBitmap()
self.parent.scroll_img.SetScrollbars(1, 1, bmp.GetWidth(), bmp.GetHeight())
self.parent.bitmap = wx.StaticBitmap(self.parent.scroll_img, -1, bmp, (0, 0))
self.parent.Refresh()
except:
pass
def areachange(self, pg):
print pg
try:
if IMAGE_DATA[self.image_listsel] == '':
deletepic(self)
except:
pass
if pg == "Regular Pictures":
self.images_area.Show()
self.scroll_img.Show()
self.btnTwo.Show()
else:
self.images_area.Hide()
self.scroll_img.Hide()
self.btnTwo.Hide()
if pg == "More Pictures":
self.images_area.Show()
self.scroll_img.Show()
self.imageboxersiz.Show()
else:
self.imageboxersiz.Hide()
self.Refresh()
class imageTab(wx.Panel):
def __init__(self, parent, grandparent):
wx.Panel.__init__(self, parent)
self.parent = grandparent
self.image_listsel = 0
self.listBox = wx.ListBox(self, size=(200, -1), choices=IMAGE_NAME, style=wx.LB_SINGLE)
self.sizer = wx.BoxSizer(wx.VERTICAL)
btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
self.sizerMain = wx.BoxSizer()
self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self.reName)
self.listBox.Bind(wx.EVT_LISTBOX, self.imagesel)
btn = wx.Button(self, label="Create New",size=(200, 40))
btnTwo = wx.Button(self, label="Test 2",size=(200, 40))
btn.Bind(wx.EVT_BUTTON, self.newAddImage)
self.sizer.Add(self.listBox, proportion=1, flag=wx.TOP | wx.EXPAND | wx.LEFT, border=5)
btnSizer.Add(btn, 0, wx.ALL, 5)
btnSizer.Add(btnTwo, 0, wx.ALL, 5)
self.sizer.Add(btnSizer)
self.sizerMain.Add(self.sizer, proportion=0, flag=wx.BOTTOM | wx.EXPAND, border=0)
self.SetSizer(self.sizerMain)
def imagesel(self, evt):
self.image_listsel = self.listBox.GetSelection()
sendnewpic(self)
def newAddImage(self, evt):
IMAGE_NAME.append('hi')
IMAGE_DATA.append('')
self.listBox.Set(IMAGE_NAME)
self.listBox.SetSelection(len(IMAGE_NAME)-1)
self.imagesel(None) #making it a selected image, globally
def reName(self,parent):
sel = self.listBox.GetSelection()
text = self.listBox.GetString(sel)
renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)
if renamed != '':
IMAGE_NAME.pop(sel)
IMAGE_NAME.insert(sel,renamed)
self.listBox.Set(IMAGE_NAME)
self.listBox.SetSelection(sel)
class objectTab(wx.Panel):
def __init__(self, parent, grandparent):
wx.Panel.__init__(self, parent)
self.parent = grandparent
self.image_listsel = 0
self.listBox = wx.ListBox(self, size=(200, -1), choices=IMAGEMORE_NAME, style=wx.LB_SINGLE)
self.sizer = wx.BoxSizer(wx.VERTICAL)
btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
self.sizerMain = wx.BoxSizer()
self.listBox.Bind(wx.EVT_LISTBOX_DCLICK, self.reName)
self.listBox.Bind(wx.EVT_LISTBOX, self.imagesel)
btn = wx.Button(self, label="Create New",size=(200, 40))
btnTwo = wx.Button(self, label="Test 2",size=(200, 40))
btn.Bind(wx.EVT_BUTTON, self.newAddImage)
self.sizer.Add(self.listBox, proportion=1, flag=wx.TOP | wx.EXPAND | wx.LEFT, border=5)
btnSizer.Add(btn, 0, wx.ALL, 5)
btnSizer.Add(btnTwo, 0, wx.ALL, 5)
self.sizer.Add(btnSizer)
self.sizerMain.Add(self.sizer, proportion=0, flag=wx.BOTTOM | wx.EXPAND, border=0)
self.SetSizer(self.sizerMain)
def imagesel(self, evt):
self.image_listsel = self.listBox.GetSelection()
def newAddImage(self, evt):
IMAGEMORE_NAME.append('New image')
IMAGEMORE_DATA.append('')
self.listBox.Set(IMAGEMORE_NAME)
self.listBox.SetSelection(len(IMAGEMORE_NAME)-1)
self.imagesel(None) #making it a selected image, globally
def reName(self,parent):
sel = self.listBox.GetSelection()
text = self.listBox.GetString(sel)
renamed = wx.GetTextFromUser('Rename item', 'Rename dialog', text)
if renamed != '':
IMAGEMORE_NAME.pop(sel)
IMAGEMORE_NAME.insert(sel,renamed)
self.listBox.Set(IMAGEMORE_NAME)
self.listBox.SetSelection(sel)
class MyPanel(wx.Panel):
def __init__(self, *args, **kwargs):
wx.Panel.__init__(self, *args, **kwargs)
self.notebook = wx.Notebook(self, size=(225, -1))
self.tab_images = imageTab(self.notebook, self)
self.notebook.AddPage(self.tab_images, "Regular Pictures", select=True)
self.tab_imagesmore = objectTab(self.notebook, self)
self.notebook.AddPage(self.tab_imagesmore, "More Pictures")
self.scroll_img = wx.ScrolledWindow(self, -1)
self.scroll_img.SetScrollbars(1, 1, 600, 400)
self.images_area = wx.StaticBox(self, -1, '')
self.sizerBox = wx.StaticBoxSizer(self.images_area, wx.HORIZONTAL)
self.sizerBox2 = wx.BoxSizer()
self.sizerBox.Add(self.scroll_img, 1, wx.EXPAND|wx.ALL, 10)
self.sizerBox2.Add(self.sizerBox, 1, wx.EXPAND|wx.ALL, 10)
self.sizer = wx.BoxSizer()
self.sizer.Add(self.notebook, proportion=0, flag=wx.EXPAND)
btnSizer = wx.BoxSizer(wx.VERTICAL) #change to horizontal for side by side
self.btnTwo = wx.Button(self, label="Load File", size=(200, 40))
self.bmp = None
self.bitmap = None
self.imageboxersiz=wx.ComboBox(self, -1, "None Selected!",(0, 0), (190,20),IMAGE_NAME, wx.CB_DROPDOWN)
btnSizer.Add(self.imageboxersiz, 0, wx.TOP, 15)
btnSizer.Add(self.btnTwo, 0, wx.TOP, 15)
self.sizerBox2.Add(btnSizer)
#
self.sizer.Add(self.sizerBox2, proportion=1, flag=wx.EXPAND)
self.SetSizer(self.sizer)
self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
areachange(self, self.notebook.GetPageText(0))
def OnClickTop(self, event):
self.scroll_img.Scroll(600, 400)
def OnClickBottom(self, event):
self.scroll_img.Scroll(1, 1)
def OnPageChanged(self, event):
new = event.GetSelection()
areachange(self, self.notebook.GetPageText(new))
event.Skip()
def OnPageChanging(self, event):
event.Skip()
class MainWindow(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.panel = MyPanel(self)
self.Show()
app = wx.App(False)
win = MainWindow(None, size=(600, 400))
app.MainLoop()
Thank you very much.
Just change the self.Refresh() to self.Layout(). Worked for me on Windows 7 anyway.
I'm trying to build a small application in wxPython (absolute beginner) in which I display a login box before showing the content. I created a frame, inside the frame a panel with a flexigrid to put the login form inside but it doesn't show. If I launch the application the login form is invisible. If I resize the application the login box shows. Any idea why? Here's my code so far:
import wx
class AP_App(wx.App):
def OnInit(self):
frame = AP_MainFrame("Test application", (0, 0), (650, 350))
frame.Show()
self.SetTopWindow(frame)
loginPanel = AP_LoginPanel(frame)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
return True
def OnCloseWindow(self, event):
self.Destroy()
class AP_MainFrame(wx.Frame):
def __init__(self, title, pos, size):
wx.Frame.__init__(self, None, -1, title, pos, size)
self.CreateStatusBar()
class AP_LoginPanel(wx.Panel):
def __init__(self, frame):
self.panel = wx.Panel(frame)
self.frame = frame
self.frame.SetStatusText("Authentification required!")
self.showLoginBox()
def showLoginBox(self): #Create the sizer
sizer = wx.FlexGridSizer(rows = 3, cols = 2, hgap = 5, vgap = 15)
# Username
self.txt_Username = wx.TextCtrl(self.panel, 1, size = (150, -1))
lbl_Username = wx.StaticText(self.panel, -1, "Username:")
sizer.Add(lbl_Username,0, wx.LEFT|wx.TOP| wx.RIGHT, 50)
sizer.Add(self.txt_Username,0, wx.TOP| wx.RIGHT, 50)
# Password
self.txt_Password = wx.TextCtrl(self.panel, 1, size=(150, -1), style=wx.TE_PASSWORD)
lbl_Password = wx.StaticText(self.panel, -1, "Password:")
sizer.Add(lbl_Password,0, wx.LEFT|wx.RIGHT, 50)
sizer.Add(self.txt_Password,0, wx.RIGHT, 50)
# Submit button
btn_Process = wx.Button(self.panel, -1, "&Login")
self.panel.Bind(wx.EVT_BUTTON, self.OnSubmit, btn_Process)
sizer.Add(btn_Process,0, wx.LEFT, 50)
self.panel.SetSizer(sizer)
def OnSubmit(self, event):
UserText = self.txt_Username.GetValue()
PasswordText = self.txt_Password.GetValue()
if __name__ == '__main__':
app = AP_App()
app.MainLoop()
I just discovered I'm calling frame.Show() too soon. :)