When creating wx.ComboBox under Windows you can specify wxCB_READONLY to let users select from only proposed options. But you can clear selection by:
combo.SetSelection(wx.NOT_FOUND)
But under linux (wxGTK) the option is deselected on creation, but once selected in cannot be cleared. Not by any of following:
combo.SetSelection(wx.NOT_FOUND)
combo.SetValue('')
Is it possible to do this anyhow?
Actually, setting the value to an empty string works for me on Arch Linux:
import wx
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
choices = ["", "1", "2", "3"]
self.choices = choices
self.cbo = wx.ComboBox(self, value="1", choices=choices)
btn = wx.Button(self, label="Reset")
btn.Bind(wx.EVT_BUTTON, self.onReset)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.cbo, 0, wx.ALL, 5)
sizer.Add(btn, 0, wx.ALL, 5)
self.SetSizer(sizer)
#----------------------------------------------------------------------
def onReset(self, event):
""""""
print "resetting"
self.cbo.SetValue("")
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="CombBox")
panel = MyPanel(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Related
I am trying to use window splitter to get 6 different subwindows. Three columns and two rows. So far I am trying to use nested splitters, but it is not working.
This is the code I have:
import wx
########################################################################
class RandomPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent, color):
"""Constructor"""
wx.Panel.__init__(self, parent)
self.SetBackgroundColour(color)
########################################################################
class MainPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
topSplitter = wx.SplitterWindow(self)
vSplitter = wx.SplitterWindow(topSplitter)
panelOne = RandomPanel(vSplitter, "blue")
panelTwo = RandomPanel(vSplitter, "red")
vSplitter.SplitVertically(panelOne, panelTwo)
vSplitter.SetSashGravity(0.5)
panelThree = RandomPanel(topSplitter, "green")
topSplitter.SplitHorizontally(vSplitter, panelThree)
topSplitter.SetSashGravity(0.5)
panelFour=RandomPanel(hSplitter, "yellow")
hSplitter.SplitVertically(topSplitter, panelFour)
hSplitter.SetSashGravity(0.5)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(topSplitter, 1, wx.EXPAND)
self.SetSizer(sizer)
#
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Nested Splitters",
size=(800,600))
panel = MainPanel(self)
self.Show()
----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
app.MainLoop()
For this I am just trying to get 4 subwindows not 6, and I still get an error.
You might want to check out the MultiSplitterWindow widget:
https://wxpython.org/Phoenix/docs/html/wx.lib.splitter.MultiSplitterWindow.html
It allows you to have more than two windows in a splitter window widget. I actually wrote a bit about the various splitter windows that wxPython supports over on my blog, so you might want to check that out too.
Anyway, here is a simple example that uses that widget:
import wx
from wx.lib.splitter import MultiSplitterWindow
class SplitterPanel(wx.Panel):
def __init__(self, parent, color):
"""Constructor"""
wx.Panel.__init__(self, parent)
main_sizer = wx.BoxSizer(wx.VERTICAL)
splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
for col in range(3):
panel = wx.Panel(splitter, size=(200, 200))
panel.SetBackgroundColour(color)
splitter.AppendWindow(panel)
main_sizer.Add(splitter, 1, wx.ALL|wx.EXPAND)
self.SetSizer(main_sizer)
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='Splitters')
panel = wx.Panel(self)
main_sizer = wx.BoxSizer(wx.VERTICAL)
splitter_panel = SplitterPanel(panel, color='blue')
main_sizer.Add(splitter_panel, 1, wx.ALL|wx.EXPAND)
splitter_panel_two = SplitterPanel(panel, color='red')
main_sizer.Add(splitter_panel_two, 1, wx.ALL|wx.EXPAND)
panel.SetSizer(main_sizer)
self.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = MainFrame()
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()
I want to ask is it possible to add wx.Panel with event button in wxpython? There are plenty examples how to switch panels Hide first one and show second, but they are useless for me. I want to create panel with add button. For example I have panel something like this
import wx
import wx.grid as grid
class MainPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent = parent)
class SecondPanel(wx.Panel):
def __init__(self, parent,a,b):
wx.Panel.__init__(self, parent=parent)
MyGrid=grid.Grid(self)
MyGrid.CreateGrid(a, b)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(MyGrid, 0, wx.EXPAND)
self.SetSizer(sizer)
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="test",
size=(800,600))
self.splitter = wx.SplitterWindow(self)
self.panelOne = MainPanel(self.splitter)
self.panelTwo = SecondPanel(self.splitter, 1, 1)
txtOne = wx.StaticText(self.panelOne, -1, label = "piradoba", pos = (20,10))
self.txtTwo = wx.StaticText(self.panelOne, -1, label = "", pos = (40,80))
self.txtPlace = wx.TextCtrl(self.panelOne, pos = (20,30))
button = wx.Button(self.panelOne, label = "search", pos = (40,100))
button.Bind(wx.EVT_BUTTON, self.Onbutton)
self.splitter.SplitHorizontally(self.panelOne, self.panelTwo)
self.splitter.SetMinimumPaneSize(20)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
def Onbutton(self, event):
var=self.txtPlace.GetValue()
if len(var) == 9 or len(var) == 11:
???????????????????????????????????????????????
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
frame.Show()
app.MainLoop()
for example now I want to add new panel with this event what can I do? and I want to create this panel with event.
I don't know if it is what you need but in this example you have:
panel with button and event
button call function in mainframe
mainframe add next panel (with grid) to boxsizer
Tested on Linux Mint + Python 2.7.4
import wx
import wx.grid as grid
class MainPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent = parent)
self.txtOne = wx.StaticText(self, -1, label = "piradoba", pos = (20,10))
self.txtPlace = wx.TextCtrl(self, pos = (20,30))
self.txtTwo = wx.StaticText(self, -1, label = "", pos = (20,40))
button = wx.Button(self, label = "search", pos = (20,70))
button.Bind(wx.EVT_BUTTON, self.onButton)
def onButton(self, event):
var=self.txtPlace.GetValue()
if len(var) == 9 or len(var) == 11:
print "???"
# MainPanel->SplitterWindow->MainFrame ( 2x GetParent() )
self.GetParent().GetParent().AddPanel()
class SecondPanel(wx.Panel):
def __init__(self, parent,a,b):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
MyGrid=grid.Grid(self)
MyGrid.CreateGrid(a, b)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(MyGrid, 0, wx.EXPAND)
self.SetSizer(sizer)
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="test", size=(800,600))
self.splitter = wx.SplitterWindow(self)
self.panelOne = MainPanel(self.splitter)
self.panelTwo = SecondPanel(self.splitter, 1, 1)
self.splitter.SplitHorizontally(self.panelOne, self.panelTwo)
self.splitter.SetMinimumPaneSize(20)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.splitter, 2, wx.EXPAND)
self.SetSizer(self.sizer)
def AddPanel(self):
self.newPanel = SecondPanel(self, 1, 1)
self.sizer.Add(self.newPanel, 1, wx.EXPAND)
self.sizer.Layout()
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
frame.Show()
app.MainLoop()
In the EVT_CLOSE handler of a wxpython app, I'm trying to flush the clipboard to leave the copied text available to other applications. However, the Flush() method always returns false.
Example:
cp = wx.Clipboard.Get()
print cp.Flush()
Returns:
False
I'm using python 2.7.3 on Fedora 16 (Gnome 3 default spin) and wx.VERSION returns (2, 8, 12, 0, '')
Thanks for any help you can give me
UPDATE: Apparently it's been a "known bug" since 2009. Not sure what'll happen with it. Please add solutions if you're way into WX
I just finished creating a simple demo app and mine works. Here's my code:
import wx
########################################################################
class ClipboardPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
lbl = wx.StaticText(self, label="Enter text to copy to clipboard:")
self.text = wx.TextCtrl(self, style=wx.TE_MULTILINE)
copyBtn = wx.Button(self, label="Copy")
copyBtn.Bind(wx.EVT_BUTTON, self.onCopy)
copyFlushBtn = wx.Button(self, label="Copy and Flush")
copyFlushBtn.Bind(wx.EVT_BUTTON, self.onCopyAndFlush)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(lbl, 0, wx.ALL, 5)
sizer.Add(self.text, 1, wx.EXPAND)
sizer.Add(copyBtn, 0, wx.ALL|wx.CENTER, 5)
sizer.Add(copyFlushBtn, 0, wx.ALL|wx.CENTER, 5)
self.SetSizer(sizer)
#----------------------------------------------------------------------
def onCopy(self, event):
""""""
self.dataObj = wx.TextDataObject()
self.dataObj.SetText(self.text.GetValue())
if wx.TheClipboard.Open():
wx.TheClipboard.SetData(self.dataObj)
wx.TheClipboard.Close()
else:
wx.MessageBox("Unable to open the clipboard", "Error")
#----------------------------------------------------------------------
def onCopyAndFlush(self, event):
""""""
self.dataObj = wx.TextDataObject()
self.dataObj.SetText(self.text.GetValue())
if wx.TheClipboard.Open():
wx.TheClipboard.SetData(self.dataObj)
wx.TheClipboard.Flush()
else:
wx.MessageBox("Unable to open the clipboard", "Error")
self.GetParent().Close()
########################################################################
class ClipboardFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Clipboard Tutorial")
panel = ClipboardPanel(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = ClipboardFrame()
app.MainLoop()
I'm on Windows 7, wxPython 2.8.12 and Python 2.6.6. What are you on? Does this code work for you?
with this code:
import wx
import wx.aui
class MyFrame(wx.Frame):
def __init__(self, parent, id=-1, title='wx.aui Test',
pos=wx.DefaultPosition, size=(800, 600),
style=wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent, id, title, pos, size, style)
self._mgr = wx.aui.AuiManager(self)
# create several text controls
text1 = wx.TextCtrl(self, -1, 'Pane 1 - sample text',
wx.DefaultPosition, wx.Size(200,150),
wx.NO_BORDER | wx.TE_MULTILINE)
text2 = wx.TextCtrl(self, -1, 'Pane 2 - sample text',
wx.DefaultPosition, wx.Size(200,150),
wx.NO_BORDER | wx.TE_MULTILINE)
info = wx.aui.AuiPaneInfo()
info.CaptionVisible(True)
info.BottomDockable(False)
info.LeftDockable(False)
info.RightDockable(False)
info.PaneBorder(False)
info.Top()
info.Row(1)
info2 = wx.aui.AuiPaneInfo()
info2.CaptionVisible(True)
info2.BottomDockable(False)
info2.LeftDockable(False)
info2.RightDockable(False)
info2.Top()
info2.Row(2)
self._mgr.AddPane(text1, info, 'Pane Number One')
self._mgr.AddPane(text2, info2, 'Pane Number Two')
self._mgr.Update()
self.Bind(wx.EVT_CLOSE, self.OnClose)
def OnClose(self, event):
self._mgr.UnInit()
self.Destroy()
app = wx.App()
frame = MyFrame(None)
frame.Show()
app.MainLoop()
the two panes that I create are docked in the Top.
The info.Row(1) and info2.Row(2) put the two panes one after another:
_TOP_
Pane1
Pane2
Now, if I move on Pane2, this docks in the Top and this situation occurs:
_TOP_
Pane1|Pane2
I want:
1. to avoid this situation (only one pane per row!)
2. if I move, dock the pane in the bottom/top of another pane
Is this possible?
Maybe the AuiNotebook wxPython sample works for you?
import wx
import wx.aui
########################################################################
class TabPanel(wx.Panel):
"""
This will be the first notebook tab
"""
#----------------------------------------------------------------------
def __init__(self, parent):
""""""
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
sizer = wx.BoxSizer(wx.VERTICAL)
txtOne = wx.TextCtrl(self, wx.ID_ANY, "")
txtTwo = wx.TextCtrl(self, wx.ID_ANY, "")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(txtOne, 0, wx.ALL, 5)
sizer.Add(txtTwo, 0, wx.ALL, 5)
self.SetSizer(sizer)
class DemoPanel(wx.Panel):
"""
This will be the first notebook tab
"""
#----------------------------------------------------------------------
def __init__(self, parent):
""""""
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
# create the AuiNotebook instance
nb = wx.aui.AuiNotebook(self)
# add some pages to the notebook
pages = [(TabPanel(nb), "Tab 1"),
(TabPanel(nb), "Tab 2"),
(TabPanel(nb), "Tab 3")]
for page, label in pages:
nb.AddPage(page, label)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(nb, 1, wx.EXPAND)
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,
"AUI-Notebook Tutorial",
size=(600,400))
panel = DemoPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = DemoFrame()
app.MainLoop()