Calling a Subform of Startup - python

class MyDialog(wx.Frame):
def __init__(self, parent, title):
self.no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
wx.Frame.__init__(self, parent, title=title, size=(500, 450),style = self.no_resize)
self.panel = wx.Panel(self, size=(250, 270))
self.combo = wx.ComboBox(self.panel, -1, pos=(60, 100))
#call settings form here
self.start_read_thread()
self.Centre()
self.Show(True)
def read_employees(self,read_file):
emp_list = []
with open(read_file) as f_obj:
for line in f_obj:
emp_list.append(line)
wx.CallAfter(self.combo.Append, emp_list)
def start_read_thread(self):
filename = 'employees.txt'
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
executor.submit(self.read_employees, filename)
app = wx.App(False)
frame = MyDialog(None, "Messaging App")
app.MainLoop()
Problem:
When the program loads for the first time on the users machine, it will open a settings menu that prompts for the e-mail/password. Without filling out the settings menu, the program is of no use, so calling the settings subform and having the user configure it is necessary. In subsequent startups, it will just read the data in from the file.
Should I call the settings subform from the __init__ constructor directly, or another thread and pass the data? I'm still learning threading, but to me, it seems like overkill for a simple subform to gather the data.
Any time afterward, the user can on the settings menu and access that same subform to update the data.

It does seem like overkill.
Without knowing exactly what your plans are, I'd run with something simple like this.
import wx
import os
class MyDialog(wx.Frame):
def __init__(self, parent, title):
self.no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX)
wx.Frame.__init__(self, parent, title=title, size=(500, 450),style = self.no_resize)
self.panel = wx.Panel(self, size=(250, 270))
self.emp_list = []
e_name = 'employees.txt'
if os.access(e_name, os.R_OK):
with open(e_name,'r') as f_obj:
for line in f_obj:
self.emp_list.append(line.strip())
else:
#Call employees.txt setup routine here
frame = SetUp(parent=self)
self.combo = wx.ComboBox(self.panel, -1,choices=self.emp_list, pos=(60, 100))
self.Centre()
self.Show(True)
class SetUp(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self, parent, wx.ID_ANY, "Setup employee data", size= (280,130))
self.parent=parent
sizer = wx.BoxSizer(wx.VERTICAL)
self.emp_panel = wx.Panel(self, wx.ID_ANY)
self.employee_name = wx.TextCtrl(self.emp_panel, wx.ID_ANY, "Input Employee Name",size=(200,25))
self.emp_button = wx.Button(self.emp_panel, wx.ID_ANY, "Add")
self.emp_button.Bind(wx.EVT_BUTTON, self.AddEmp)
close_button = wx.Button(self.emp_panel, wx.ID_ANY, "Close")
close_button.Bind(wx.EVT_BUTTON, self.OnClose)
sizer.Add(self.employee_name)
sizer.Add(self.emp_button)
sizer.Add(close_button)
self.emp_panel.SetSizer(sizer)
self.Show()
def AddEmp(self,event):
e_name = 'employees.txt'
emp_name = self.employee_name.GetValue()
with open(e_name,'a') as f_obj:
f_obj.write(emp_name+"\n")
def OnClose(self,event):
e_name = 'employees.txt'
if os.access(e_name, os.R_OK):
with open(e_name,'r') as f_obj:
for line in f_obj:
self.parent.combo.Append(line.strip())
self.Close()
app = wx.App()
frame = MyDialog(None, "Messaging App")
app.MainLoop()
It's very rough and ready but I am running of time to do other things.
Hopefully it will help

Related

Change FilePickerCtrl box width (wxPython)

