I have wxpython app that open wx.DirDialog on button click.
dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE)
if dlg.ShowModal() == wx.ID_OK:
# Do some stuff
Since my application is multithreaded and uses wxTaskbaricon which allow user (on Win 7) to close application even when modal DirDialog is open, I want to close the DirDialog before closing main app. Somehow non of below method work:
dlg.Destroy()
dlg.Close(True)
It is my testing code.
I can test Destroy(), Close() and EndModal() on Modal and Non-Modal wx.DirDialog()
To close modal dialog I had to use Timer - because modal dialog is blocking access to the main window.
It can't close dialog only if I do
self.dlg = None
self.dlg.EndModal(wx.CANCEL) # or Destroy() or Close(True)
And one more thing - I use Linux Mint 15, Python 2.7.4, wxPython 2.8.12.1 :)
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import wx
import sys # to get python version
#----------------------------------------------------------------------
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(600,100))
self.panel = wx.Panel(self)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.panel.SetSizer(self.sizer)
self.label = wx.StaticText(self.panel, label="Python "+sys.version+"\nwxPython"+wx.version())
self.button1 = wx.Button(self.panel, label="On")
self.button2 = wx.Button(self.panel, label="Off")
self.sizer.Add(self.label)
self.sizer.Add(self.button1)
self.sizer.Add(self.button2)
self.Bind(wx.EVT_BUTTON, self.OpenDialog, self.button1)
self.Bind(wx.EVT_BUTTON, self.CloseDialog, self.button2)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.TimerCloseDialog, self.timer)
self.Show(True)
self.dlg = None
def OpenDialog(self, event):
print "OpenDialog"
self.timer.Start(3000, oneShot=True)
print "wait 3s ..."
if not self.dlg:
self.dlg = wx.DirDialog(self)
self.dlg.ShowModal()
#self.dlg.Show(True)
def CloseDialog(self, event):
print "CloseDialog"
if self.dlg:
#self.dlg = None
#self.dlg.EndModal(wx.CANCEL)
self.dlg.Destroy()
#self.dlg.Close(True)
def TimerCloseDialog(self, event):
print "TimerCloseDialog"
if self.dlg:
#self.dlg = None
self.dlg.EndModal(wx.CANCEL)
#self.dlg.Destroy()
#self.dlg.Close(True)
#----------------------------------------------------------------------
print "Python", sys.version
print "wxPython", wx.version()
app = wx.App()
frame = MyFrame(None, "Hello Dialog")
app.MainLoop()
Related
for a pet project of mine I am using a wxPython 2.8 and I have a dialog with a disabled wx.TextCtrl:
self.txt = wx.TextCtrl(self, wx.ID_ANY, size=(450,100),
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
in the same dialog there is a button; when button is clicked I want to append some text (programmatically) to the TextCtrl. I tried by using
self.txt.AppendText('Hello')
but it doesn't work (Windows XP OS).
Is there any way to do that ?
thanks
You can use the wx.TextCtrl write function to achieve that.
import wx
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='Test TextCtrl')
self.panel = wx.Panel(self)
self.text1 = wx.TextCtrl(self.panel,value="My Text",pos=(10,10),size=(350,30))
self.button = wx.Button(self.panel, -1, "Click",pos=(10,40))
self.button.Bind(wx.EVT_BUTTON, self.On_Button)
self.text1.Enable(False)
self.Show()
def On_Button(self, event):
self.text1.write(" Click ")
if __name__ == '__main__':
app = wx.App()
frame = MainFrame()
app.MainLoop()
This is the code that i have written. It does close the window but doesnt display the text in it. I need the text displayed and then automatic close of the window.
What changes should i make for it to work
Thanks
Here is the code
import wx
from time import sleep
class Frame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, size=(300,200))
self.panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
m_text = wx.StaticText(self.panel, -1, 'File Uploaded!')
m_text.SetSize(m_text.GetBestSize())
box.Add(m_text, 0, wx.ALL, 10)
self.panel.SetSizer(box)
self.panel.Layout()
self.Bind(wx.EVT_ACTIVATE, self.onClose)
def onClose(self, event):
sleep(5)
self.Destroy()
app = wx.App(redirect=True)
top = Frame('test')
top.Show()
app.MainLoop()
I would recommend using a wx.Timer. If you use time.sleep(), you will block wxPython's main loop which makes your application unresponsive. Here is your code modified to use the timer:
import wx
class Frame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, size=(300,200))
self.panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
m_text = wx.StaticText(self.panel, -1, 'File Uploaded!')
m_text.SetSize(m_text.GetBestSize())
box.Add(m_text, 0, wx.ALL, 10)
self.panel.SetSizer(box)
self.panel.Layout()
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.onClose, self.timer)
self.timer.Start(5000)
def onClose(self, event):
self.Close()
app = wx.App(redirect=True)
top = Frame('test')
top.Show()
app.MainLoop()
You can read more about timers in this article:
http://www.blog.pythonlibrary.org/2009/08/25/wxpython-using-wx-timers/
>>> import wx
>>> import time
>>> app = wx.App()
>>> b = wx.BusyInfo('Upload Finished!')
>>> time.sleep(5)
>>> del b
>>>
The code is only used to write a simple UI( there is only a textbox on the window), and bind the event wx.EVT_KEY_DOWN to the function OnKeyDown, but when I pressed the Esc key, the window will pop up Esc, Test, then another Esc, Test, finally it will exit after the four message box, why? I only define two message box int the wx.WXK_ESCAPE bindings.
# -*- coding: utf-8 -*-
import wx
class Command(wx.Frame):
def __init__(self, parent, title):
super(Command, self).__init__(parent, title=title,
size=(600, 500))
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
pnl = wx.Panel(self)
self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyDown)
hbox = wx.BoxSizer(wx.HORIZONTAL)
self.__tc_command = wx.TextCtrl(pnl, style=wx.TE_MULTILINE)
self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyDown)
hbox.Add(self.__tc_command, proportion=1, flag=wx.ALL|wx.EXPAND, border=15)
pnl.SetSizer(hbox)
def OnKeyDown(self, evt):
"""Enter to send data, Esc to exit."""
key = evt.GetKeyCode()
if key == wx.WXK_ESCAPE:
##################Only two MessageBox, but pop up four##################
wx.MessageBox("Esc")
wx.MessageBox("Test")
##################Only two MessageBox, but pop up four##################
self.Close()
if key == wx.WXK_RETURN:
wx.MessageBox("Enter")
evt.Skip()
if __name__ == '__main__':
app = wx.App(redirect=False)
Command(None, title='Command')
app.MainLoop()
You are calling self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyDown) twice in your code.
Hi, everyone.
I have a little python GUI program based on wxPython 2.8.x.
It create a wx.Dialog widget and show the dialog by calling ShowModal().
At some situation, the wx.Dialog will show a wx.PopupWindow with a wx.ListCtrl locate inside.
The wx.PopupWindow appears correctly, but trouble comes.
wx.ListCtrl, and its parent widget, wx.PopupWindow, couldn't receive any mouse event,
this cause wx.ListCtrl and wx.PopupWindow have no response while user generate any mouse action.
If wx.Dialog is opened by calling Show(),the above situation won't happen, wx.PopupWindow and wx.ListCtrl work correctly.
However, the above situation won't happen in windows version of wxPython 2.8.x even if we show wx.Dialog by calling ShowModal(),it happen in linux only.
Any suggestion?
Thanks.
Here is my source code.
It may be too long but is easy enough to test the above situation (just copy and paste).
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import wx
class TestPopupWindow(wx.PopupWindow): # modify here to change different Widget
def __init__(self, *args, **kwargs):
super(TestPopupWindow, self).__init__(*args, **kwargs)
self.SetSize((200, 200))
self.testButton = wx.Button(self, label='Test')
self.testButton.Bind(wx.EVT_BUTTON, self.__onEvtButton, self.testButton)
self.Show()
def __onEvtButton(self, event):
event.Skip()
print 'PopupWindow: test button pushed!'
self.Hide()
class TestDialog(wx.Dialog):
def __init__(self, *args, **kwargs):
wx.Dialog.__init__(self, *args, **kwargs)
panel = wx.Panel(self)
panel.SetAutoLayout(True)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Fit(panel)
sizer.SetSizeHints(panel)
panel.SetSizer(sizer)
for i in xrange(2):
ctrl = wx.TextCtrl(panel)
sizer.Add(ctrl, 0, wx.ADJUST_MINSIZE|wx.EXPAND, 0)
for i in xrange(2):
ctrl = wx.ComboBox(panel)
sizer.Add(ctrl, 0, wx.ADJUST_MINSIZE|wx.EXPAND, 0)
self.openPopupWindowButton = wx.Button(panel, label='Open PopupWindow')
sizer.Add(self.openPopupWindowButton, 0, 0, 0)
standardDialogButtonSizer = wx.StdDialogButtonSizer()
self.standardDialogButtonSizerOK = wx.Button(panel, wx.ID_OK)
standardDialogButtonSizer.AddButton(self.standardDialogButtonSizerOK)
self.standardDialogButtonSizerCancel = wx.Button(panel, wx.ID_CANCEL)
standardDialogButtonSizer.AddButton(self.standardDialogButtonSizerCancel)
standardDialogButtonSizer.Realize()
sizer.Add(standardDialogButtonSizer, 0, wx.EXPAND, 0)
panel.Layout()
# event binding
self.openPopupWindowButton.Bind(wx.EVT_BUTTON, self.__onEvtButtonOpenPopupWindow, self.openPopupWindowButton)
self.popupWindow = None
# event handler
def __onEvtButtonOpenPopupWindow(self, event):
event.Skip()
if self.popupWindow is not None:
self.popupWindow.Close()
self.popupWindow = TestPopupWindow(self)
class TestFrame(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
panel = wx.Panel(self)
panel.SetAutoLayout(True)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Fit(panel)
sizer.SetSizeHints(panel)
panel.SetSizer(sizer)
self.openButton = wx.Button(panel, label='Open Dialog')
sizer.Add(self.openButton, 0, 0, 0)
self.openPopupWindowButton = wx.Button(panel, label='Open PopupWindow')
sizer.Add(self.openPopupWindowButton, 0, 0, 0)
panel.Layout()
# event binding
self.openButton.Bind(wx.EVT_BUTTON, self.__onEvtButtonOpen, self.openButton)
self.openPopupWindowButton.Bind(wx.EVT_BUTTON, self.__onEvtButtonOpenPopupWindow, self.openPopupWindowButton)
self.Show()
self.popupWindow = None
# event handler
def __onEvtButtonOpenPopupWindow(self, event):
event.Skip()
if self.popupWindow is not None:
self.popupWindow.Close()
self.popupWindow = TestPopupWindow(self)
def __onEvtButtonOpen(self, event):
event.Skip()
dialog = TestDialog(self, title='TestDialog')
result = dialog.ShowModal()
if result == wx.ID_OK:
print >>sys.stderr, 'OK!'
else:
print >>sys.stderr, 'Cancel!'
def main(argv=sys.argv[:]):
app = wx.PySimpleApp()
frame = TestFrame(None, title='TestFrame', style=wx.TAB_TRAVERSAL|wx.DEFAULT_FRAME_STYLE)
app.SetTopWindow(frame)
app.MainLoop()
return 0
if __name__ == '__main__':
sys.exit(main())
Instead of using a PopupWindow, just show a second wx.Dialog. Or open a frame. PopupWindows can be kind of weird with complex widgets like the ListCtrl.
What event is used when I close a tab in an auinotebook? I tested with
EVT_AUINOTEBOOK_PAGE_CLOSE(D). It didn't work.
I would also like to fire a right click on the tab itself event.
Where can I find all the events that can be used with the aui manager/notebook? Might just be my poor searching skills, but I can't find any lists over the different events that exist, not for mouse/window events either. It would be really handy to have a complete list.
#!/usr/bin/python
#12_aui_notebook1.py
import wx
import wx.lib.inspection
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.nb = wx.aui.AuiNotebook(self)
self.new_panel('Page 1')
self.new_panel('Page 2')
self.new_panel('Page 3')
self.nb.Bind(wx.EVT_AUINOTEBOOK_PAGE_CLOSED, self.close)
def new_panel(self, nm):
pnl = wx.Panel(self)
pnl.identifierTag = nm
self.nb.AddPage(pnl, nm)
self.sizer = wx.BoxSizer()
self.sizer.Add(self.nb, 1, wx.EXPAND)
self.SetSizer(self.sizer)
def close(self, event):
print 'closed'
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, '12_aui_notebook1.py')
frame.Show()
self.SetTopWindow(frame)
return 1
if __name__ == "__main__":
app = MyApp(0)
# wx.lib.inspection.InspectionTool().Show()
app.MainLoop()
Oerjan Pettersen
This is the bind command you want:
self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSED, self.close, self.nb)
To detect a right click on the tab (e.g. to show a custom context menu):
self.Bind(wx.aui.EVT_AUINOTEBOOK_TAB_RIGHT_DOWN, self.right, self.nb)
Here's a list of the aui notebook events:
EVT_AUINOTEBOOK_PAGE_CLOSE
EVT_AUINOTEBOOK_PAGE_CLOSED
EVT_AUINOTEBOOK_PAGE_CHANGED
EVT_AUINOTEBOOK_PAGE_CHANGING
EVT_AUINOTEBOOK_BUTTON
EVT_AUINOTEBOOK_BEGIN_DRAG
EVT_AUINOTEBOOK_END_DRAG
EVT_AUINOTEBOOK_DRAG_MOTION
EVT_AUINOTEBOOK_ALLOW_DND
EVT_AUINOTEBOOK_DRAG_DONE
EVT_AUINOTEBOOK_BG_DCLICK
EVT_AUINOTEBOOK_TAB_MIDDLE_DOWN
EVT_AUINOTEBOOK_TAB_MIDDLE_UP
EVT_AUINOTEBOOK_TAB_RIGHT_DOWN
EVT_AUINOTEBOOK_TAB_RIGHT_UP
From: {python folder}/Lib/site-packages/{wxpython folder}/wx/aui.py