So I think I know what my problem is but I cant seem to figure out how to fix it. I am relatively new to wxPython. I am moving some functionality I have in a terminal script to a GUI and cant seem to get it right. I use anaconda for my python distribution and have added wxPython for the GUI. I want users to be able to drag and drop files into the text controls and then have the file contents imported into dataframes for analysis with pandas. So far everything is happy. Other than the fact that the program will not quit. I think it has to do with how I am defining the window and the frame. I have removed a significant amount of the functionality from the script to help simplify things. Please let me know what I am missing.
Thanks
Tyler
import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress
class MyFileDropTarget(wx.FileDropTarget):
#----------------------------------------------------------------------
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
#----------------------------------------------------------------------
def OnDropFiles(self, x, y, filenames):
self.window.SetInsertionPointEnd(y)
#self.window.updateText("\n%d file(s) dropped at %d,%d:\n" %
# (len(filenames), x, y), y)
for filepath in filenames:
self.window.updateText(filepath + '\n', y)
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(200,100))
file_drop_target = MyFileDropTarget(self)
self.CreateStatusBar() # A Statusbar in the bottom of the window
# Creating the menubar.
menubar = wx.MenuBar()
fileMenu = wx.Menu()
helpMenu = wx.Menu()
menubar.Append(fileMenu, '&File')
menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
#self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
fileMenu.AppendSeparator()
menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
menubar.Append(helpMenu, '&Help')
menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About"," Information about this program")
self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
self.SetMenuBar(menubar)
#Create some sizers
mainSizer = wx.BoxSizer(wx.VERTICAL)
grid = wx.GridBagSizer(hgap=5, vgap=5)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
#Create a button
self.button = wx.Button(self, label="Test")
#self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)
# Radio Boxes
sysList = ['QEXL','QEX10','QEX7']
wlList = ['1100', '1400', '1800']
sys = wx.RadioBox(self, label="What system are you calibrating ?", pos=(20, 40), choices=sysList, majorDimension=3,
style=wx.RA_SPECIFY_COLS)
grid.Add(sys, pos=(1,0), span=(1,3))
WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?", pos=(20, 100), choices=wlList, majorDimension=0,
style=wx.RA_SPECIFY_COLS)
grid.Add(WL, pos=(2,0), span=(1,3))
self.lblname = wx.StaticText(self, label="Cal File 1 :")
grid.Add(self.lblname, pos=(3,0))
self.Cal_1 = wx.TextCtrl(self, name="Cal_1", value="", size=(240,-1))
self.Cal_1.SetDropTarget(file_drop_target)
grid.Add(self.Cal_1, pos=(3,1))
self.lblname = wx.StaticText(self, label="Cal File 2 :")
grid.Add(self.lblname, pos=(4,0))
self.Cal_2 = wx.TextCtrl(self, value="", name="Cal_2", size=(240,-1))
self.Cal_2.SetDropTarget(file_drop_target)
grid.Add(self.Cal_2, pos=(4,1))
self.lblname = wx.StaticText(self, label="Cal File 3 :")
grid.Add(self.lblname, pos=(5,0))
self.Cal_3 = wx.TextCtrl(self, value="", name="Cal_3", size=(240,-1))
self.Cal_3.SetDropTarget(file_drop_target)
grid.Add(self.Cal_3, pos=(5,1))
hSizer.Add(grid, 0, wx.ALL, 5)
mainSizer.Add(hSizer, 0, wx.ALL, 5)
mainSizer.Add(self.button, 0, wx.CENTER)
self.SetSizerAndFit(mainSizer)
self.Show(True)
def OnAbout(self,e):
# A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
dlg.ShowModal() # Show it
dlg.Destroy() # finally destroy it when finished.
def OnExit(self,e):
# Close the frame.
self.Close(True)
def SetInsertionPointEnd(self, y):
if y <= -31:
self.Cal_1.SetInsertionPointEnd()
elif y >= -1:
self.Cal_3.SetInsertionPointEnd()
else:
self.Cal_2.SetInsertionPointEnd()
def updateText(self, text, y):
if y <= -31:
self.Cal_1.WriteText(text)
elif y >= -1:
self.Cal_3.WriteText(text)
else:
self.Cal_2.WriteText(text)
app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()
The problem is that you only create one instance of the MyFileDropTarget class and then assign that same object to multiple widgets. It would appear that you need to create one drop target instance per widget. I refactored your code a bit, but here's one way to do it:
import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress
class MyFileDropTarget(wx.FileDropTarget):
#----------------------------------------------------------------------
def __init__(self, window):
wx.FileDropTarget.__init__(self)
self.window = window
#----------------------------------------------------------------------
def OnDropFiles(self, x, y, filenames):
self.window.SetInsertionPointEnd(y)
#self.window.updateText("\n%d file(s) dropped at %d,%d:\n" %
# (len(filenames), x, y), y)
for filepath in filenames:
self.window.updateText(filepath + '\n', y)
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
file_drop_target = MyFileDropTarget(self)
file_drop_target2 = MyFileDropTarget(self)
file_drop_target3 = MyFileDropTarget(self)
#Create some sizers
mainSizer = wx.BoxSizer(wx.VERTICAL)
grid = wx.GridBagSizer(hgap=5, vgap=5)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
#Create a button
self.button = wx.Button(self, label="Test")
#self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)
# Radio Boxes
sysList = ['QEXL','QEX10','QEX7']
wlList = ['1100', '1400', '1800']
sys = wx.RadioBox(self, label="What system are you calibrating ?",
pos=(20, 40), choices=sysList, majorDimension=3,
style=wx.RA_SPECIFY_COLS)
grid.Add(sys, pos=(1,0), span=(1,3))
WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?",
pos=(20, 100), choices=wlList, majorDimension=0,
style=wx.RA_SPECIFY_COLS)
grid.Add(WL, pos=(2,0), span=(1,3))
self.lblname = wx.StaticText(self, label="Cal File 1 :")
grid.Add(self.lblname, pos=(3,0))
self.Cal_1 = wx.TextCtrl(self, name="Cal_1", value="", size=(240,-1))
self.Cal_1.SetDropTarget(file_drop_target)
grid.Add(self.Cal_1, pos=(3,1))
self.lblname = wx.StaticText(self, label="Cal File 2 :")
grid.Add(self.lblname, pos=(4,0))
self.Cal_2 = wx.TextCtrl(self, value="", name="Cal_2", size=(240,-1))
self.Cal_2.SetDropTarget(file_drop_target2)
grid.Add(self.Cal_2, pos=(4,1))
self.lblname = wx.StaticText(self, label="Cal File 3 :")
grid.Add(self.lblname, pos=(5,0))
self.Cal_3 = wx.TextCtrl(self, value="", name="Cal_3", size=(240,-1))
self.Cal_3.SetDropTarget(file_drop_target3)
grid.Add(self.Cal_3, pos=(5,1))
hSizer.Add(grid, 0, wx.ALL, 5)
mainSizer.Add(hSizer, 0, wx.ALL, 5)
mainSizer.Add(self.button, 0, wx.CENTER)
self.SetSizer(mainSizer)
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(400,400))
panel = MyPanel(self)
self.CreateStatusBar() # A Statusbar in the bottom of the window
# Creating the menubar.
menubar = wx.MenuBar()
fileMenu = wx.Menu()
helpMenu = wx.Menu()
menubar.Append(fileMenu, '&File')
menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
#self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
fileMenu.AppendSeparator()
menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
menubar.Append(helpMenu, '&Help')
menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About",
" Information about this program")
self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
self.SetMenuBar(menubar)
self.Show(True)
def OnAbout(self,e):
# A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
dlg.ShowModal() # Show it
dlg.Destroy() # finally destroy it when finished.
def OnExit(self,e):
# Close the frame.
#del self.fdt
self.Close(True)
app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()
UPDATE 2016.03.09 - I decided to post a refactored version of the OP's solution:
import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress
class MyFileDropTarget(wx.FileDropTarget):
#----------------------------------------------------------------------
def __init__(self, obj):
wx.FileDropTarget.__init__(self)
self.obj = obj
#----------------------------------------------------------------------
def OnDropFiles(self, x, y, filenames):
#self.obj.SetInsertionPointEnd(y)
#self.obj.WriteText("\n%d file(s) dropped at %d,%d:\n" %
# (len(filenames), x, y))
for filepath in filenames:
self.obj.WriteText(filepath + '\n')
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
#Create some sizers
mainSizer = wx.BoxSizer(wx.VERTICAL)
grid = wx.GridBagSizer(hgap=5, vgap=5)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
#Create a button
self.button = wx.Button(self, label="Test")
#self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)
# Radio Boxes
sysList = ['QEXL','QEX10','QEX7']
wlList = ['1100', '1400', '1800']
sys = wx.RadioBox(self, label="What system are you calibrating ?",
pos=(20, 40), choices=sysList, majorDimension=3,
style=wx.RA_SPECIFY_COLS)
grid.Add(sys, pos=(1,0), span=(1,3))
WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?",
pos=(20, 100), choices=wlList, majorDimension=0,
style=wx.RA_SPECIFY_COLS)
grid.Add(WL, pos=(2,0), span=(1,3))
x = 3
for widget in range(1, 4):
lbl = wx.StaticText(self, label="Cal File {} :".format(widget))
grid.Add(lbl, pos=(x,0))
txt = wx.TextCtrl(self, name="Cal_{}".format(widget),
value="", size=(240,-1))
dt = MyFileDropTarget(txt)
txt.SetDropTarget(dt)
grid.Add(txt, pos=(x,1))
x += 1
hSizer.Add(grid, 0, wx.ALL, 5)
mainSizer.Add(hSizer, 0, wx.ALL, 5)
mainSizer.Add(self.button, 0, wx.CENTER)
self.SetSizer(mainSizer)
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(400,400))
panel = MyPanel(self)
self.CreateStatusBar() # A Statusbar in the bottom of the window
# Creating the menubar.
menubar = wx.MenuBar()
fileMenu = wx.Menu()
helpMenu = wx.Menu()
menubar.Append(fileMenu, '&File')
menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
#self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
fileMenu.AppendSeparator()
menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
menubar.Append(helpMenu, '&Help')
menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About",
" Information about this program")
self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
self.SetMenuBar(menubar)
self.Show(True)
def OnAbout(self,e):
# A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
dlg.ShowModal() # Show it
dlg.Destroy() # finally destroy it when finished.
def OnExit(self,e):
# Close the frame.
#del self.fdt
self.Close(True)
app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()
Note that you can use a loop to create those label and text widgets.
Mike, Your solution really helped me out thank you. Although it solved the problem with the window not closing it caused a problem with the ability to bring in the files and display their names. I modified the code you provided so that it will work for me and am posting it here in case anyone else has a problem similar to this. It is not the most elegant solution but it works. Thanks again.
import wx
import os
#import pandas as pd
#import numpy as np
#import matplotlib.pyplot as ply
#from scipy.stats import linregress
class MyFileDropTarget(wx.FileDropTarget):
#----------------------------------------------------------------------
def __init__(self, obj):
wx.FileDropTarget.__init__(self)
self.obj = obj
#----------------------------------------------------------------------
def OnDropFiles(self, x, y, filenames):
#self.obj.SetInsertionPointEnd(y)
#self.obj.WriteText("\n%d file(s) dropped at %d,%d:\n" %
# (len(filenames), x, y))
for filepath in filenames:
self.obj.WriteText(filepath + '\n')
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
#Create some sizers
mainSizer = wx.BoxSizer(wx.VERTICAL)
grid = wx.GridBagSizer(hgap=5, vgap=5)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
#Create a button
self.button = wx.Button(self, label="Test")
#self.Bind(wx.EVT_BUTTON, self.OnClick,self.button)
# Radio Boxes
sysList = ['QEXL','QEX10','QEX7']
wlList = ['1100', '1400', '1800']
sys = wx.RadioBox(self, label="What system are you calibrating ?",
pos=(20, 40), choices=sysList, majorDimension=3,
style=wx.RA_SPECIFY_COLS)
grid.Add(sys, pos=(1,0), span=(1,3))
WL = wx.RadioBox(self, label="Maximum WL you currently Calibrating ?",
pos=(20, 100), choices=wlList, majorDimension=0,
style=wx.RA_SPECIFY_COLS)
grid.Add(WL, pos=(2,0), span=(1,3))
self.lblname = wx.StaticText(self, label="Cal File 1 :")
grid.Add(self.lblname, pos=(3,0))
self.Cal_1 = wx.TextCtrl(self, name="Cal_1", value="", size=(240,-1))
Cal1 = MyFileDropTarget(self.Cal_1)
self.Cal_1.SetDropTarget(Cal1)
grid.Add(self.Cal_1, pos=(3,1))
self.lblname = wx.StaticText(self, label="Cal File 2 :")
grid.Add(self.lblname, pos=(4,0))
self.Cal_2 = wx.TextCtrl(self, value="", name="Cal_2", size=(240,-1))
Cal2 = MyFileDropTarget(self.Cal_2)
self.Cal_2.SetDropTarget(Cal2)
grid.Add(self.Cal_2, pos=(4,1))
self.lblname = wx.StaticText(self, label="Cal File 3 :")
grid.Add(self.lblname, pos=(5,0))
self.Cal_3 = wx.TextCtrl(self, value="", name="Cal_3", size=(240,-1))
Cal3 = MyFileDropTarget(self.Cal_3)
self.Cal_3.SetDropTarget(Cal3)
grid.Add(self.Cal_3, pos=(5,1))
hSizer.Add(grid, 0, wx.ALL, 5)
mainSizer.Add(hSizer, 0, wx.ALL, 5)
mainSizer.Add(self.button, 0, wx.CENTER)
self.SetSizer(mainSizer)
class MainWindow(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(400,400))
panel = MyPanel(self)
self.CreateStatusBar() # A Statusbar in the bottom of the window
# Creating the menubar.
menubar = wx.MenuBar()
fileMenu = wx.Menu()
helpMenu = wx.Menu()
menubar.Append(fileMenu, '&File')
menuOpen = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
#self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
fileMenu.AppendSeparator()
menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
menubar.Append(helpMenu, '&Help')
menuAbout= helpMenu.Append(wx.ID_ABOUT, "&About",
" Information about this program")
self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
self.SetMenuBar(menubar)
self.Show(True)
def OnAbout(self,e):
# A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets.
dlg = wx.MessageDialog( self, "A quick test to see if your scans pass repeatability", "DOMA-64 Tester", wx.OK)
dlg.ShowModal() # Show it
dlg.Destroy() # finally destroy it when finished.
def OnExit(self,e):
# Close the frame.
#del self.fdt
self.Close(True)
app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()
Related
There is a simple text editor developed with WxPython.
I need to add hot keys. ctrl+1, ctrl+2, ctrl+3 and ctrl+4. So that when you press these hot keys to perform certain functions.
How can I do it?
The code:
import os
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title)
self.textBox = wx.TextCtrl(self, style=wx.TE_MULTILINE)
fileMenu = wx.Menu()
menuOpen = fileMenu.Append(wx.ID_OPEN,"O&pen","")
menuExit = fileMenu.Append(wx.ID_EXIT,"E&xit","")
menuBar = wx.MenuBar()
menuBar.Append(fileMenu,"&File")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
self.Show(True)
def OnOpen(self,e):
self.dirName = ''
dlg = wx.FileDialog(self, "Choose a file", self.dirName, "", "text file|*.txt", wx.FD_OPEN)
if dlg.ShowModal() == wx.ID_OK:
self.fileName = dlg.GetFilename()
self.dirName = dlg.GetDirectory()
f = open(os.path.join(self.dirName, self.fileName), 'r')
self.textBox.SetValue(f.read())
f.close()
dlg.Destroy()
def OnExit(self,e):
self.Close(True)
app = wx.App(False)
frame = MyFrame(None, 'RecordBooks')
app.MainLoop()
i have wx.Notebook and 2 pages:
nb = wx.Notebook(PanelLobby,wx.ID_ANY,pos=(100,100),size=(413,214))
nb.AddPage(page1,"Page 1",select=True)
nb.AddPage(page2,"Page 2")
i want to add pages to it on button press,
i tried to bind a wx.EVT_LEFT_DOWN event but with no luck.
thanks in advance.
This is actually pretty easy. Here's one way to do it:
import random
import wx
########################################################################
class TabPanel(wx.Panel):
#----------------------------------------------------------------------
def __init__(self, parent):
""""""
wx.Panel.__init__(self, parent=parent)
colors = ["red", "blue", "gray", "yellow", "green"]
self.SetBackgroundColour(random.choice(colors))
btn = wx.Button(self, label="Press Me")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(btn, 0, wx.ALL, 10)
self.SetSizer(sizer)
########################################################################
class DemoFrame(wx.Frame):
"""
Frame that holds all other widgets
"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, wx.ID_ANY,
"Notebook Tutorial",
size=(600,400)
)
panel = wx.Panel(self)
self.tab_num = 3
self.notebook = wx.Notebook(panel)
tabOne = TabPanel(self.notebook)
self.notebook.AddPage(tabOne, "Tab 1")
tabTwo = TabPanel(self.notebook)
self.notebook.AddPage(tabTwo, "Tab 2")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.notebook, 1, wx.ALL|wx.EXPAND, 5)
btn = wx.Button(panel, label="Add Page")
btn.Bind(wx.EVT_BUTTON, self.addPage)
sizer.Add(btn)
panel.SetSizer(sizer)
self.Layout()
self.Show()
#----------------------------------------------------------------------
def addPage(self, event):
""""""
new_tab = TabPanel(self.notebook)
self.notebook.AddPage(new_tab, "Tab %s" % self.tab_num)
self.tab_num += 1
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = DemoFrame()
app.MainLoop()
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.
There's an issue in this bit of wxPython code I have, the StaticText causes everything else to seemingly disappear.
Note: This is my first time using wxPython and I'm very novice at programming in general, so please try to give a clear explanation. Thanks!
import wx
APP_EXIT = 1
pos1 = (150, 200)
class scoutingSet(wx.Frame):
def __init__(self, *args, **kwargs):
super(scoutingSet, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
############################################################
# MENUBARS AND MENUITEMS
menuBar = wx.MenuBar()
fileMenu = wx.Menu()
fileMenu2 = wx.Menu()
openSheet = wx.MenuItem(fileMenu, wx.ID_ANY, 'Open')
openSheet.SetBitmap(wx.Bitmap('open.png'))
fileMenu.AppendItem(openSheet)
fileMenu.AppendSeparator()
saveSheet = wx.MenuItem(fileMenu, wx.ID_ANY, 'Save')
saveSheet.SetBitmap(wx.Bitmap('save.png'))
fileMenu.AppendItem(saveSheet)
fileMenu.AppendSeparator()
quitSheet = wx.MenuItem(fileMenu, APP_EXIT, 'Quit')
quitSheet.SetBitmap(wx.Bitmap('close.png'))
fileMenu.AppendItem(quitSheet)
self.Bind(wx.EVT_MENU, self.OnQuit, id=APP_EXIT)
fileMenu2.Append(100, '&About')
self.Bind(wx.EVT_MENU, self.aboutBox, id=100)
menuBar.Append(fileMenu, 'File')
menuBar.Append(fileMenu2, 'Information')
self.SetMenuBar(menuBar)
############################################################
# BUTTONS AND CONTROL
panel = wx.Panel(self)
closebutton = wx.Button(panel, label = 'Close\nClose', pos = (20, 30))
closebutton.Bind(wx.EVT_BUTTON, self.OnQuit)
############################################################
# STATIC TEXTS
############################################################
# TEXT CONTROL BOXES
wx.TextCtrl(panel, pos = pos1, size = (50, 50))
wx.TextCtrl(panel, pos = (300, 400), size = (50, 50))
############################################################
# SETTINGS
self.stuff(self)
self.Maximize()
self.SetTitle('Scouting Sheet')
self.Centre()
self.Show(True)
############################################################
# Quitting
def OnQuit(self, e):
self.Close()
# Info in
def aboutBox(self, e):
desc = """This is the SOTAbots 2014 scouting sheet for the FRC 2014 game Aerial Assist"""
infoInAbout = wx.AboutDialogInfo()
infoInAbout.SetIcon(wx.Icon('scouting.png', wx.BITMAP_TYPE_PNG))
infoInAbout.SetName('Scouting Sheet')
infoInAbout.SetVersion('1.0')
infoInAbout.SetDescription(desc)
infoInAbout.AddDeveloper('Franklin Lyon\nLucas Grillos')
wx.AboutBox(infoInAbout)
def stuff(self, e):
textpnl = wx.StaticText(self,-1 , label='Watermark', pos=(20, 30))
textpnl.SetForegroundColour('white')
textpnl.SetBackgroundColour('blue')
def main():
ex = wx.App()
scoutingSet(None)
ex.MainLoop()
if __name__ == '__main__':
main()
Note: I put the Static Text in a function, but even inside the InitUI function, the issue persists. It has to do with the StaticText being shown because if I comment out the call everything displays fine.
Thanks in advance.
I think wx.StaticText is put on self (wx.Frame) rather than the panel, although wx.TextCtrl are on the panel. What happens if you put wx.StaticText on the panel?
Also, I think you need a Sizer (ex. wx.BoxSizer) to manage the layout. You can find a tutorial about wx.BoxSizer at http://zetcode.com/wxpython/layout/. In initUI, I will do something like:
txtctrl1 = wx.TextCtrl(panel, pos = pos1, size = (50, 50))
txtctrl2 = wx.TextCtrl(panel, pos = (300, 400), size = (50, 50))
textpnl = wx.StaticText(panel,-1 , label='Watermark', pos=(20, 30))
vbox = wx.BoxSizer(wx.VERTICAL)
vbox.add(txtctrl1, 1, wx.EXPAND | wx.ALL, 5)
vbox.add(txtctrl2, 1, wx.EXPAND | wx.ALL, 5)
vbox.add(textpnl , 1, wx.EXPAND | wx.ALL, 5)
vbox.add(closebutton, 0, wx.EXPAND | wx.ALL, 5)
panel.SetSizer(vbox)
i hope it helps.
You GUI components are not properly laid out. I recommend you to use sizers for a proper layout. BoxSizer are simple to play with. Here is a nice tutorial on Layout management.
Your code will work when you provide the size of the panel. Use this line panel = wx.Panel(self, -1, size=(800,800)) now you shall see all your components! I also changed the position of your static text, because it was being overlapped with the button.
Please note that you should discourage using names like panel in your code. Instead use something like myPanel or panelA etc.
Working code: Tested on Windows 8, wxPython v3.0
import wx
APP_EXIT = 1
pos1 = (150, 200)
class scoutingSet(wx.Frame):
def __init__(self, *args, **kwargs):
super(scoutingSet, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
############################################################
# MENUBARS AND MENUITEMS
menuBar = wx.MenuBar()
fileMenu = wx.Menu()
fileMenu2 = wx.Menu()
openSheet = wx.MenuItem(fileMenu, wx.ID_ANY, 'Open')
openSheet.SetBitmap(wx.Bitmap('open.png'))
fileMenu.AppendItem(openSheet)
fileMenu.AppendSeparator()
saveSheet = wx.MenuItem(fileMenu, wx.ID_ANY, 'Save')
saveSheet.SetBitmap(wx.Bitmap('save.png'))
fileMenu.AppendItem(saveSheet)
fileMenu.AppendSeparator()
quitSheet = wx.MenuItem(fileMenu, APP_EXIT, 'Quit')
quitSheet.SetBitmap(wx.Bitmap('close.png'))
fileMenu.AppendItem(quitSheet)
self.Bind(wx.EVT_MENU, self.OnQuit, id=APP_EXIT)
fileMenu2.Append(100, '&About')
self.Bind(wx.EVT_MENU, self.aboutBox, id=100)
menuBar.Append(fileMenu, 'File')
menuBar.Append(fileMenu2, 'Information')
self.SetMenuBar(menuBar)
############################################################
# BUTTONS AND CONTROL
panel = wx.Panel(self, -1, size=(800,800))
closebutton = wx.Button(panel, label = 'Close\nClose', pos = (20, 30))
closebutton.Bind(wx.EVT_BUTTON, self.OnQuit)
############################################################
# STATIC TEXTS
############################################################
# TEXT CONTROL BOXES
wx.TextCtrl(panel, pos = pos1, size = (50, 50))
wx.TextCtrl(panel, pos = (300, 400), size = (50, 50))
############################################################
# SETTINGS
self.stuff(self)
self.Maximize()
self.SetTitle('Scouting Sheet')
self.Centre()
self.Show(True)
############################################################
# Quitting
def OnQuit(self, e):
self.Close()
# Info in
def aboutBox(self, e):
desc = """This is the SOTAbots 2014 scouting sheet for the FRC 2014 game Aerial Assist"""
infoInAbout = wx.AboutDialogInfo()
infoInAbout.SetIcon(wx.Icon('scouting.png', wx.BITMAP_TYPE_PNG))
infoInAbout.SetName('Scouting Sheet')
infoInAbout.SetVersion('1.0')
infoInAbout.SetDescription(desc)
infoInAbout.AddDeveloper('Franklin Lyon\nLucas Grillos')
wx.AboutBox(infoInAbout)
def stuff(self, e):
textpnl = wx.StaticText(self,-1 , label='Watermark', pos=(100, 100))
textpnl.SetForegroundColour('white')
textpnl.SetBackgroundColour('blue')
def main():
ex = wx.App()
scoutingSet(None)
ex.MainLoop()
if __name__ == '__main__':
main()
I hope this was helpful.
I have set up a wxpython GUI that has a menu bar and some items in the menu bar. What I would like to do is select an item in my menu bar (ex. File - Options), and when i select "Options" have a dialog box pop up in which I can set different parameters in my code. Similar behaviors would be wx.FontDialog and wx.FileDialog -- However, I want mine to be custom in that i could have radio buttons and check boxes as selectable options. How do I do this?
Snippets of my code are:
Here is where I set up part of the Main application and GUI (I have layout and box sizers set up in another section):
class TMainForm(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.Splitter = wx.SplitterWindow(self, -1, style=wx.SP_3D|wx.SP_BORDER)
self.PlotPanel = wx.Panel(self.Splitter, -1)
self.FilePanel = wx.Panel(self.Splitter, -1)
#self.SelectionPanel = wx.Panel(self.Splitter,-1)
self.Notebook = wx.Notebook(self.FilePanel, -1)#, style=0)
self.ReportPage = wx.Panel(self.Notebook, -1)
self.FilePage = wx.Panel(self.Notebook, -1)
Here is where I set up part of the Menu Bar:
self.MainMenu = wx.MenuBar()
self.FileMenu = wx.Menu()
self.OptimizeMenu = wx.Menu()
self.HelpMenu = wx.Menu()
self.OptimizeOptions= wx.MenuItem(self.OptimizeMenu, 302, "&Select Parameters","Select Parameters for Optimization",wx.ITEM_NORMAL)
self.OptimizeMenu.AppendItem(self.OptimizeOptions)
self.MainMenu.Append(self.OptimizeMenu, "&Optimization")
Here is where I bind an event to my "options" part of my menu bar. When I click on this, I want a pop up menu dialog to show up
self.Bind(wx.EVT_MENU, self.OnOptimizeOptions, self.OptimizeOptions)
This is the function in which i'm hoping the pop up menu will be defined. I would like to do it in this format if possible (rather than doing separate classes).
def OnOptimizeOptions(self,event):
give me a dialog box (radio buttons, check boxes, etc)
I have only shown snippets, but all of my code does work. My GUI and menu bars are set up correctly - i just don't know how to get a pop up menu like the wx.FileDialog and wx.FontDialog menus. Any help would be great! Thanks
You would want to instantiate a dialog in your handler (OnOptimizeOptions). Basically you would subclass wx.Dialog and put in whatever widgets you want. Then you'd instantiate it in your handler and call ShowModal. Something like this psuedo-code:
myDlg = MyDialog(*args)
myDlg.ShowModal()
See the Custom Dialog part on zetcodes site: http://zetcode.com/wxpython/dialogs/ (near the bottom) for one example.
EDIT - Here's an example:
import wx
########################################################################
class MyDialog(wx.Dialog):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Dialog.__init__(self, None, title="Options")
radio1 = wx.RadioButton( self, -1, " Radio1 ", style = wx.RB_GROUP )
radio2 = wx.RadioButton( self, -1, " Radio2 " )
radio3 = wx.RadioButton( self, -1, " Radio3 " )
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(radio1, 0, wx.ALL, 5)
sizer.Add(radio2, 0, wx.ALL, 5)
sizer.Add(radio3, 0, wx.ALL, 5)
for i in range(3):
chk = wx.CheckBox(self, label="Checkbox #%s" % (i+1))
sizer.Add(chk, 0, wx.ALL, 5)
self.SetSizer(sizer)
########################################################################
class MyForm(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "wx.Menu Tutorial")
# Add a panel so it looks the correct on all platforms
self.panel = wx.Panel(self, wx.ID_ANY)
menuBar = wx.MenuBar()
fileMenu = wx.Menu()
optionsItem = fileMenu.Append(wx.NewId(), "Options",
"Show an Options Dialog")
self.Bind(wx.EVT_MENU, self.onOptions, optionsItem)
exitMenuItem = fileMenu.Append(wx.NewId(), "Exit",
"Exit the application")
self.Bind(wx.EVT_MENU, self.onExit, exitMenuItem)
menuBar.Append(fileMenu, "&File")
self.SetMenuBar(menuBar)
#----------------------------------------------------------------------
def onExit(self, event):
""""""
self.Close()
#----------------------------------------------------------------------
def onOptions(self, event):
""""""
dlg = MyDialog()
dlg.ShowModal()
dlg.Destroy()
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = MyForm().Show()
app.MainLoop()