I am new to wxpython. I am trying to write a little app that allows me to pick a file. I wonder how I can change the width of the file path box.
My code is below:
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title = title, size=(500, 400))
self.Center()
self.panel = wx.Panel(self)
self.label1 = wx.StaticText(self.panel)
self.fileCtrl = wx.FilePickerCtrl(self.panel, size=(100, 50))
row1 = wx.StaticBoxSizer(wx.StaticBox(self.panel, 1, 'Please select the input file:'), orient=wx.HORIZONTAL)
row1.Add(self.label1,0,wx.TOP | wx.RIGHT,70)
row1.Add(self.fileCtrl)
wrapper = wx.FlexGridSizer(1,1,20,20)
wrapper.AddGrowableCol(0)
wrapper.Add(row1,50,wx.TOP | wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER,20)
self.panel.SetSizerAndFit(wrapper)
self.Centre()
#self.Fit()
self.Show()
app = wx.App(False)
win = MainWindow(None, "File selector")
app.MainLoop()
In short, I don't think that you can.
From the look of your example I'm guessing that you are running on MSW, my example is from Linux but it shouldn't matter in this case.
Your code looks a bit off, so I have cleaned it up a bit. try it and see if it helps.
You could always use wx.FileDialog rather than wx.FilePicker
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title = title, size=(500, 400))
self.panel = wx.Panel(self)
self.label1 = wx.StaticText(self.panel,wx.ID_ANY,"Select the Input File")
self.fileCtrl = wx.FilePickerCtrl(self.panel, message="Select the input file name")
self.selectedfile = wx.TextCtrl(self.panel,wx.ID_ANY,"None",size=(490,25))
self.fileCtrl.Bind(wx.EVT_FILEPICKER_CHANGED, self.Selected)
row1 = wx.BoxSizer(wx.VERTICAL)
row1.Add(self.label1,0,wx.TOP | wx.RIGHT,5)
row1.Add(self.fileCtrl)
row1.Add(self.selectedfile)
self.panel.SetSizer(row1)
self.Show()
def Selected(self, event):
self.selectedfile.SetValue(self.fileCtrl.GetPath())
app = wx.App(False)
win = MainWindow(None, "File selector")
app.MainLoop()
Edit:
I'm not sure if anything has changed with this widget in the years since I first answered this question but following would be how I'd code it today.
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title = title, size=(500, 200))
self.panel = wx.Panel(self)
row1 = wx.StaticBoxSizer(wx.VERTICAL, self.panel, 'Please select the input file:')
self.fileCtrl = wx.FilePickerCtrl(self.panel, message="Select file",style=wx.FLP_USE_TEXTCTRL,size=(390,25))
row1.Add(self.fileCtrl,0,wx.ALL,10)
self.panel.SetSizer(row1)
self.Show()
app = wx.App(False)
win = MainWindow(None, "File selector")
app.MainLoop()
You could use the VERTICAL & HORIZONTAL BoxSizer and keep the proportion of widget as 1 instead of the default 0
Code below:
import wx
import os
wildcard = "All files (*.*)|*.*"
class MainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='File Selector')
self.currentDirectory = os.getcwd()
self.panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
ie_box = wx.StaticBox(self.panel, -1, 'Please select the input file')
ie_sizer = wx.StaticBoxSizer(ie_box, wx.VERTICAL)
fl_box = wx.BoxSizer(wx.HORIZONTAL)
self.fl_ctrl = wx.FilePickerCtrl(self.panel, message="Choose a file")
fl_box.Add(self.fl_ctrl, 1, wx.ALL | wx.CENTER | wx.EXPAND, 5)
ie_sizer.Add(fl_box, 1, wx.ALL | wx.CENTER | wx.EXPAND, 10)
self.fl_ctrl.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_open_file)
vbox.Add(ie_sizer, 0, wx.ALL | wx.CENTER | wx.EXPAND, 5)
self.panel.SetSizer(vbox)
self.Center()
self.panel.Fit()
self.Show()
def on_open_file(self, event):
self.fl_ctrl.GetPath()
if __name__ == '__main__':
app = wx.App()
frame = MainWindow()
app.MainLoop()

wxPython wx.TextCtrl is uneditable

In my wxPython Application I have a few wx.TextCtrl input fields for a form. My problem is, some of my wx.TextCtrl input fields are uneditable, meaning I can not type in the field nor can I select text that is in the field. My parent wx.Panel in my main.py file has two children a login wx.Panel and a wx.Notebook. The wx.TextCtrls in my login work great, but the wx.TextCtrls in my wx.Notebook do not work. The following code is from my main.py file where I create my wx.Notebook and add a page:
main.py
import wx
from LoginPanel import LoginPanel
from UserView import UserView
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title=title, size=(850,725))
# Creating Panels
self.main = wx.Panel(self)
self.mainLogin = LoginPanel(self.main,-1,addSpacers=1)
#start off showing the login panel
self.mainLogin.Show()
# Create a notebook on the panel
self.nb = wx.Notebook(self.main, 1)
#Start off hiding the Notebook until successfully logged in
self.nb.Hide()
# create the page windows as children of the notebook
self.userAdmin = UserView(parent=self.nb, ID=-1)
# add the pages to the notebook with the label to show on the tab
self.nb.AddPage(self.userAdmin, "Users")
# Bindings
self.Bind(wx.EVT_BUTTON, self.EvtLoginBtn, self.mainLogin.loginBtns.LoginBtn)
self.Bind(wx.EVT_BUTTON, self.EvtLogoutBtn, self.mainLogin.loginBtns.LogoutBtn)
# Create sizers
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
# Adding Objects to mainSizer
self.mainSizer.AddSpacer(10)
self.mainSizer.Add(self.mainLogin, 1, wx.ALL|wx.EXPAND)
self.mainSizer.Add(self.nb, 1, wx.ALL|wx.EXPAND)
# Set main sizer
self.main.SetAutoLayout(True)
self.main.SetSizer(self.mainSizer)
self.mainSizer.Fit(self.main)
self.Layout()
self.Centre(wx.BOTH)
self.Show()
def EvtLoginBtn(self,e):
self.nb.Show()
self.mainLogin.Hide()
print("Login clicked")
self.mainSizer.Layout()
def EvtLogoutBtn(self,e):
print("Logout clicked")
app = wx.App(False)
frame = MyFrame(None, -1, 'App UI')
app.MainLoop()
LoginPanel.py
import wx
from OneLblOneSingleTxt_HorzBoxSizer_Panel import OneLblOneSingleTxt_HorzBoxSizer_Panel
from LoginBtnsPanel import LoginBtnsPanel
class LoginPanel(wx.Panel):
def __init__(self, parent, ID, addSpacers):
wx.Panel.__init__(self, parent, ID)
sizer = wx.BoxSizer(wx.VERTICAL)
self.userNamePnl = OneLblOneSingleTxt_HorzBoxSizer_Panel(self,-1,
name="loginUser", lbl="Username: ", addSpacers=1)
self.passwordPnl = OneLblOneSingleTxt_HorzBoxSizer_Panel(self,-1,
name="loginPass", lbl="Password: ", addSpacers=1)
self.loginBtns = LoginBtnsPanel(self,-1)
if addSpacers == 1:
sizer.AddStretchSpacer()
sizer.Add(self.userNamePnl,0,wx.EXPAND)
sizer.AddSpacer(10)
sizer.Add(self.passwordPnl,0,wx.EXPAND)
sizer.AddSpacer(10)
sizer.Add(self.loginBtns,0,wx.EXPAND)
if addSpacers == 1:
sizer.AddStretchSpacer()
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
self.Layout()
OneLblOneSingleTxt_HorzBoxSizer_Panel.py
import wx
class OneLblOneSingleTxt_HorzBoxSizer_Panel(wx.Panel):
def __init__(self, parent, ID, name, lbl, addSpacers):
wx.Panel.__init__(self, parent, ID)
sizer = wx.BoxSizer(wx.HORIZONTAL)
lbl = wx.StaticText(self, label=lbl)
self.singleTxt = wx.TextCtrl(self, size=(140,-1))
if addSpacers==1:
sizer.AddStretchSpacer()
sizer.Add(lbl,0,wx.EXPAND)
sizer.AddSpacer(10)
sizer.Add(self.singleTxt,1,wx.EXPAND)
sizer.AddStretchSpacer()
if addSpacers==1:
sizer.AddStretchSpacer()
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
LoginBtnsPanel.py
import wx
class LoginBtnsPanel(wx.Panel):
def __init__(self, parent, ID):
wx.Panel.__init__(self, parent, ID)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.LoginBtn =wx.Button(self, label='Login')
self.LogoutBtn =wx.Button(self, label='Logout')
sizer.AddStretchSpacer()
sizer.Add(self.LoginBtn,1,wx.EXPAND)
sizer.AddSpacer(10)
sizer.Add(self.LogoutBtn,1,wx.EXPAND)
sizer.AddStretchSpacer()
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
UserView.py
import wx
from UserTable import UserGridTable
class UserView(wx.Panel):
def __init__(self, parent, ID):
wx.Panel.__init__(self, parent, ID)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.gridPnl = wx.Panel(self,-1)
self.gridPnlSizer = wx.BoxSizer(wx.HORIZONTAL)
#Grid that show current users
self.UserGrid = UserGridTable(self.gridPnl)
#Start out showing this Grid until the Add button or Edit button is clicked
self.UserGrid.Show()
self.userEntryPnl = wx.Panel(self,0)
self.userEntryPnlSizer = wx.BoxSizer(wx.VERTICAL)
self.userlbl = wx.StaticText(self.userEntryPnl, label='Username')
self.userTxt = wx.TextCtrl(self.userEntryPnl, size=(140,-1))
self.userTxt.SetModified(True)
self.userTxt.SetEditable(True)
self.passlbl = wx.StaticText(self.userEntryPnl, label='Password')
self.passTxt = wx.TextCtrl(self.userEntryPnl, size=(140,-1))
self.passTxt.SetModified(True)
self.passTxt.SetEditable(True)
self.userEntryPnlSizer.AddStretchSpacer()
self.userEntryPnlSizer.Add(self.userlbl,0,wx.EXPAND)
self.userEntryPnlSizer.AddSpacer(10)
self.userEntryPnlSizer.Add(self.userTxt,0,wx.EXPAND)
self.userEntryPnlSizer.AddSpacer(10)
self.userEntryPnlSizer.Add(self.passlbl,0,wx.EXPAND)
self.userEntryPnlSizer.AddSpacer(10)
self.userEntryPnlSizer.Add(self.passTxt,0,wx.EXPAND)
self.userEntryPnlSizer.AddStretchSpacer()
self.userEntryPnl.SetAutoLayout(True)
self.userEntryPnl.SetSizer(self.userEntryPnlSizer)
self.userEntryPnlSizer.Fit(self.userEntryPnl)
#start out hiding this panel until Add button or Edit button is clicked
self.userEntryPnl.Hide()
self.gridPnlSizer.AddStretchSpacer()
self.gridPnlSizer.Add(self.UserGrid,0,wx.EXPAND)
self.gridPnlSizer.Add(self.userEntryPnl,0,wx.EXPAND)
self.gridPnlSizer.AddStretchSpacer()
self.gridPnl.SetAutoLayout(True)
self.gridPnl.SetSizer(self.gridPnlSizer)
self.gridPnlSizer.Fit(self.gridPnl)
self.bottomBtnsPnl = wx.Panel(self,-1)
self.bottomSizer = wx.BoxSizer(wx.HORIZONTAL)
self.AddBtn = wx.Button(self.bottomBtnsPnl, label='Add')
self.EditBtn = wx.Button(self.bottomBtnsPnl, label='Edit')
self.DeleteBtn = wx.Button(self.bottomBtnsPnl, label='Delete')
self.SaveBtn = wx.Button(self.bottomBtnsPnl, label='Save')
self.AddBtn.Show()
self.EditBtn.Show()
self.DeleteBtn.Show()
self.SaveBtn.Hide()
self.Bind(wx.EVT_BUTTON, self.addBtnEnt, self.AddBtn)
self.Bind(wx.EVT_BUTTON, self.editBtnEnt, self.EditBtn)
self.Bind(wx.EVT_BUTTON, self.deleteBtnEnt, self.DeleteBtn)
self.Bind(wx.EVT_BUTTON, self.saveBtnEnt, self.SaveBtn)
self.bottomSizer.AddStretchSpacer()
self.bottomSizer.Add(self.AddBtn,0,wx.EXPAND)
self.bottomSizer.AddSpacer(10)
self.bottomSizer.Add(self.EditBtn,0,wx.EXPAND)
self.bottomSizer.AddSpacer(10)
self.bottomSizer.Add(self.DeleteBtn,0,wx.EXPAND)
self.bottomSizer.AddSpacer(10)
self.bottomSizer.Add(self.SaveBtn,0,wx.EXPAND)
self.bottomSizer.AddSpacer(10)
self.bottomSizer.AddStretchSpacer()
self.bottomBtnsPnl.SetAutoLayout(True)
self.bottomBtnsPnl.SetSizer(self.bottomSizer)
self.bottomSizer.Fit(self.bottomBtnsPnl)
self.sizer.AddSpacer(10)
self.sizer.Add(self.gridPnl,0,wx.EXPAND)
self.sizer.AddSpacer(10)
self.sizer.Add(self.bottomBtnsPnl,0,wx.EXPAND)
self.sizer.AddSpacer(10)
self.SetAutoLayout(True)
self.SetSizer(self.sizer)
self.sizer.Fit(self)
def addBtnEnt(self,e):
self.UserGrid.Hide()
self.AddBtn.Hide()
self.EditBtn.Hide()
self.DeleteBtn.Hide()
self.SaveBtn.Show()
self.userEntryPnl.Show()
self.userEntryPnl.Layout()
def editBtnEnt(self,e):
self.UserGrid.Hide()
self.AddBtn.Hide()
self.EditBtn.Hide()
self.DeleteBtn.Hide()
self.SaveBtn.Show()
self.userEntryPnl.Show()
self.userEntryPnl.Layout()
def deleteBtnEnt(self,e):
print("Delete clicked")
def saveBtnEnt(self,e):
self.userEntryPnl.Hide()
self.SaveBtn.Hide()
self.UserGrid.Show()
self.AddBtn.Show()
self.EditBtn.Show()
self.DeleteBtn.Show()
self.userEntryPnl.Layout()
UserTable.py
import wx
import wx.grid
class UserGridTable(wx.grid.Grid):
def __init__(self, parent):
wx.grid.Grid.__init__(self, parent)
self.CreateGrid(6,3)
self.SetColLabelValue(0, "ID")
self.SetColLabelValue(1, "Username")
self.SetColLabelValue(2, "Password")
self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.EmpCellLeftClick, self)
def EmpCellLeftClick(self,e):
self.SelectRow(e.GetRow())
How do I get self.userTxt and self.passTxt to be editable where I can enter text in and select it? Thank you for any and all help!
UPDATE:
The above code is a working on Python 2.7.8
As a quick fix, change
self.userEntryPnl = wx.Panel(self, 0)
To
self.userEntryPnl = wx.Panel(self.gridPnl, -1)
gridPnl was on top of userEntryPnl although userEntryPnl was visible. Because of that you couldn't edit what was underneath gridPnl.

Wxpython Switching frames between two python files

i have two py files that each have its own frame made using wxPython, MainWindow and RecWindow. MainWindow has the RecWindow python file included using the keyword "recovery".
MainWindow code:
class MainWindow(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self, parent, wx.ID_ANY,title,pos=(500,200), size = (650,500), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
self.Bind(wx.EVT_CLOSE,self.OnExit)
self.SetIcon(wx.Icon('etc\icons\download.ico', wx.BITMAP_TYPE_ICO))
panel = wx.Panel(self)
RecWindow code:
class RecWindow(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self, parent, wx.ID_ANY,title,pos=(400,200), size = (700,600), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
self.SetIcon(wx.Icon('etc\icons\download.ico', wx.BITMAP_TYPE_ICO))
self.count = 0
when i click on a button in MainWindow , it will hide the MainWindow create an instance of RecWindow, shown below;
def OpenRec(self,event):#this will be used to open the next frame
OR = recovery(None,-1,"RAVE")
OR.Show(True)
MainWindow.Hide()
now, what i am unsure of is how i can return to the MainWindow once i close the RecWindow. RecWindow has a cancel and finish button which both map to a self.close() function. How would i then get MainWindow to show itself again?
Use pubsub to send a message to the main window telling it to Show itself again. I actually have an example of how to do that here:
http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/
Note that this tutorial is using slightly older API that was available in wxPython 2.8. If you're using wxPython 2.9, then you'll have to use the slightly different API that I detail in this article:
http://www.blog.pythonlibrary.org/2013/09/05/wxpython-2-9-and-the-newer-pubsub-api-a-simple-tutorial/
When you create an instance of RecWindow keep a reference to it on main_window and bind to its close event.
In the main_window's close handler check if the window closed was the RecWindow.
If it was, clear the reference to it and show the main_window.
Elif the closed window was main_window carry out any required code.
Finally call event.Skip() so the windows get destroyed.
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, (500, 200), (650, 500),
wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
panel = wx.Panel(self)
button = wx.Button(panel, wx.ID_OPEN)
panel.sizer = wx.BoxSizer(wx.VERTICAL)
panel.sizer.Add(button, 0, wx.ALL, 7)
panel.SetSizer(panel.sizer)
button.Bind(wx.EVT_BUTTON, self.on_button)
self.Bind(wx.EVT_CLOSE, self.on_close)
self.rec_window = None
def on_button(self, event):
rec_window = RecWindow(self, 'Rec window')
rec_window.Show()
self.Hide()
rec_window.Bind(wx.EVT_CLOSE, self.on_close)
self.rec_window = rec_window
def on_close(self, event):
closed_window = event.EventObject
if closed_window == self.rec_window:
self.rec_window = None
self.Show()
elif closed_window == self:
print 'Carry out your code for when Main window closes'
event.Skip()
class RecWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, (400, 200), (700, 600),
wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
app = wx.App(False)
main_window = MainWindow(None, 'Main window')
main_window.Show()
app.MainLoop()

Save the selected value of a combobox in wxpython

I'm working to design a gui using wxpython, a pecie of my code is that i have a class which a fram
declaration and also i declared variables that i wanna chage their values based on the comboboxes
selection. i did the folowing:
class myMenu(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(900, 700))
self.ct = 0
self.phaseSelection = ""
self.opSelection = ""
self.instSelection = ""
self.orgSelection = ""
panel = wx.Panel(self, -1)
panel.SetBackgroundColour('#4f3856')
phasesList = ["preOperations", "inOperations", "postOperations"]
self.cbPhases = wx.ComboBox(panel, 500, 'Phase', (50, 150), (160,-1), phasesList, wx.CB_DROPDOWN)
self.Bind(wx.EVT_COMBOBOX, self.OnPhaseSelection, id = self.cbPhases.GetId())
and this is the code of the "OnPhaseSelection" event :
def OnPhaseSelection(self, event):
self.phaseSelection = self.cbPhases.GetValue()
where i wanna save the selected value in the variable "self.phaseSelection" that i declared it with an
empty string as initial value, then i wanna use this variable with the new saved value, but when i run
the program, the variable contains the default value of the combobox! so please what is the problem in
my work ?
I'm not sure what's wrong with that. It looks like it should work. I copied most of it and put it into a runnable example that works on Windows:
import wx
########################################################################
class MyForm(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")
panel = wx.Panel(self, wx.ID_ANY)
self.ct = 0
self.phaseSelection = ""
self.opSelection = ""
self.instSelection = ""
self.orgSelection = ""
phasesList = ["preOperations", "inOperations", "postOperations"]
self.combo = wx.ComboBox(panel, choices=phasesList)
self.combo.Bind(wx.EVT_COMBOBOX, self.onCombo)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.combo)
panel.SetSizer(sizer)
#----------------------------------------------------------------------
def onCombo(self, event):
"""
"""
self.phaseSelection = self.combo.GetValue()
print self.phaseSelection
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm().Show()
app.MainLoop()

wxPython: displaying multiple widgets in same frame

I would like to be able to display Notebook and a TxtCtrl wx widgets in a single frame. Below is an example adapted from the wxpython wiki; is it possible to change their layout (maybe with something like wx.SplitterWindow) to display the text box below the Notebook in the same frame?
import wx
import wx.lib.sheet as sheet
class MySheet(sheet.CSheet):
def __init__(self, parent):
sheet.CSheet.__init__(self, parent)
self.SetLabelBackgroundColour('#CCFF66')
self.SetNumberRows(50)
self.SetNumberCols(50)
class Notebook(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 600))
menubar = wx.MenuBar()
file = wx.Menu()
file.Append(101, 'Quit', '' )
menubar.Append(file, "&File")
self.SetMenuBar(menubar)
wx.EVT_MENU(self, 101, self.OnQuit)
nb = wx.Notebook(self, -1, style=wx.NB_BOTTOM)
self.sheet1 = MySheet(nb)
self.sheet2 = MySheet(nb)
self.sheet3 = MySheet(nb)
nb.AddPage(self.sheet1, "Sheet1")
nb.AddPage(self.sheet2, "Sheet2")
nb.AddPage(self.sheet3, "Sheet3")
self.sheet1.SetFocus()
self.StatusBar()
def StatusBar(self):
self.statusbar = self.CreateStatusBar()
def OnQuit(self, event):
self.Close()
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(450, 400))
self.text = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)
self.Center()
class MyApp(wx.App):
def OnInit(self):
frame = Notebook(None, -1, 'notebook.py')
frame.Show(True)
frame.Center()
frame2 = MyFrame(None, -1, '')
frame2.Show(True)
self.SetTopWindow(frame2)
return True
app = MyApp(0)
app.MainLoop()
Making two widgets appear on the same frame is easy, actually. You should use sizers to accomplish this.
In your example, you can change your Notebook class implementation to something like this:
class Notebook(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 600))
menubar = wx.MenuBar()
file = wx.Menu()
file.Append(101, 'Quit', '' )
menubar.Append(file, "&File")
self.SetMenuBar(menubar)
wx.EVT_MENU(self, 101, self.OnQuit)
nb = wx.Notebook(self, -1, style=wx.NB_BOTTOM)
self.sheet1 = MySheet(nb)
self.sheet2 = MySheet(nb)
self.sheet3 = MySheet(nb)
nb.AddPage(self.sheet1, "Sheet1")
nb.AddPage(self.sheet2, "Sheet2")
nb.AddPage(self.sheet3, "Sheet3")
self.sheet1.SetFocus()
self.StatusBar()
# new code begins here:
# add your text ctrl:
self.text = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)
# create a new sizer for both controls:
sizer = wx.BoxSizer(wx.VERTICAL)
# add notebook first, with size factor 2:
sizer.Add(nb, 2)
# then text, size factor 1, maximized
sizer.Add(self.text, 1, wx.EXPAND)
# assign the sizer to Frame:
self.SetSizerAndFit(sizer)
Only the __init__ method is changed. Note that you can manipulate the proportions between the notebook and text control by changing the second argument of the Add method.
You can learn more about sizers from the official Sizer overview article.
You can use a splitter, yes.
Also, it makes sense to create a Panel, place your widgets in it (with sizers), and add this panel to the Frame.

Categories

Resources