├── .gitignore
├── README.md
├── recipe_10_catching_exceptions
├── error.log
├── exception_catcher.py
├── exception_decorator.py
├── exception_decorator2.py
└── exception_decorator3.py
├── recipe_11_context_managers
├── builtin_context.py
└── custom_context.py
├── recipe_12_converting_dates
└── README.txt
├── recipe_13_about_box
├── main_classic.py
└── main_phoenix.py
├── recipe_14_login_dialog
├── main_flag.py
└── main_pubsub.py
├── recipe_15_dialog_from_config
├── config.ini
└── main.py
├── recipe_16_saving_configs
├── controller.py
├── example.ini
├── images
│ ├── cancel.png
│ └── filesave.png
└── main.py
├── recipe_17_binding_multiple_events
└── main.py
├── recipe_18_firing_multiple_handlers
└── main.py
├── recipe_19_get_event_name
└── main.py
├── recipe_1_add_widgets_dynamically
└── dynamic_widgets.py
├── recipe_20_key_char_events
├── char_events.py
├── key_events.py
└── key_events2.py
├── recipe_21_drag_n_drop
├── drag_and_drop_app.py
├── file_drop_target.py
├── py_drop_target.py
└── text_drop_target.py
├── recipe_22_drag_n_drop_file_to_os
└── main.py
├── recipe_23_edit_gui_interactively
├── main.py
└── testApp.py
├── recipe_24_extracting_xml_from_richtextctrl
├── main_classic.py
└── main_phoenix.py
├── recipe_25_fade_in
└── main.py
├── recipe_26_flashing_text
├── changing_text.py
└── flashing_text.py
├── recipe_27_maximizing_frame
├── fullscreen.py
└── maximize.py
├── recipe_28_frame_styles
├── default_frame.py
├── default_frame_2.py
├── default_frame_3.py
├── disabled_close_btn.py
├── no_caption.py
├── no_max_min.py
├── no_resize.py
├── no_system_menu.py
└── stay_on_top.py
├── recipe_29_taskbar_icons
├── main_classic.py
├── main_phoenix.py
└── python.ico
├── recipe_2_screenshots
├── main.py
├── myImage.png
├── screenshot.htm
└── snapshotPrinter.py
├── recipe_30_minimize_to_tray
├── custTray.py
├── custTray_phoenix.py
├── main_classic.py
├── main_phoenix.py
└── python.ico
├── recipe_31_children_from_sizers
└── main.py
├── recipe_32_clipboard
└── main.py
├── recipe_33_focus
├── acquire_focus.py
├── acquire_focus_2.py
├── focus_finder.py
└── losing_focus.py
├── recipe_34_url_shortening
├── ars_example.py
├── ars_example_py3.py
└── shortening_py2.py
├── recipe_35_using_objectlistview
└── main.py
├── recipe_36_panel_destruction
└── main.py
├── recipe_37_panel_switching
└── main.py
├── recipe_38_pyplot
├── bar_graph.py
├── data.txt
├── plotting_25000_points.py
├── plotting_saved_data.py
└── sin_cos.py
├── recipe_39_logging_textctrl
└── main.py
├── recipe_3_embedding_image
├── custom_icon.py
├── image_from_exe.py
├── img_from_python_code.py
├── my_icon.py
└── py.ico
├── recipe_40_redirect_stdout
├── main_non_thread_safe.py
├── main_non_thread_safe_phoenix.py
└── main_thread_safe.py
├── recipe_41_simple_notebook
├── simple.py
└── simple_refactored.py
├── recipe_42_singleton_frame
└── main.py
├── recipe_43_storing_objects
├── objects_in_combobox.py
└── objects_in_listbox.py
├── recipe_44_syncing_grid_scroll
└── main.py
├── recipe_45_timers
├── multiple_timers.py
├── multiple_timers_2.py
├── simple_timer.py
└── simple_timer_2.py
├── recipe_46_update_progress_thread
├── main_2.8.py
└── main_3.0.py
├── recipe_47_wx_and_threads
├── main.py
├── main_legacy.py
└── post_event_example.py
├── recipe_48_updating_your_app
└── Releases
│ ├── image_viewer-0.0.1
│ ├── main.py
│ ├── mondrian.icns
│ ├── mondrian.ico
│ ├── setup.py
│ └── version.py
│ └── image_viewer-0.0.2
│ ├── main.py
│ ├── mondrian.icns
│ ├── mondrian.ico
│ ├── setup.py
│ └── version.py
├── recipe_49_xrc
├── login.py
├── login.xrc
├── notebook.xrc
├── notebook2.xrc
├── notebookXrcDemo.py
├── notebookXrcDemo2.py
├── panelOne.xrc
└── panelTwo.xrc
├── recipe_4_background_image
├── big_cat.jpg
├── daniweb_example.py
└── main.py
├── recipe_50_xrc_grid
├── broken_grid.py
├── grid.xrc
└── working_grid.py
├── recipe_51_xrced
├── first_app.py
├── notebook.xrc
├── notebook_example.py
├── twoBtns.xrc
├── twoBtns_xrc.py
└── twoBtns_xrc_subclass.py
├── recipe_52_centering_widgets
├── faux_spacers.py
├── nested_sizers.py
└── stretch_spacer.py
├── recipe_53_widget_wrapping
└── main.py
├── recipe_54_getting_selected_cells
└── main.py
├── recipe_5_resetting_background_color
└── main.py
├── recipe_6_dark_mode
├── __pycache__
│ └── dark_mode.cpython-35.pyc
├── dark_mode.py
└── main.py
├── recipe_7_pubsub
└── main.py
├── recipe_8_pydispatcher
└── main.py
└── recipe_9_disable_wizard_next
├── main_classic.py
└── main_phoenix.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.wpr
2 | *.wpu
3 | *.pyc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # wxPython Cookbook Code Examples
2 |
3 | The code examples for the book: **wxPython Cookbook**
4 |
5 | The book itself can be purchased through [Gumroad](http://gum.co/wxcookbook) or on [Leanpub](https://leanpub.com/wxpythoncookbook/).
6 |
7 | [
](https://leanpub.com/wxpythoncookbook/)
--------------------------------------------------------------------------------
/recipe_10_catching_exceptions/error.log:
--------------------------------------------------------------------------------
1 | 2016-11-23 14:36:01,869 - testLogger - Exception in onExcept:
2 | Traceback (most recent call last):
3 | File "/home/mdriscoll/py/wxcook/wxpythoncookbookcode/recipe_10_catching_exceptions/exception_decorator3_classic.py", line 20, in logger_func
4 | return func(*args)
5 | File "/home/mdriscoll/py/wxcook/wxpythoncookbookcode/recipe_10_catching_exceptions/exception_decorator3_classic.py", line 60, in onExcept
6 | 1/0
7 | ZeroDivisionError: integer division or modulo by zero
8 | 2016-12-04 20:28:37,165 - wxErrors - Exception
9 | Traceback (most recent call last):
10 | File "c:\Users\mike\Dropbox\Documents\wxpython_cookbook\wxpythoncookbookcode\recipe_10_catching_exceptions\exception_decorator2.py", line 20, in __call__
11 | self.fn(self, *args, **kwargs)
12 | File "c:\Users\mike\Dropbox\Documents\wxpython_cookbook\wxpythoncookbookcode\recipe_10_catching_exceptions\exception_decorator2.py", line 40, in onExcept
13 | 1/0
14 | ZeroDivisionError: integer division or modulo by zero
15 | 2016-12-04 20:28:50,894 - testLogger - Exception in onExcept:
16 | Traceback (most recent call last):
17 | File "c:\Users\mike\Dropbox\Documents\wxpython_cookbook\wxpythoncookbookcode\recipe_10_catching_exceptions\exception_decorator3.py", line 20, in logger_func
18 | return func(*args)
19 | File "c:\Users\mike\Dropbox\Documents\wxpython_cookbook\wxpythoncookbookcode\recipe_10_catching_exceptions\exception_decorator3.py", line 60, in onExcept
20 | 1/0
21 | ZeroDivisionError: integer division or modulo by zero
22 | 2016-12-04 20:29:04,861 - wxErrors - Exception
23 | Traceback (most recent call last):
24 | File "c:\Users\mike\Dropbox\Documents\wxpython_cookbook\wxpythoncookbookcode\recipe_10_catching_exceptions\exception_decorator.py", line 22, in __call__
25 | self.fn(self, evt)
26 | File "c:\Users\mike\Dropbox\Documents\wxpython_cookbook\wxpythoncookbookcode\recipe_10_catching_exceptions\exception_decorator.py", line 42, in onExcept
27 | 1/0
28 | ZeroDivisionError: integer division or modulo by zero
29 |
--------------------------------------------------------------------------------
/recipe_10_catching_exceptions/exception_catcher.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import traceback
3 | import wx
4 | import wx.lib.agw.genericmessagedialog as GMD
5 |
6 |
7 | class Panel(wx.Panel):
8 | """"""
9 |
10 | def __init__(self, parent):
11 | """Constructor"""
12 | wx.Panel.__init__(self, parent)
13 |
14 | btn = wx.Button(self, label="Raise Exception")
15 | btn.Bind(wx.EVT_BUTTON, self.onExcept)
16 |
17 | def onExcept(self, event):
18 | """
19 | Raise an error
20 | """
21 | 1/0
22 |
23 |
24 | class Frame(wx.Frame):
25 | """"""
26 |
27 | def __init__(self):
28 | """Constructor"""
29 | wx.Frame.__init__(self, None, title="Exceptions")
30 | sys.excepthook = MyExceptionHook
31 | panel = Panel(self)
32 | self.Show()
33 |
34 |
35 | class ExceptionDialog(GMD.GenericMessageDialog):
36 | """
37 | The dialog to show an exception
38 | """
39 |
40 | def __init__(self, msg):
41 | """Constructor"""
42 | GMD.GenericMessageDialog.__init__(self, None, msg, "Exception!",
43 | wx.OK|wx.ICON_ERROR)
44 |
45 |
46 | def MyExceptionHook(etype, value, trace):
47 | """
48 | Handler for all unhandled exceptions.
49 |
50 | :param `etype`: the exception type (`SyntaxError`, `ZeroDivisionError`, etc...);
51 | :type `etype`: `Exception`
52 | :param string `value`: the exception error message;
53 | :param string `trace`: the traceback header, if any (otherwise, it prints the
54 | standard Python header: ``Traceback (most recent call last)``.
55 | """
56 | frame = wx.GetApp().GetTopWindow()
57 | tmp = traceback.format_exception(etype, value, trace)
58 | exception = "".join(tmp)
59 |
60 | dlg = ExceptionDialog(exception)
61 | dlg.ShowModal()
62 | dlg.Destroy()
63 |
64 |
65 | if __name__ == "__main__":
66 | app = wx.App(False)
67 | frame = Frame()
68 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_10_catching_exceptions/exception_decorator.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import wx
3 |
4 |
5 | class ExceptionLogging(object):
6 |
7 | def __init__(self, fn):
8 | self.fn = fn
9 |
10 | # create logging instance
11 | self.log = logging.getLogger("wxErrors")
12 | self.log.setLevel(logging.INFO)
13 |
14 | # create a logging file handler / formatter
15 | log_fh = logging.FileHandler("error.log")
16 | formatter = logging.Formatter("%(asctime)s - %(name)s - %(message)s")
17 | log_fh.setFormatter(formatter)
18 | self.log.addHandler(log_fh)
19 |
20 | def __call__(self, evt):
21 | try:
22 | self.fn(self, evt)
23 | except Exception as e:
24 | self.log.exception("Exception")
25 |
26 |
27 | class Panel(wx.Panel):
28 | """"""
29 |
30 | def __init__(self, parent):
31 | """Constructor"""
32 | wx.Panel.__init__(self, parent)
33 |
34 | btn = wx.Button(self, label="Raise Exception")
35 | btn.Bind(wx.EVT_BUTTON, self.onExcept)
36 |
37 | @ExceptionLogging
38 | def onExcept(self, event):
39 | """
40 | Raise an error
41 | """
42 | 1/0
43 |
44 |
45 | class Frame(wx.Frame):
46 | """"""
47 |
48 | def __init__(self):
49 | """Constructor"""
50 | wx.Frame.__init__(self, None, title="Exceptions")
51 | panel = Panel(self)
52 | self.Show()
53 |
54 |
55 | if __name__ == "__main__":
56 | app = wx.App(False)
57 | frame = Frame()
58 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_10_catching_exceptions/exception_decorator2.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import wx
3 |
4 | class ExceptionLogging(object):
5 | def __init__(self, fn, *args, **kwargs):
6 | self.fn = fn
7 |
8 | # create logging instance
9 | self.log = logging.getLogger("wxErrors")
10 | self.log.setLevel(logging.INFO)
11 |
12 | # create a logging file handler / formatter
13 | log_fh = logging.FileHandler("error.log")
14 | formatter = logging.Formatter("%(asctime)s - %(name)s - %(message)s")
15 | log_fh.setFormatter(formatter)
16 | self.log.addHandler(log_fh)
17 |
18 | def __call__(self, *args, **kwargs):
19 | try:
20 | self.fn(self, *args, **kwargs)
21 | except Exception as e:
22 | self.log.exception("Exception")
23 |
24 |
25 | class Panel(wx.Panel):
26 | """"""
27 |
28 | def __init__(self, parent):
29 | """Constructor"""
30 | wx.Panel.__init__(self, parent)
31 |
32 | btn = wx.Button(self, label="Raise Exception")
33 | btn.Bind(wx.EVT_BUTTON, self.onExcept)
34 |
35 | @ExceptionLogging
36 | def onExcept(self, event):
37 | """
38 | Raise an error
39 | """
40 | 1/0
41 |
42 |
43 | class Frame(wx.Frame):
44 | """"""
45 |
46 | def __init__(self):
47 | """Constructor"""
48 | wx.Frame.__init__(self, None, title="Exceptions")
49 | panel = Panel(self)
50 | self.Show()
51 |
52 |
53 | if __name__ == "__main__":
54 | app = wx.App(False)
55 | frame = Frame()
56 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_10_catching_exceptions/exception_decorator3.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | import logging
4 | import wx
5 |
6 | print(wx.version())
7 |
8 | def exceptionLogger(func, loggerName=''):
9 | """
10 | A simple decorator that will catch and log any exceptions that may occur
11 | to the root logger.
12 | """
13 | assert callable(func)
14 | mylogger = logging.getLogger(loggerName)
15 |
16 | # wrap a new function around the callable
17 | def logger_func(*args, **kw):
18 | try:
19 | if not kw:
20 | return func(*args)
21 | return func(*args, **kw)
22 | except Exception:
23 | mylogger.exception('Exception in %s:', func.__name__)
24 |
25 | logger_func.__name__ = func.__name__
26 | logger_func.__doc__ = func.__doc__
27 | if hasattr(func, '__dict__'):
28 | logger_func.__dict__.update(func.__dict__)
29 | return logger_func
30 |
31 |
32 | def exceptionLog2Logger(loggerName):
33 | """
34 | A decorator that will catch and log any exceptions that may occur
35 | to the named logger.
36 | """
37 | import functools
38 | return functools.partial(exceptionLogger, loggerName=loggerName)
39 |
40 |
41 | class Panel(wx.Panel):
42 | """"""
43 |
44 | def __init__(self, parent):
45 | """Constructor"""
46 | wx.Panel.__init__(self, parent)
47 |
48 | btn = wx.Button(self, label="Raise Exception")
49 | btn.Bind(wx.EVT_BUTTON, self.onExcept)
50 |
51 | @exceptionLog2Logger('testLogger')
52 | def onExcept(self, event):
53 | """
54 | Raise an error
55 | """
56 | print(self, event)
57 | print(isinstance(self, wx.Panel))
58 |
59 | # trigger an exception
60 | 1/0
61 |
62 |
63 | class Frame(wx.Frame):
64 | """"""
65 |
66 | def __init__(self):
67 | """Constructor"""
68 | wx.Frame.__init__(self, None, title="Exceptions")
69 | panel = Panel(self)
70 | self.Show()
71 |
72 |
73 | if __name__ == "__main__":
74 |
75 | # set up the default logger
76 | log = logging.getLogger('testLogger')
77 | log.setLevel(logging.INFO)
78 |
79 | # create a logging file handler / formatter
80 | log_fh = logging.FileHandler("error.log")
81 | formatter = logging.Formatter("%(asctime)s - %(name)s - %(message)s")
82 | log_fh.setFormatter(formatter)
83 | log.addHandler(log_fh)
84 |
85 | app = wx.App(False)
86 | frame = Frame()
87 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_11_context_managers/builtin_context.py:
--------------------------------------------------------------------------------
1 | import time
2 | import wx
3 |
4 |
5 | class MyPanel(wx.Panel):
6 | """"""
7 |
8 | def __init__(self, parent):
9 | """Constructor"""
10 | wx.Panel.__init__(self, parent)
11 | self.frame = parent
12 |
13 | main_sizer = wx.BoxSizer(wx.VERTICAL)
14 |
15 | dlg_btn = wx.Button(self, label='Open ColorDialog')
16 | dlg_btn.Bind(wx.EVT_BUTTON, self.onOpenColorDialog)
17 | main_sizer.Add(dlg_btn, 0, wx.ALL|wx.CENTER)
18 |
19 | busy_btn = wx.Button(self, label='Open BusyInfo')
20 | busy_btn.Bind(wx.EVT_BUTTON, self.onOpenBusyInfo)
21 | main_sizer.Add(busy_btn,0, wx.ALL|wx.CENTER)
22 |
23 | self.SetSizer(main_sizer)
24 |
25 | def onOpenColorDialog(self, event):
26 | """
27 | Creates and opens the wx.ColourDialog
28 | """
29 | with wx.ColourDialog(self) as dlg:
30 | if dlg.ShowModal() == wx.ID_OK:
31 | data = dlg.GetColourData()
32 | color = str(data.GetColour().Get())
33 | print 'You selected: %s\n' % color
34 |
35 | def onOpenBusyInfo(self, event):
36 | """
37 | Creates and opens an instance of BusyInfo
38 | """
39 | msg = 'This app is busy right now!'
40 | self.frame.Hide()
41 | with wx.BusyInfo(msg) as busy:
42 | time.sleep(5)
43 | self.frame.Show()
44 |
45 |
46 | class MyFrame(wx.Frame):
47 | """"""
48 |
49 | def __init__(self):
50 | """Constructor"""
51 | wx.Frame.__init__(self, None, title='Context Managers')
52 | panel = MyPanel(self)
53 |
54 | self.Show()
55 |
56 |
57 | if __name__ == '__main__':
58 | app = wx.App(False)
59 | frame = MyFrame()
60 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_11_context_managers/custom_context.py:
--------------------------------------------------------------------------------
1 | import os
2 | import wx
3 |
4 |
5 | class ContextFileDialog(wx.FileDialog):
6 | """"""
7 |
8 | def __enter__(self):
9 | """"""
10 | return self
11 |
12 | def __exit__(self, exc_type, exc_val, exc_tb):
13 | self.Destroy()
14 |
15 |
16 | class MyPanel(wx.Panel):
17 | """"""
18 |
19 | def __init__(self, parent):
20 | """Constructor"""
21 | wx.Panel.__init__(self, parent)
22 |
23 | btn = wx.Button(self, label='Open File')
24 | btn.Bind(wx.EVT_BUTTON, self.onOpenFile)
25 |
26 | def onOpenFile(self, event):
27 | """"""
28 | wildcard = "Python source (*.py)|*.py|" \
29 | "All files (*.*)|*.*"
30 | kwargs = {'message':"Choose a file",
31 | 'defaultDir':os.path.dirname(os.path.abspath( __file__ )),
32 | 'defaultFile':"",
33 | 'wildcard':wildcard,
34 | 'style':wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR
35 | }
36 | with ContextFileDialog(self, **kwargs) as dlg:
37 | if dlg.ShowModal() == wx.ID_OK:
38 | paths = dlg.GetPaths()
39 | print "You chose the following file(s):"
40 | for path in paths:
41 | print path
42 |
43 |
44 | class MyFrame(wx.Frame):
45 | """"""
46 |
47 | def __init__(self):
48 | """Constructor"""
49 | wx.Frame.__init__(self, None, title='wxPython Contexts')
50 | panel = MyPanel(self)
51 | self.Show()
52 |
53 |
54 | if __name__ == '__main__':
55 | app = wx.App(False)
56 | frame = MyFrame()
57 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_12_converting_dates/README.txt:
--------------------------------------------------------------------------------
1 | This recipe doesn't have a complete runnable example, but you should be able to add the code from the recipe to your own code without issue.
--------------------------------------------------------------------------------
/recipe_13_about_box/main_classic.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.html
3 | from wx.lib.wordwrap import wordwrap
4 |
5 | class MyForm(wx.Frame):
6 |
7 | def __init__(self):
8 | wx.Frame.__init__(self, None, wx.ID_ANY, title='The About Box')
9 |
10 | # Add a panel so it looks correct on all platforms
11 | self.panel = wx.Panel(self, wx.ID_ANY)
12 |
13 | # Create buttons
14 | aboutBtn = wx.Button(self.panel, wx.ID_ANY, "Open wx.AboutBox")
15 | self.Bind(wx.EVT_BUTTON, self.onAboutDlg, aboutBtn)
16 | aboutHtmlBtn = wx.Button(self.panel, wx.ID_ANY, "Open HtmlAboutBox")
17 | self.Bind(wx.EVT_BUTTON, self.onAboutHtmlDlg, aboutHtmlBtn)
18 |
19 | closeBtn = wx.Button(self.panel, wx.ID_ANY, "Close")
20 | self.Bind(wx.EVT_BUTTON, self.onClose, closeBtn)
21 |
22 | # Create Sizers
23 | topSizer = wx.BoxSizer(wx.VERTICAL)
24 |
25 | # Add widgets to sizers
26 | topSizer.Add(aboutBtn, 0, wx.ALL|wx.CENTER, 5)
27 | topSizer.Add(aboutHtmlBtn, 0, wx.ALL|wx.CENTER, 5)
28 | topSizer.Add(closeBtn, 0, wx.ALL|wx.CENTER, 5)
29 |
30 | # Create the menu
31 | self.createMenu()
32 | self.statusBar = self.CreateStatusBar()
33 |
34 | self.panel.SetSizer(topSizer)
35 | self.SetSizeHints(250,300,500,400)
36 | self.Fit()
37 | self.Refresh()
38 |
39 | def createMenu(self):
40 | """ Create the application's menu """
41 | menubar = wx.MenuBar()
42 |
43 | # Create the file menu
44 | fileMenu = wx.Menu()
45 |
46 | # Append the close item
47 | # Append takes an id, the text label, and a string
48 | # to display in the statusbar when the item is selected
49 | close_menu_item = fileMenu.Append(wx.NewId(),
50 | "&Close",
51 | "Closes the application")
52 | # Bind an event to the menu item
53 | self.Bind(wx.EVT_MENU, self.onClose, close_menu_item)
54 | # Add the fileMenu to the menu bar
55 | menubar.Append(fileMenu, "&File")
56 |
57 | # Create the help menu
58 | helpMenu = wx.Menu()
59 | about_menu_item = helpMenu.Append(wx.NewId(),
60 | "&About",
61 | "Opens the About Box")
62 | self.Bind(wx.EVT_MENU, self.onAboutDlg, about_menu_item)
63 | menubar.Append(helpMenu, "&Help")
64 |
65 | # Add the menu bar to the frame
66 | self.SetMenuBar(menubar)
67 |
68 | def onAboutHtmlDlg(self, event):
69 | aboutDlg = AboutDlg(None)
70 | aboutDlg.Show()
71 |
72 | def onAboutDlg(self, event):
73 | info = wx.AboutDialogInfo()
74 | info.Name = "My About Box"
75 | info.Version = "0.0.1 Beta"
76 | info.Copyright = "(C) 2016 Python Geeks Everywhere"
77 | info.Description = wordwrap(
78 | "This is an example application that shows how to create "
79 | "different kinds of About Boxes using wxPython!",
80 | 350, wx.ClientDC(self.panel))
81 | info.WebSite = ("http://www.pythonlibrary.org", "My Home Page")
82 | info.Developers = ["Mike Driscoll"]
83 | info.License = wordwrap("Completely and totally open source!", 500,
84 | wx.ClientDC(self.panel))
85 | # Show the wx.AboutBox
86 | wx.AboutBox(info)
87 |
88 | def onClose(self, event):
89 | self.Close()
90 |
91 |
92 | class AboutDlg(wx.Frame):
93 |
94 | def __init__(self, parent):
95 |
96 | wx.Frame.__init__(self, parent, wx.ID_ANY, title="About", size=(400,400))
97 |
98 | html = wxHTML(self)
99 |
100 | html.SetPage(
101 | ''
102 |
103 | "
About the About Tutorial
"
104 |
105 | "This about box is for demo purposes only. It was created in June 2006 "
106 |
107 | "by Mike Driscoll.
"
108 |
109 | "Software used in making this demo:
"
110 |
111 | 'Python 2.7 / 3.5
'
112 |
113 | 'wxPython 3.0.2.0 / Phoenix
'
114 | )
115 |
116 | class wxHTML(wx.html.HtmlWindow):
117 |
118 | def OnLinkClicked(self, link):
119 | webbrowser.open(link.GetHref())
120 |
121 |
122 | # Run the program
123 | if __name__ == '__main__':
124 | app = wx.App(False)
125 | frame = MyForm().Show()
126 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_13_about_box/main_phoenix.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.adv
3 | import wx.html
4 | from wx.lib.wordwrap import wordwrap
5 |
6 |
7 | class MyForm(wx.Frame):
8 |
9 | def __init__(self):
10 | wx.Frame.__init__(self, None, wx.ID_ANY, title='The About Box')
11 |
12 | # Add a panel so it looks correct on all platforms
13 | self.panel = wx.Panel(self, wx.ID_ANY)
14 |
15 | # Create buttons
16 | aboutBtn = wx.Button(self.panel, wx.ID_ANY, "Open wx.AboutBox")
17 | self.Bind(wx.EVT_BUTTON, self.onAboutDlg, aboutBtn)
18 | aboutHtmlBtn = wx.Button(self.panel, wx.ID_ANY, "Open HtmlAboutBox")
19 | self.Bind(wx.EVT_BUTTON, self.onAboutHtmlDlg, aboutHtmlBtn)
20 |
21 | closeBtn = wx.Button(self.panel, wx.ID_ANY, "Close")
22 | self.Bind(wx.EVT_BUTTON, self.onClose, closeBtn)
23 |
24 | # Create Sizers
25 | topSizer = wx.BoxSizer(wx.VERTICAL)
26 |
27 | # Add widgets to sizers
28 | topSizer.Add(aboutBtn, 0, wx.ALL|wx.CENTER, 5)
29 | topSizer.Add(aboutHtmlBtn, 0, wx.ALL|wx.CENTER, 5)
30 | topSizer.Add(closeBtn, 0, wx.ALL|wx.CENTER, 5)
31 |
32 | # Create the menu
33 | self.createMenu()
34 | self.statusBar = self.CreateStatusBar()
35 |
36 | self.panel.SetSizer(topSizer)
37 | self.SetSizeHints(250,300,500,400)
38 | self.Fit()
39 | self.Refresh()
40 |
41 | def createMenu(self):
42 | """ Create the application's menu """
43 | menubar = wx.MenuBar()
44 |
45 | # Create the file menu
46 | fileMenu = wx.Menu()
47 |
48 | # Append the close item
49 | # Append takes an id, the text label, and a string
50 | # to display in the statusbar when the item is selected
51 | close_menu_item = fileMenu.Append(wx.NewId(),
52 | "&Close",
53 | "Closes the application")
54 | # Bind an event to the menu item
55 | self.Bind(wx.EVT_MENU, self.onClose, close_menu_item)
56 | # Add the fileMenu to the menu bar
57 | menubar.Append(fileMenu, "&File")
58 |
59 | # Create the help menu
60 | helpMenu = wx.Menu()
61 | about_menu_item = helpMenu.Append(wx.NewId(),
62 | "&About",
63 | "Opens the About Box")
64 | self.Bind(wx.EVT_MENU, self.onAboutDlg, about_menu_item)
65 | menubar.Append(helpMenu, "&Help")
66 |
67 | # Add the menu bar to the frame
68 | self.SetMenuBar(menubar)
69 |
70 | def onAboutHtmlDlg(self, event):
71 | aboutDlg = AboutDlg(None)
72 | aboutDlg.Show()
73 |
74 | def onAboutDlg(self, event):
75 | info = wx.adv.AboutDialogInfo()
76 | info.Name = "My About Box"
77 | info.Version = "0.0.1 Beta"
78 | info.Copyright = "(C) 2008 Python Geeks Everywhere"
79 | info.Description = wordwrap(
80 | "This is an example application that shows how to create "
81 | "different kinds of About Boxes using wxPython!",
82 | 350, wx.ClientDC(self.panel))
83 | info.WebSite = ("http://www.pythonlibrary.org", "My Home Page")
84 | info.Developers = ["Mike Driscoll"]
85 | info.License = wordwrap("Completely and totally open source!", 500,
86 | wx.ClientDC(self.panel))
87 | # Show the wx.AboutBox
88 | wx.adv.AboutBox(info)
89 |
90 | def onClose(self, event):
91 | self.Close()
92 |
93 |
94 | class AboutDlg(wx.Frame):
95 |
96 | def __init__(self, parent):
97 |
98 | wx.Frame.__init__(self, parent, wx.ID_ANY, title="About", size=(400,400))
99 |
100 | html = wxHTML(self)
101 |
102 | html.SetPage(
103 | ''
104 |
105 | "About the About Tutorial
"
106 |
107 | "This about box is for demo purposes only. It was created in June 2006"
108 |
109 | "by Mike Driscoll.
"
110 |
111 | "Software used in making this demo:
"
112 |
113 | 'Python 2.4
'
114 |
115 | 'wxPython 2.8
'
116 | )
117 |
118 | class wxHTML(wx.html.HtmlWindow):
119 |
120 | def OnLinkClicked(self, link):
121 | webbrowser.open(link.GetHref())
122 |
123 |
124 | # Run the program
125 | if __name__ == '__main__':
126 | app = wx.App(False)
127 | frame = MyForm().Show()
128 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_14_login_dialog/main_flag.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class LoginDialog(wx.Dialog):
5 | """
6 | Class to define login dialog
7 | """
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | wx.Dialog.__init__(self, None, title="Login")
12 | self.logged_in = False
13 |
14 | # user info
15 | user_sizer = wx.BoxSizer(wx.HORIZONTAL)
16 |
17 | user_lbl = wx.StaticText(self, label="Username:")
18 | user_sizer.Add(user_lbl, 0, wx.ALL|wx.CENTER, 5)
19 | self.user = wx.TextCtrl(self)
20 | user_sizer.Add(self.user, 0, wx.ALL, 5)
21 |
22 | # pass info
23 | p_sizer = wx.BoxSizer(wx.HORIZONTAL)
24 |
25 | p_lbl = wx.StaticText(self, label="Password:")
26 | p_sizer.Add(p_lbl, 0, wx.ALL|wx.CENTER, 5)
27 | self.password = wx.TextCtrl(self, style=wx.TE_PASSWORD|wx.TE_PROCESS_ENTER)
28 | self.password.Bind(wx.EVT_TEXT_ENTER, self.onLogin)
29 | p_sizer.Add(self.password, 0, wx.ALL, 5)
30 |
31 | main_sizer = wx.BoxSizer(wx.VERTICAL)
32 | main_sizer.Add(user_sizer, 0, wx.ALL, 5)
33 | main_sizer.Add(p_sizer, 0, wx.ALL, 5)
34 |
35 | btn = wx.Button(self, label="Login")
36 | btn.Bind(wx.EVT_BUTTON, self.onLogin)
37 | main_sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
38 |
39 | self.SetSizer(main_sizer)
40 |
41 | def onLogin(self, event):
42 | """
43 | Check credentials and login
44 | """
45 | stupid_password = "pa$$w0rd!"
46 | user_password = self.password.GetValue()
47 | if user_password == stupid_password:
48 | print("You are now logged in!")
49 | self.logged_in = True
50 | self.Close()
51 | else:
52 | print("Username or password is incorrect!")
53 |
54 |
55 | class MyPanel(wx.Panel):
56 | """"""
57 |
58 | def __init__(self, parent):
59 | """Constructor"""
60 | wx.Panel.__init__(self, parent)
61 |
62 |
63 | class MainFrame(wx.Frame):
64 | """"""
65 |
66 | def __init__(self):
67 | """Constructor"""
68 | wx.Frame.__init__(self, None, title="Main App")
69 | panel = MyPanel(self)
70 |
71 | # Ask user to login
72 | dlg = LoginDialog()
73 | dlg.ShowModal()
74 | authenticated = dlg.logged_in
75 | dlg.Destroy()
76 | if not authenticated:
77 | self.Close()
78 |
79 | self.Show()
80 |
81 |
82 | if __name__ == "__main__":
83 | app = wx.App(False)
84 | frame = MainFrame()
85 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_14_login_dialog/main_pubsub.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx.lib.pubsub import pub
3 |
4 |
5 | class LoginDialog(wx.Dialog):
6 | """
7 | Class to define login dialog
8 | """
9 |
10 | def __init__(self):
11 | """Constructor"""
12 | wx.Dialog.__init__(self, None, title="Login")
13 |
14 | # user info
15 | user_sizer = wx.BoxSizer(wx.HORIZONTAL)
16 |
17 | user_lbl = wx.StaticText(self, label="Username:")
18 | user_sizer.Add(user_lbl, 0, wx.ALL|wx.CENTER, 5)
19 | self.user = wx.TextCtrl(self)
20 | user_sizer.Add(self.user, 0, wx.ALL, 5)
21 |
22 | # pass info
23 | p_sizer = wx.BoxSizer(wx.HORIZONTAL)
24 |
25 | p_lbl = wx.StaticText(self, label="Password:")
26 | p_sizer.Add(p_lbl, 0, wx.ALL|wx.CENTER, 5)
27 | self.password = wx.TextCtrl(self, style=wx.TE_PASSWORD|wx.TE_PROCESS_ENTER)
28 | p_sizer.Add(self.password, 0, wx.ALL, 5)
29 |
30 | main_sizer = wx.BoxSizer(wx.VERTICAL)
31 | main_sizer.Add(user_sizer, 0, wx.ALL, 5)
32 | main_sizer.Add(p_sizer, 0, wx.ALL, 5)
33 |
34 | btn = wx.Button(self, label="Login")
35 | btn.Bind(wx.EVT_BUTTON, self.onLogin)
36 | main_sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
37 |
38 | self.SetSizer(main_sizer)
39 |
40 | def onLogin(self, event):
41 | """
42 | Check credentials and login
43 | """
44 | stupid_password = "pa$$w0rd!"
45 | user_password = self.password.GetValue()
46 | if user_password == stupid_password:
47 | print("You are now logged in!")
48 | pub.sendMessage("frameListener", message="show")
49 | self.Destroy()
50 | else:
51 | print("Username or password is incorrect!")
52 |
53 |
54 | class MyPanel(wx.Panel):
55 | """"""
56 |
57 | def __init__(self, parent):
58 | """Constructor"""
59 | wx.Panel.__init__(self, parent)
60 |
61 |
62 | class MainFrame(wx.Frame):
63 | """"""
64 |
65 | def __init__(self):
66 | """Constructor"""
67 | wx.Frame.__init__(self, None, title="Main App")
68 | panel = MyPanel(self)
69 | pub.subscribe(self.myListener, "frameListener")
70 |
71 | # Ask user to login
72 | dlg = LoginDialog()
73 | dlg.ShowModal()
74 |
75 | def myListener(self, message, arg2=None):
76 | """
77 | Show the frame
78 | """
79 | self.Show()
80 |
81 |
82 | if __name__ == "__main__":
83 | app = wx.App(False)
84 | frame = MainFrame()
85 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_15_dialog_from_config/config.ini:
--------------------------------------------------------------------------------
1 | [Labels]
2 | server = Update Server:
3 | username = Username:
4 | password = Password:
5 | update interval = Update Interval:
6 | agency = Agency Filter:
7 | filters = ""
8 |
9 | [Values]
10 | server = http://www.someCoolWebsite/hackery.php
11 | username = ""
12 | password = ""
13 | update interval = 2
14 | agency_choices = Include all agencies except, Include all agencies except, Exclude all agencies except
15 | filters = ""
16 |
--------------------------------------------------------------------------------
/recipe_15_dialog_from_config/main.py:
--------------------------------------------------------------------------------
1 | import configobj
2 | import wx
3 |
4 |
5 | class PreferencesDialog(wx.Dialog):
6 | """
7 | Creates and displays a preferences dialog that allows the user to
8 | change some settings.
9 | """
10 |
11 | def __init__(self):
12 | """
13 | Initialize the dialog
14 | """
15 | wx.Dialog.__init__(self, None, title='Preferences',
16 | size=(550,300))
17 | self.createWidgets()
18 |
19 | def createWidgets(self):
20 | """
21 | Create and layout the widgets in the dialog
22 | """
23 | lblSizer = wx.BoxSizer(wx.VERTICAL)
24 | valueSizer = wx.BoxSizer(wx.VERTICAL)
25 | btnSizer = wx.StdDialogButtonSizer()
26 | colSizer = wx.BoxSizer(wx.HORIZONTAL)
27 | mainSizer = wx.BoxSizer(wx.VERTICAL)
28 |
29 | iniFile = "config.ini"
30 | self.config = configobj.ConfigObj(iniFile)
31 |
32 | labels = self.config["Labels"]
33 | values = self.config["Values"]
34 | self.widgetNames = values
35 | font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD)
36 |
37 | for key in labels:
38 | value = labels[key]
39 | lbl = wx.StaticText(self, label=value)
40 | lbl.SetFont(font)
41 | lblSizer.Add(lbl, 0, wx.ALL, 5)
42 |
43 | for key in values:
44 | print(key)
45 | value = values[key]
46 | if isinstance(value, list):
47 | default = value[0]
48 | choices = value[1:]
49 | cbo = wx.ComboBox(self, value=value[0],
50 | size=wx.DefaultSize, choices=choices,
51 | style=wx.CB_DROPDOWN|wx.CB_READONLY,
52 | name=key)
53 | valueSizer.Add(cbo, 0, wx.ALL, 5)
54 | else:
55 | txt = wx.TextCtrl(self, value=value, name=key)
56 | valueSizer.Add(txt, 0, wx.ALL|wx.EXPAND, 5)
57 |
58 | saveBtn = wx.Button(self, wx.ID_OK, label="Save")
59 | saveBtn.Bind(wx.EVT_BUTTON, self.onSave)
60 | btnSizer.AddButton(saveBtn)
61 |
62 | cancelBtn = wx.Button(self, wx.ID_CANCEL)
63 | btnSizer.AddButton(cancelBtn)
64 | btnSizer.Realize()
65 |
66 | colSizer.Add(lblSizer)
67 | colSizer.Add(valueSizer, 1, wx.EXPAND)
68 | mainSizer.Add(colSizer, 0, wx.EXPAND)
69 | mainSizer.Add(btnSizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
70 | self.SetSizer(mainSizer)
71 |
72 | def onSave(self, event):
73 | """
74 | Saves values to disk
75 | """
76 | for name in self.widgetNames:
77 | widget = wx.FindWindowByName(name)
78 | if isinstance(widget, wx.ComboBox):
79 | selection = widget.GetValue()
80 | choices = widget.GetItems()
81 | choices.insert(0, selection)
82 | self.widgetNames[name] = choices
83 | else:
84 | value = widget.GetValue()
85 | self.widgetNames[name] = value
86 | self.config.write()
87 | self.EndModal(0)
88 |
89 |
90 | class MyApp(wx.App):
91 | """"""
92 |
93 | def OnInit(self):
94 | """Constructor"""
95 | dlg = PreferencesDialog()
96 | dlg.ShowModal()
97 | dlg.Destroy()
98 |
99 | return True
100 |
101 |
102 | if __name__ == "__main__":
103 | app = MyApp(False)
104 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_16_saving_configs/controller.py:
--------------------------------------------------------------------------------
1 | # controller.py
2 | import configobj
3 | import os
4 | import sys
5 |
6 |
7 | appPath = os.path.abspath(os.path.dirname(os.path.join(sys.argv[0])))
8 | inifile = os.path.join(appPath, "example.ini")
9 |
10 | def create_config():
11 | """
12 | Create the configuration file
13 | """
14 | config = configobj.ConfigObj()
15 | config.filename = inifile
16 | config['update server'] = "http://www.someCoolWebsite/hackery.php"
17 | config['username'] = ""
18 | config['password'] = ""
19 | config['update interval'] = 2
20 | config['agency filter'] = 'include'
21 | config['filters'] = ""
22 | config.write()
23 |
24 |
25 | def get_config():
26 | """
27 | Open the config file and return a configobj
28 | """
29 | if not os.path.exists(inifile):
30 | create_config()
31 | return configobj.ConfigObj(inifile)
--------------------------------------------------------------------------------
/recipe_16_saving_configs/example.ini:
--------------------------------------------------------------------------------
1 | update server = http://www.someCoolWebsite/hackery.php
2 | username = ""
3 | password = ""
4 | update interval = 2
5 | agency filter = include
6 | filters = ""
7 |
--------------------------------------------------------------------------------
/recipe_16_saving_configs/images/cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_16_saving_configs/images/cancel.png
--------------------------------------------------------------------------------
/recipe_16_saving_configs/images/filesave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_16_saving_configs/images/filesave.png
--------------------------------------------------------------------------------
/recipe_17_binding_multiple_events/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyForm(wx.Frame):
5 |
6 | def __init__(self):
7 | wx.Frame.__init__(
8 | self, None, title="Binding Multiple Widgets")
9 | panel = wx.Panel(self, wx.ID_ANY)
10 |
11 | sizer = wx.BoxSizer(wx.VERTICAL)
12 | buttonOne = wx.Button(panel, label="One", name="one")
13 | buttonTwo = wx.Button(panel, label="Two", name="two")
14 | buttonThree = wx.Button(panel, label="Three", name="three")
15 | buttons = [buttonOne, buttonTwo, buttonThree]
16 |
17 | for button in buttons:
18 | self.buildButtons(button, sizer)
19 |
20 | panel.SetSizer(sizer)
21 |
22 | def buildButtons(self, btn, sizer):
23 | """"""
24 | btn.Bind(wx.EVT_BUTTON, self.onButton)
25 | sizer.Add(btn, 0, wx.ALL, 5)
26 |
27 | def onButton(self, event):
28 | """
29 | This method is fired when its corresponding button is pressed
30 | """
31 | button = event.GetEventObject()
32 | print("The button you pressed was labeled: " + button.GetLabel())
33 | print("The button's name is " + button.GetName())
34 |
35 | button_id = event.GetId()
36 | button_by_id = self.FindWindowById(button_id)
37 | print("The button you pressed was labeled: " + button_by_id.GetLabel())
38 | print("The button's name is " + button_by_id.GetName())
39 |
40 |
41 | if __name__ == "__main__":
42 | app = wx.App(False)
43 | frame = MyForm()
44 | frame.Show()
45 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_18_firing_multiple_handlers/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyPanel(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """Constructor"""
9 | wx.Panel.__init__(self, parent)
10 | btn = wx.Button(self, label="Press Me")
11 | btn.Bind(wx.EVT_BUTTON, self.HandlerOne)
12 | btn.Bind(wx.EVT_BUTTON, self.HandlerTwo)
13 |
14 | def HandlerOne(self, event):
15 | """"""
16 | print("handler one fired!")
17 | event.Skip()
18 |
19 | def HandlerTwo(self, event):
20 | """"""
21 | print("handler two fired!")
22 | event.Skip()
23 |
24 |
25 | class MyFrame(wx.Frame):
26 | """"""
27 |
28 | def __init__(self):
29 | """Constructor"""
30 | wx.Frame.__init__(self, None, title="Test")
31 | panel = MyPanel(self)
32 | self.Show()
33 |
34 |
35 | if __name__ == "__main__":
36 | app = wx.App(False)
37 | frame = MyFrame()
38 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_19_get_event_name/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.grid
3 |
4 |
5 | class MyForm(wx.Frame):
6 |
7 | def __init__(self):
8 | wx.Frame.__init__(self, None, title="Tutorial")
9 |
10 | self.eventDict = {}
11 | evt_names = [x for x in dir(wx) if x.startswith("EVT_")]
12 | for name in evt_names:
13 | evt = getattr(wx, name)
14 | if isinstance(evt, wx.PyEventBinder):
15 | self.eventDict[evt.typeId] = name
16 |
17 | grid_evt_names = [x for x in dir(wx.grid) if x.startswith("EVT_")]
18 | for name in grid_evt_names:
19 | evt = getattr(wx.grid, name)
20 | if isinstance(evt, wx.PyEventBinder):
21 | self.eventDict[evt.typeId] = name
22 |
23 | panel = wx.Panel(self, wx.ID_ANY)
24 | btn = wx.Button(panel, wx.ID_ANY, "Get POS")
25 |
26 | btn.Bind(wx.EVT_BUTTON, self.onEvent)
27 | panel.Bind(wx.EVT_LEFT_DCLICK, self.onEvent)
28 | panel.Bind(wx.EVT_RIGHT_DOWN, self.onEvent)
29 |
30 | def onEvent(self, event):
31 | """
32 | Print out what event was fired
33 | """
34 | evt_id = event.GetEventType()
35 | print(self.eventDict[evt_id])
36 |
37 |
38 | if __name__ == "__main__":
39 | app = wx.App(redirect=True)
40 | frame = MyForm().Show()
41 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_1_add_widgets_dynamically/dynamic_widgets.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyPanel(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """Constructor"""
9 | wx.Panel.__init__(self, parent)
10 | self.number_of_buttons = 0
11 | self.frame = parent
12 |
13 | self.mainSizer = wx.BoxSizer(wx.VERTICAL)
14 | controlSizer = wx.BoxSizer(wx.HORIZONTAL)
15 | self.widgetSizer = wx.BoxSizer(wx.VERTICAL)
16 |
17 | self.addButton = wx.Button(self, label="Add")
18 | self.addButton.Bind(wx.EVT_BUTTON, self.onAddWidget)
19 | controlSizer.Add(self.addButton, 0, wx.CENTER|wx.ALL, 5)
20 |
21 | self.removeButton = wx.Button(self, label="Remove")
22 | self.removeButton.Bind(wx.EVT_BUTTON, self.onRemoveWidget)
23 | controlSizer.Add(self.removeButton, 0, wx.CENTER|wx.ALL, 5)
24 |
25 | self.mainSizer.Add(controlSizer, 0, wx.CENTER)
26 | self.mainSizer.Add(self.widgetSizer, 0, wx.CENTER|wx.ALL, 10)
27 |
28 | self.SetSizer(self.mainSizer)
29 |
30 | def onAddWidget(self, event):
31 | """"""
32 | self.number_of_buttons += 1
33 | label = "Button %s" % self.number_of_buttons
34 | name = "button%s" % self.number_of_buttons
35 | new_button = wx.Button(self, label=label, name=name)
36 | self.widgetSizer.Add(new_button, 0, wx.ALL, 5)
37 | self.frame.fSizer.Layout()
38 | self.frame.Fit()
39 |
40 | def onRemoveWidget(self, event):
41 | """"""
42 | if self.widgetSizer.GetChildren():
43 | self.widgetSizer.Hide(self.number_of_buttons-1)
44 | self.widgetSizer.Remove(self.number_of_buttons-1)
45 | self.number_of_buttons -= 1
46 | self.frame.fSizer.Layout()
47 | self.frame.Fit()
48 |
49 |
50 | class MyFrame(wx.Frame):
51 | """"""
52 |
53 | def __init__(self):
54 | """Constructor"""
55 | wx.Frame.__init__(self, parent=None, title="Add / Remove Buttons")
56 | self.fSizer = wx.BoxSizer(wx.VERTICAL)
57 | panel = MyPanel(self)
58 | self.fSizer.Add(panel, 1, wx.EXPAND)
59 | self.SetSizer(self.fSizer)
60 | self.Fit()
61 | self.Show()
62 |
63 |
64 | if __name__ == "__main__":
65 | app = wx.App(False)
66 | frame = MyFrame()
67 | app.MainLoop()
68 |
--------------------------------------------------------------------------------
/recipe_20_key_char_events/char_events.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title="Char Event Tutorial")
7 |
8 | # Add a panel so it looks the correct on all platforms
9 | panel = wx.Panel(self, wx.ID_ANY)
10 | btn = wx.TextCtrl(panel, value="")
11 |
12 | btn.Bind(wx.EVT_CHAR, self.onCharEvent)
13 |
14 | def onCharEvent(self, event):
15 | keycode = event.GetKeyCode()
16 | controlDown = event.CmdDown()
17 | altDown = event.AltDown()
18 | shiftDown = event.ShiftDown()
19 |
20 | print(keycode)
21 | if keycode == wx.WXK_SPACE:
22 | print("you pressed the spacebar!")
23 | elif controlDown and altDown:
24 | print(keycode)
25 | event.Skip()
26 |
27 |
28 | if __name__ == "__main__":
29 | app = wx.App(True)
30 | frame = MyForm()
31 | frame.Show()
32 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_20_key_char_events/key_events.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title="Key Press Tutorial")
7 |
8 | panel = wx.Panel(self, wx.ID_ANY)
9 | btn = wx.Button(panel, label="OK")
10 |
11 | btn.Bind(wx.EVT_KEY_DOWN, self.onKeyPress)
12 |
13 | def onKeyPress(self, event):
14 | keycode = event.GetKeyCode()
15 | print(keycode)
16 | if keycode == wx.WXK_SPACE:
17 | print("you pressed the spacebar!")
18 | event.Skip()
19 |
20 |
21 | if __name__ == "__main__":
22 | app = wx.App(True)
23 | frame = MyForm()
24 | frame.Show()
25 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_20_key_char_events/key_events2.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title="Key Press Tutorial 2")
7 |
8 | panel = wx.Panel(self, wx.ID_ANY)
9 | sizer = wx.BoxSizer(wx.VERTICAL)
10 |
11 | btn = self.onWidgetSetup(wx.Button(panel, label="OK"),
12 | wx.EVT_KEY_UP,
13 | self.onButtonKeyEvent, sizer)
14 | txt = self.onWidgetSetup(wx.TextCtrl(panel, value=""),
15 | wx.EVT_KEY_DOWN, self.onTextKeyEvent,
16 | sizer)
17 | panel.SetSizer(sizer)
18 |
19 | def onWidgetSetup(self, widget, event, handler, sizer):
20 | widget.Bind(event, handler)
21 | sizer.Add(widget, 0, wx.ALL, 5)
22 | return widget
23 |
24 | def onButtonKeyEvent(self, event):
25 | keycode = event.GetKeyCode()
26 | print(keycode)
27 | if keycode == wx.WXK_SPACE:
28 | print("you pressed the spacebar!")
29 | event.Skip()
30 |
31 | def onTextKeyEvent(self, event):
32 | keycode = event.GetKeyCode()
33 | print(keycode)
34 | if keycode == wx.WXK_DELETE:
35 | print("you pressed the delete key!")
36 | event.Skip()
37 |
38 |
39 | if __name__ == "__main__":
40 | app = wx.App(True)
41 | frame = MyForm()
42 | frame.Show()
43 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_21_drag_n_drop/drag_and_drop_app.py:
--------------------------------------------------------------------------------
1 | import os
2 | import stat
3 | import time
4 | import wx
5 | from ObjectListView import ObjectListView, ColumnDefn
6 |
7 |
8 | class MyFileDropTarget(wx.FileDropTarget):
9 | """"""
10 |
11 | def __init__(self, window):
12 | """Constructor"""
13 | wx.FileDropTarget.__init__(self)
14 | self.window = window
15 |
16 | def OnDropFiles(self, x, y, filenames):
17 | """
18 | When files are dropped, update the display
19 | """
20 | self.window.updateDisplay(filenames)
21 | return True
22 |
23 |
24 | class FileInfo(object):
25 | """"""
26 |
27 | def __init__(self, path, date_created, date_modified, size):
28 | """Constructor"""
29 | self.name = os.path.basename(path)
30 | self.path = path
31 | self.date_created = date_created
32 | self.date_modified = date_modified
33 | self.size = size
34 |
35 |
36 | class MainPanel(wx.Panel):
37 | """"""
38 |
39 | def __init__(self, parent):
40 | """Constructor"""
41 | wx.Panel.__init__(self, parent=parent)
42 | self.file_list = []
43 |
44 | file_drop_target = MyFileDropTarget(self)
45 | self.olv = ObjectListView(
46 | self, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
47 | self.olv.SetDropTarget(file_drop_target)
48 | self.setFiles()
49 |
50 | sizer = wx.BoxSizer(wx.VERTICAL)
51 | sizer.Add(self.olv, 1, wx.EXPAND)
52 | self.SetSizer(sizer)
53 |
54 | def updateDisplay(self, file_list):
55 | """"""
56 | for path in file_list:
57 | file_stats = os.stat(path)
58 | creation_time = time.strftime(
59 | "%m/%d/%Y %I:%M %p",
60 | time.localtime(file_stats[stat.ST_CTIME]))
61 | modified_time = time.strftime(
62 | "%m/%d/%Y %I:%M %p",
63 | time.localtime(file_stats[stat.ST_MTIME]))
64 | file_size = file_stats[stat.ST_SIZE]
65 | if file_size > 1024:
66 | file_size = file_size / 1024.0
67 | file_size = "%.2f KB" % file_size
68 |
69 | self.file_list.append(FileInfo(path,
70 | creation_time,
71 | modified_time,
72 | file_size))
73 |
74 | self.olv.SetObjects(self.file_list)
75 |
76 | def setFiles(self):
77 | """"""
78 | self.olv.SetColumns([
79 | ColumnDefn("Name", "left", 220, "name"),
80 | ColumnDefn("Date created", "left", 150, "date_created"),
81 | ColumnDefn("Date modified", "left", 150, "date_modified"),
82 | ColumnDefn("Size", "left", 100, "size")
83 | ])
84 | self.olv.SetObjects(self.file_list)
85 |
86 |
87 | class MainFrame(wx.Frame):
88 | """"""
89 |
90 | def __init__(self):
91 | """Constructor"""
92 | wx.Frame.__init__(self, None,
93 | title="OLV DnD Tutorial", size=(800,600))
94 | panel = MainPanel(self)
95 | self.Show()
96 |
97 |
98 | def main():
99 | """"""
100 | app = wx.App(False)
101 | frame = MainFrame()
102 | app.MainLoop()
103 |
104 |
105 | if __name__ == "__main__":
106 | main()
--------------------------------------------------------------------------------
/recipe_21_drag_n_drop/file_drop_target.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyFileDropTarget(wx.FileDropTarget):
5 | """"""
6 |
7 | def __init__(self, window):
8 | """Constructor"""
9 | wx.FileDropTarget.__init__(self)
10 | self.window = window
11 |
12 | def OnDropFiles(self, x, y, filenames):
13 | """
14 | When files are dropped, write where they were dropped and then
15 | the file paths themselves
16 | """
17 | self.window.SetInsertionPointEnd()
18 | self.window.updateText("\n%d file(s) dropped at %d,%d:\n" %
19 | (len(filenames), x, y))
20 | for filepath in filenames:
21 | self.window.updateText(filepath + '\n')
22 |
23 | return True
24 |
25 |
26 | class DnDPanel(wx.Panel):
27 | """"""
28 |
29 | def __init__(self, parent):
30 | """Constructor"""
31 | wx.Panel.__init__(self, parent=parent)
32 |
33 | file_drop_target = MyFileDropTarget(self)
34 | lbl = wx.StaticText(self, label="Drag some files here:")
35 | self.fileTextCtrl = wx.TextCtrl(self,
36 | style=wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY)
37 | self.fileTextCtrl.SetDropTarget(file_drop_target)
38 |
39 | sizer = wx.BoxSizer(wx.VERTICAL)
40 | sizer.Add(lbl, 0, wx.ALL, 5)
41 | sizer.Add(self.fileTextCtrl, 1, wx.EXPAND|wx.ALL, 5)
42 | self.SetSizer(sizer)
43 |
44 | def SetInsertionPointEnd(self):
45 | """
46 | Put insertion point at end of text control to prevent overwriting
47 | """
48 | self.fileTextCtrl.SetInsertionPointEnd()
49 |
50 | def updateText(self, text):
51 | """
52 | Write text to the text control
53 | """
54 | self.fileTextCtrl.WriteText(text)
55 |
56 |
57 | class DnDFrame(wx.Frame):
58 | """"""
59 |
60 | def __init__(self):
61 | """Constructor"""
62 | wx.Frame.__init__(self, parent=None, title="DnD Tutorial")
63 | panel = DnDPanel(self)
64 | self.Show()
65 |
66 |
67 | if __name__ == "__main__":
68 | app = wx.App(False)
69 | frame = DnDFrame()
70 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_21_drag_n_drop/py_drop_target.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyURLDropTarget(wx.PyDropTarget):
5 |
6 | def __init__(self, window):
7 | wx.PyDropTarget.__init__(self)
8 | self.window = window
9 |
10 | self.data = wx.URLDataObject();
11 | self.SetDataObject(self.data)
12 |
13 | def OnDragOver(self, x, y, d):
14 | return wx.DragLink
15 |
16 | def OnData(self, x, y, d):
17 | if not self.GetData():
18 | return wx.DragNone
19 |
20 | url = self.data.GetURL()
21 | self.window.AppendText(url + "\n")
22 |
23 | return d
24 |
25 |
26 | class DnDPanel(wx.Panel):
27 | """"""
28 |
29 | def __init__(self, parent):
30 | """Constructor"""
31 | wx.Panel.__init__(self, parent=parent)
32 | font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False)
33 |
34 | # create and setup first set of widgets
35 | lbl = wx.StaticText(self,
36 | label="Drag some URLS from your browser here:")
37 | lbl.SetFont(font)
38 | self.dropText = wx.TextCtrl(
39 | self, size=(200,200),
40 | style=wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY)
41 | dt = MyURLDropTarget(self.dropText)
42 | self.dropText.SetDropTarget(dt)
43 | firstSizer = self.addWidgetsToSizer([lbl, self.dropText])
44 |
45 | # create and setup second set of widgets
46 | lbl = wx.StaticText(self, label="Drag this URL to your browser:")
47 | lbl.SetFont(font)
48 | self.draggableURLText = wx.TextCtrl(self,
49 | value="http://www.mousevspython.com")
50 | self.draggableURLText.Bind(wx.EVT_MOTION, self.OnStartDrag)
51 | secondSizer = self.addWidgetsToSizer([lbl, self.draggableURLText])
52 |
53 | # Add sizers to main sizer
54 | mainSizer = wx.BoxSizer(wx.VERTICAL)
55 | mainSizer.Add(firstSizer, 0, wx.EXPAND)
56 | mainSizer.Add(secondSizer, 0, wx.EXPAND)
57 | self.SetSizer(mainSizer)
58 |
59 | def addWidgetsToSizer(self, widgets):
60 | """
61 | Returns a sizer full of widgets
62 | """
63 | sizer = wx.BoxSizer(wx.HORIZONTAL)
64 | for widget in widgets:
65 | if isinstance(widget, wx.TextCtrl):
66 | sizer.Add(widget, 1, wx.EXPAND|wx.ALL, 5)
67 | else:
68 | sizer.Add(widget, 0, wx.ALL, 5)
69 | return sizer
70 |
71 | def OnStartDrag(self, evt):
72 | """"""
73 | if evt.Dragging():
74 | url = self.draggableURLText.GetValue()
75 | data = wx.URLDataObject()
76 | data.SetURL(url)
77 |
78 | dropSource = wx.DropSource(self.draggableURLText)
79 | dropSource.SetData(data)
80 | result = dropSource.DoDragDrop()
81 |
82 |
83 | class DnDFrame(wx.Frame):
84 | """"""
85 |
86 | def __init__(self):
87 | """Constructor"""
88 | wx.Frame.__init__(self, parent=None,
89 | title="DnD URL Tutorial", size=(800,600))
90 | panel = DnDPanel(self)
91 | self.Show()
92 |
93 |
94 | if __name__ == "__main__":
95 | app = wx.App(False)
96 | frame = DnDFrame()
97 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_21_drag_n_drop/text_drop_target.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyTextDropTarget(wx.TextDropTarget):
5 |
6 | def __init__(self, textctrl):
7 | wx.TextDropTarget.__init__(self)
8 | self.textctrl = textctrl
9 |
10 | def OnDropText(self, x, y, text):
11 | self.textctrl.WriteText("(%d, %d)\n%s\n" % (x, y, text))
12 | return True
13 |
14 | def OnDragOver(self, x, y, d):
15 | return wx.DragCopy
16 |
17 |
18 | class DnDPanel(wx.Panel):
19 | """"""
20 |
21 | def __init__(self, parent):
22 | """Constructor"""
23 | wx.Panel.__init__(self, parent=parent)
24 |
25 |
26 | lbl = wx.StaticText(self, label="Drag some text here:")
27 | self.myTextCtrl = wx.TextCtrl(
28 | self, style=wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY)
29 | text_dt = MyTextDropTarget(self.myTextCtrl)
30 | self.myTextCtrl.SetDropTarget(text_dt)
31 |
32 | sizer = wx.BoxSizer(wx.VERTICAL)
33 | sizer.Add(self.myTextCtrl, 1, wx.EXPAND)
34 | self.SetSizer(sizer)
35 |
36 | def WriteText(self, text):
37 | self.text.WriteText(text)
38 |
39 |
40 | class DnDFrame(wx.Frame):
41 | """"""
42 |
43 | def __init__(self):
44 | """Constructor"""
45 | wx.Frame.__init__(
46 | self, parent=None, title="DnD Text Tutorial")
47 | panel = DnDPanel(self)
48 | self.Show()
49 |
50 |
51 | if __name__ == "__main__":
52 | app = wx.App(False)
53 | frame = DnDFrame()
54 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_22_drag_n_drop_file_to_os/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import os
3 | import time
4 |
5 |
6 | class MyListCtrl(wx.ListCtrl):
7 |
8 | def __init__(self, parent, id):
9 | wx.ListCtrl.__init__(self, parent, id,
10 | style=wx.LC_REPORT)
11 |
12 | files = os.listdir('.')
13 |
14 | self.InsertColumn(0, 'Name')
15 | self.InsertColumn(1, 'Ext')
16 | self.InsertColumn(2, 'Size',
17 | wx.LIST_FORMAT_RIGHT)
18 | self.InsertColumn(3, 'Modified')
19 |
20 | self.SetColumnWidth(0, 220)
21 | self.SetColumnWidth(1, 70)
22 | self.SetColumnWidth(2, 100)
23 | self.SetColumnWidth(3, 420)
24 |
25 | j = 0
26 | for i in files:
27 | (name, ext) = os.path.splitext(i)
28 |
29 | size = os.path.getsize(i)
30 | sec = os.path.getmtime(i)
31 | self.InsertStringItem(j, "{}{}".format(name, ext))
32 | self.SetStringItem(j, 1, ext)
33 | self.SetStringItem(j, 2, str(size) + ' B')
34 | self.SetStringItem(
35 | j, 3, time.strftime('%Y-%m-%d %H:%M',
36 | time.localtime(sec)))
37 |
38 | if os.path.isdir(i):
39 | self.SetItemImage(j, 1)
40 | elif 'py' in ext:
41 | self.SetItemImage(j, 2)
42 | elif 'jpg' in ext:
43 | self.SetItemImage(j, 3)
44 | elif 'pdf' in ext:
45 | self.SetItemImage(j, 4)
46 | else:
47 | self.SetItemImage(j, 0)
48 |
49 | if (j % 2) == 0:
50 | self.SetItemBackgroundColour(j, 'light blue')
51 | j = j + 1
52 |
53 |
54 | class DnDFrame(wx.Frame):
55 |
56 | def __init__(self):
57 | wx.Frame.__init__(self, None, title='DnD Files')
58 | panel = wx.Panel(self)
59 |
60 | p1 = MyListCtrl(panel, -1)
61 | p1.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onDrag)
62 | sizer = wx.BoxSizer()
63 | sizer.Add(p1, 1, wx.EXPAND)
64 | panel.SetSizer(sizer)
65 |
66 | self.Center()
67 | self.Show(True)
68 |
69 |
70 | def onDrag(self, event):
71 | """"""
72 | data = wx.FileDataObject()
73 | obj = event.GetEventObject()
74 | id = event.GetIndex()
75 | filename = obj.GetItem(id).GetText()
76 | dirname = os.path.dirname(os.path.abspath(
77 | os.listdir(".")[0]))
78 | fullpath = os.path.join(dirname, filename)
79 |
80 | data.AddFile(fullpath)
81 |
82 | dropSource = wx.DropSource(obj)
83 | dropSource.SetData(data)
84 | result = dropSource.DoDragDrop()
85 | print(fullpath)
86 |
87 | if __name__ == '__main__':
88 | app = wx.App(False)
89 | frame = DnDFrame()
90 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_23_edit_gui_interactively/main.py:
--------------------------------------------------------------------------------
1 | # main.py
2 | import testApp
3 | import wx
4 |
5 |
6 | class ReloaderPanel(wx.Panel):
7 | """"""
8 |
9 | def __init__(self, parent):
10 | """Constructor"""
11 | wx.Panel.__init__(self, parent)
12 | self.testFrame = None
13 |
14 | showAppBtn = wx.Button(self, label="Show App")
15 | showAppBtn.Bind(wx.EVT_BUTTON, self.onShowApp)
16 |
17 | reloadBtn = wx.Button(self, label="Reload")
18 | reloadBtn.Bind(wx.EVT_BUTTON, self.onReload)
19 |
20 | mainSizer = wx.BoxSizer(wx.VERTICAL)
21 | mainSizer.Add(showAppBtn, 0, wx.ALL|wx.CENTER, 5)
22 | mainSizer.Add(reloadBtn, 0, wx.ALL|wx.CENTER, 5)
23 | self.SetSizer(mainSizer)
24 |
25 | def onReload(self, event):
26 | """
27 | Reload the code!
28 | """
29 | if self.testFrame:
30 | self.testFrame.Close()
31 | try:
32 | reload(testApp)
33 | except NameError:
34 | # reload doesn't exist in Python 3.
35 | # Use importlib.reload in Python 3.4+
36 | # or imp.reload in Python 3.0 - 3.3
37 | import importlib
38 | importlib.reload(testApp)
39 | self.showApp()
40 | else:
41 | self.testFrame = None
42 |
43 | def onShowApp(self, event):
44 | """
45 | Call the showApp() method
46 | """
47 | self.showApp()
48 |
49 | def showApp(self):
50 | """
51 | Show the application we want to edit dynamically
52 | """
53 | self.testFrame = testApp.TestFrame()
54 |
55 |
56 | class ReloaderFrame(wx.Frame):
57 | """"""
58 |
59 | def __init__(self):
60 | """Constructor"""
61 | wx.Frame.__init__(self, None, title="Reloader")
62 | panel = ReloaderPanel(self)
63 | self.Show()
64 |
65 |
66 | if __name__ == "__main__":
67 | app = wx.App(False)
68 | frame = ReloaderFrame()
69 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_23_edit_gui_interactively/testApp.py:
--------------------------------------------------------------------------------
1 | # testApp.py
2 | import wx
3 |
4 |
5 | class TestPanel(wx.Panel):
6 | """"""
7 |
8 | def __init__(self, parent):
9 | """Constructor"""
10 | wx.Panel.__init__(self, parent)
11 | btn = wx.Button(self, label='Test')
12 |
13 |
14 | class TestFrame(wx.Frame):
15 | """"""
16 |
17 | def __init__(self):
18 | """Constructor"""
19 | wx.Frame.__init__(self, None, title="Test program")
20 | panel = TestPanel(self)
21 | self.Show()
22 |
23 |
24 | if __name__ == "__main__":
25 | app = wx.App(False)
26 | frame = TestFrame()
27 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_24_extracting_xml_from_richtextctrl/main_classic.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.richtext
3 |
4 | from StringIO import StringIO
5 |
6 |
7 | class MyFrame(wx.Frame):
8 |
9 | def __init__(self):
10 | wx.Frame.__init__(self, None, title='Richtext Test')
11 |
12 | sizer = wx.BoxSizer(wx.VERTICAL)
13 | self.rt = wx.richtext.RichTextCtrl(self)
14 | self.rt.SetMinSize((300,200))
15 |
16 | save_button = wx.Button(self, label="Save")
17 | save_button.Bind(wx.EVT_BUTTON, self.on_save)
18 |
19 | sizer = wx.BoxSizer(wx.VERTICAL)
20 | sizer.Add(self.rt, 1, wx.EXPAND|wx.ALL, 6)
21 | sizer.Add(save_button, 0, wx.EXPAND|wx.ALL, 6)
22 |
23 | self.SetSizer(sizer)
24 | self.Show()
25 |
26 | def on_save(self, event):
27 | out = StringIO()
28 | handler = wx.richtext.RichTextXMLHandler()
29 | rt_buffer = self.rt.GetBuffer()
30 | handler.SaveStream(rt_buffer, out)
31 | self.xml_content = out.getvalue()
32 | print(self.xml_content)
33 |
34 |
35 | if __name__ == "__main__":
36 | app = wx.App(False)
37 | frame = MyFrame()
38 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_24_extracting_xml_from_richtextctrl/main_phoenix.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.richtext
3 |
4 | from io import BytesIO
5 |
6 |
7 | class MyFrame(wx.Frame):
8 |
9 | def __init__(self):
10 | wx.Frame.__init__(self, None, title='Richtext Test')
11 |
12 | sizer = wx.BoxSizer(wx.VERTICAL)
13 | self.rt = wx.richtext.RichTextCtrl(self)
14 | self.rt.SetMinSize((300,200))
15 |
16 | save_button = wx.Button(self, label="Save")
17 | save_button.Bind(wx.EVT_BUTTON, self.on_save)
18 |
19 | sizer = wx.BoxSizer(wx.VERTICAL)
20 | sizer.Add(self.rt, 1, wx.EXPAND|wx.ALL, 6)
21 | sizer.Add(save_button, 0, wx.EXPAND|wx.ALL, 6)
22 |
23 | self.SetSizer(sizer)
24 | self.Show()
25 |
26 | def on_save(self, event):
27 | out = BytesIO()
28 | handler = wx.richtext.RichTextXMLHandler()
29 | rt_buffer = self.rt.GetBuffer()
30 | handler.SaveFile(rt_buffer, out)
31 | self.xml_content = out.getvalue()
32 | print(self.xml_content)
33 |
34 |
35 | if __name__ == "__main__":
36 | app = wx.App(False)
37 | frame = MyFrame()
38 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_25_fade_in/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class Fader(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title='Fader Example')
7 | self.amount = 5
8 | self.delta = 5
9 | panel = wx.Panel(self, wx.ID_ANY)
10 |
11 | self.SetTransparent(self.amount)
12 |
13 | # Fader Timer
14 | self.timer = wx.Timer(self, wx.ID_ANY)
15 | self.timer.Start(60)
16 | self.Bind(wx.EVT_TIMER, self.AlphaCycle)
17 |
18 | def AlphaCycle(self, evt):
19 | """
20 | Fade the frame in and out
21 | """
22 | self.amount += self.delta
23 | if self.amount >= 255:
24 | self.delta = -self.delta
25 | self.amount = 255
26 | if self.amount <= 0:
27 | self.amount = 0
28 | self.delta = 5
29 | self.SetTransparent(self.amount)
30 |
31 | if __name__ == '__main__':
32 | app = wx.App(False)
33 | frm = Fader()
34 | frm.Show()
35 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_26_flashing_text/changing_text.py:
--------------------------------------------------------------------------------
1 | import random
2 | import time
3 | import wx
4 |
5 |
6 | class MyPanel(wx.Panel):
7 | """"""
8 |
9 | def __init__(self, parent):
10 | """Constructor"""
11 | wx.Panel.__init__(self, parent)
12 |
13 | self.font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
14 | self.flashingText = wx.StaticText(self, label="I flash a LOT!")
15 | self.flashingText.SetFont(self.font)
16 |
17 | self.timer = wx.Timer(self)
18 | self.Bind(wx.EVT_TIMER, self.update, self.timer)
19 | self.timer.Start(1000)
20 |
21 | def update(self, event):
22 | """"""
23 | now = int(time.time())
24 | mod = now % 2
25 | print (now)
26 | print (mod)
27 | if mod:
28 | self.flashingText.SetLabel("Current time: %i" % now)
29 | else:
30 | self.flashingText.SetLabel("Oops! It's mod zero time!")
31 | colors = ["blue", "green", "red", "yellow"]
32 | self.flashingText.SetForegroundColour(random.choice(colors))
33 |
34 |
35 | class MyFrame(wx.Frame):
36 | """"""
37 |
38 | def __init__(self):
39 | """Constructor"""
40 | wx.Frame.__init__(self, None, title="Flashing text!")
41 | panel = MyPanel(self)
42 | self.Show()
43 |
44 |
45 | if __name__ == "__main__":
46 | app = wx.App(False)
47 | frame = MyFrame()
48 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_26_flashing_text/flashing_text.py:
--------------------------------------------------------------------------------
1 | import random
2 | import time
3 | import wx
4 |
5 |
6 | class MyPanel(wx.Panel):
7 | """"""
8 |
9 | def __init__(self, parent):
10 | """Constructor"""
11 | wx.Panel.__init__(self, parent)
12 |
13 | self.font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
14 | self.label = "I flash a LOT!"
15 | self.flashingText = wx.StaticText(self, label=self.label)
16 | self.flashingText.SetFont(self.font)
17 |
18 | self.timer = wx.Timer(self)
19 | self.Bind(wx.EVT_TIMER, self.update, self.timer)
20 | self.timer.Start(1000)
21 |
22 | def update(self, event):
23 | """"""
24 | colors = ["blue", "green", "red", "yellow"]
25 | self.flashingText.SetLabel(self.label)
26 | self.flashingText.SetForegroundColour(random.choice(colors))
27 |
28 |
29 | class MyFrame(wx.Frame):
30 | """"""
31 |
32 | def __init__(self):
33 | """Constructor"""
34 | wx.Frame.__init__(self, None, title="Flashing text!")
35 | panel = MyPanel(self)
36 | self.Show()
37 |
38 |
39 | if __name__ == "__main__":
40 | app = wx.App(False)
41 | frame = MyFrame()
42 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_27_maximizing_frame/fullscreen.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyPanel(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """Constructor"""
9 | wx.Panel.__init__(self, parent)
10 |
11 | self.Bind(wx.EVT_KEY_DOWN, self.onKey)
12 |
13 | def onKey(self, event):
14 | """
15 | Check for ESC key press and exit is ESC is pressed
16 | """
17 | key_code = event.GetKeyCode()
18 | if key_code == wx.WXK_ESCAPE:
19 | self.GetParent().Close()
20 | else:
21 | event.Skip()
22 |
23 |
24 | class MyFrame(wx.Frame):
25 | """"""
26 |
27 | def __init__(self):
28 | """Constructor"""
29 | wx.Frame.__init__(self, None, title="Test FullScreen")
30 | panel = MyPanel(self)
31 | self.ShowFullScreen(True)
32 |
33 |
34 | if __name__ == "__main__":
35 | app = wx.App(False)
36 | frame = MyFrame()
37 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_27_maximizing_frame/maximize.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyPanel(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """"""
9 | wx.Panel.__init__(self, parent)
10 |
11 |
12 | class MyFrame(wx.Frame):
13 | """"""
14 |
15 | def __init__(self):
16 | """"""
17 | wx.Frame.__init__(self, None, title="Test Maximize")
18 | panel = MyPanel(self)
19 | self.Show()
20 | self.Maximize(True)
21 |
22 |
23 | if __name__ == "__main__":
24 | app = wx.App(False)
25 | frame = MyFrame()
26 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/default_frame.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class DefaultFrame(wx.Frame):
5 | """
6 | The default frame
7 | """
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | wx.Frame.__init__(self, None, title="Default Frame")
12 | panel = wx.Panel(self)
13 | self.Show()
14 |
15 |
16 | if __name__ == "__main__":
17 | app = wx.App(False)
18 | frame = DefaultFrame()
19 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/default_frame_2.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class DefaultFrame(wx.Frame):
5 | """
6 | The default frame
7 | """
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | wx.Frame.__init__(self, None, title="Default Frame",
12 | style=wx.DEFAULT_FRAME_STYLE)
13 | panel = wx.Panel(self)
14 | self.Show()
15 |
16 |
17 | if __name__ == "__main__":
18 | app = wx.App(False)
19 | frame = DefaultFrame()
20 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/default_frame_3.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class DefaultFrame(wx.Frame):
5 | """
6 | The default frame
7 | """
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | default = (wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER
12 | | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX
13 | | wx.CLIP_CHILDREN)
14 | wx.Frame.__init__(self, None, title="Default Frame", style=default)
15 | panel = wx.Panel(self)
16 | self.Show()
17 |
18 |
19 | if __name__ == "__main__":
20 | app = wx.App(False)
21 | frame = DefaultFrame()
22 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/disabled_close_btn.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class NoCloseFrame(wx.Frame):
5 | """
6 | This frame has no close box and the close menu is disabled
7 | """
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | no_close = (wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER
12 | | wx.SYSTEM_MENU | wx.CAPTION | wx.CLIP_CHILDREN)
13 | wx.Frame.__init__(self, None, title="No Close", style=no_close)
14 | panel = wx.Panel(self)
15 | self.Show()
16 |
17 |
18 | if __name__ == "__main__":
19 | app = wx.App(False)
20 | frame = NoCloseFrame()
21 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/no_caption.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class NoCaptionFrame(wx.Frame):
5 | """"""
6 |
7 | def __init__(self):
8 | """Constructor"""
9 | no_caption = (wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER
10 | | wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.CLIP_CHILDREN)
11 | wx.Frame.__init__(self, None, title="No Caption", style=no_caption)
12 | panel = wx.Panel(self)
13 | self.Show()
14 |
15 |
16 | if __name__ == "__main__":
17 | app = wx.App(False)
18 | frame = NoCaptionFrame()
19 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/no_max_min.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class NoMaxMinFrame(wx.Frame):
5 | """
6 | This frame does not have maximize or minimize buttons
7 | """
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | no_caption = (wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION
12 | | wx.CLOSE_BOX | wx.CLIP_CHILDREN
13 | | wx.FRAME_NO_TASKBAR)
14 | wx.Frame.__init__(self, None, title="No Max/Min", style=no_caption)
15 | panel = wx.Panel(self)
16 | self.Show()
17 |
18 |
19 | if __name__ == "__main__":
20 | app = wx.App(False)
21 | frame = NoMaxMinFrame()
22 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/no_resize.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class NoResizeFrame(wx.Frame):
5 | """
6 | This frame cannot be resized. It can only be minimized
7 | and closed
8 | """
9 |
10 | def __init__(self):
11 | """Constructor"""
12 | no_resize = wx.DEFAULT_FRAME_STYLE & ~ (wx.RESIZE_BORDER |
13 | wx.MAXIMIZE_BOX)
14 | wx.Frame.__init__(self, None, title="No Resize", style=no_resize)
15 | panel = wx.Panel(self)
16 | self.Show()
17 |
18 |
19 | if __name__ == "__main__":
20 | app = wx.App(False)
21 | frame = NoResizeFrame()
22 | app.MainLoop()
23 |
--------------------------------------------------------------------------------
/recipe_28_frame_styles/no_system_menu.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class NoSystemMenuFrame(wx.Frame):
5 | """
6 | There is no system menu, which means the title bar is there, but
7 | no buttons and no menu when clicking the top left hand corner
8 | of the frame
9 | """
10 |
11 | def __init__(self):
12 | """Constructor"""
13 | no_sys_menu = wx.CAPTION
14 | wx.Frame.__init__(self, None, title="No System Menu",
15 | style=no_sys_menu)
16 | panel = wx.Panel(self)
17 | self.Show()
18 |
19 |
20 | if __name__ == "__main__":
21 | app = wx.App(False)
22 | frame = NoSystemMenuFrame()
23 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_28_frame_styles/stay_on_top.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class StayOnTopFrame(wx.Frame):
5 | """
6 | A frame that stays on top of all the others
7 | """
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | on_top = wx.DEFAULT_FRAME_STYLE | wx.STAY_ON_TOP
12 | wx.Frame.__init__(self, None, title="Stay on top", style=on_top)
13 | panel = wx.Panel(self)
14 | self.Show()
15 |
16 |
17 | if __name__ == "__main__":
18 | app = wx.App(False)
19 | frame = StayOnTopFrame()
20 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_29_taskbar_icons/main_classic.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class PythonIcon(wx.TaskBarIcon):
5 | TBMENU_RESTORE = wx.NewId()
6 | TBMENU_CLOSE = wx.NewId()
7 | TBMENU_CHANGE = wx.NewId()
8 | TBMENU_REMOVE = wx.NewId()
9 |
10 | def __init__(self, frame):
11 | wx.TaskBarIcon.__init__(self)
12 | self.frame = frame
13 |
14 | # Set the image
15 | icon = wx.Icon('python.ico', wx.BITMAP_TYPE_ICO)
16 |
17 | self.SetIcon(icon, "Python")
18 |
19 | # bind some events
20 | self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE)
21 | self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.OnTaskBarLeftClick)
22 |
23 | def CreatePopupMenu(self, evt=None):
24 | """
25 | This method is called by the base class when it needs to popup
26 | the menu for the default EVT_RIGHT_DOWN event. Just create
27 | the menu how you want it and return it from this function,
28 | the base class takes care of the rest.
29 | """
30 | menu = wx.Menu()
31 | menu.Append(self.TBMENU_RESTORE, "Open Program")
32 | menu.Append(self.TBMENU_CHANGE, "Show all the Items")
33 | menu.AppendSeparator()
34 | menu.Append(self.TBMENU_CLOSE, "Exit Program")
35 | return menu
36 |
37 | def OnTaskBarActivate(self, evt):
38 | """"""
39 | pass
40 |
41 | def OnTaskBarClose(self, evt):
42 | """
43 | Destroy the taskbar icon and frame from the taskbar icon itself
44 | """
45 | self.frame.Close()
46 |
47 | def OnTaskBarLeftClick(self, evt):
48 | """
49 | Create the right-click menu
50 | """
51 | menu = self.CreatePopupMenu()
52 | self.PopupMenu(menu)
53 | menu.Destroy()
54 |
55 |
56 | class MyForm(wx.Frame):
57 |
58 | def __init__(self):
59 | wx.Frame.__init__(self, None, title="TaskBarIcon Tutorial",
60 | size=(500,500))
61 | panel = wx.Panel(self)
62 | self.tbIcon = PythonIcon(self)
63 | self.Bind(wx.EVT_CLOSE, self.onClose)
64 |
65 | def onClose(self, evt):
66 | """
67 | Destroy the taskbar icon and the frame
68 | """
69 | self.tbIcon.RemoveIcon()
70 | self.tbIcon.Destroy()
71 | self.Destroy()
72 |
73 |
74 | if __name__ == "__main__":
75 | app = wx.App(False)
76 | frame = MyForm().Show()
77 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_29_taskbar_icons/main_phoenix.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.adv
3 |
4 | class PythonIcon(wx.adv.TaskBarIcon):
5 | TBMENU_RESTORE = wx.NewId()
6 | TBMENU_CLOSE = wx.NewId()
7 | TBMENU_CHANGE = wx.NewId()
8 | TBMENU_REMOVE = wx.NewId()
9 |
10 | def __init__(self, frame):
11 | wx.adv.TaskBarIcon.__init__(self)
12 | self.frame = frame
13 |
14 | # Set the image
15 | icon = wx.Icon('python.ico', wx.BITMAP_TYPE_ICO)
16 |
17 | self.SetIcon(icon, "Python")
18 |
19 | # bind some events
20 | self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE)
21 | self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.OnTaskBarLeftClick)
22 |
23 | def CreatePopupMenu(self, evt=None):
24 | """
25 | This method is called by the base class when it needs to popup
26 | the menu for the default EVT_RIGHT_DOWN event. Just create
27 | the menu how you want it and return it from this function,
28 | the base class takes care of the rest.
29 | """
30 | menu = wx.Menu()
31 | menu.Append(self.TBMENU_RESTORE, "Open Program")
32 | menu.Append(self.TBMENU_CHANGE, "Show all the Items")
33 | menu.AppendSeparator()
34 | menu.Append(self.TBMENU_CLOSE, "Exit Program")
35 | return menu
36 |
37 | def OnTaskBarActivate(self, evt):
38 | """"""
39 | pass
40 |
41 | def OnTaskBarClose(self, evt):
42 | """
43 | Destroy the taskbar icon and frame from the taskbar icon itself
44 | """
45 | self.frame.Close()
46 |
47 | def OnTaskBarLeftClick(self, evt):
48 | """
49 | Create the right-click menu
50 | """
51 | menu = self.CreatePopupMenu()
52 | self.PopupMenu(menu)
53 | menu.Destroy()
54 |
55 |
56 | class MyForm(wx.Frame):
57 |
58 | def __init__(self):
59 | wx.Frame.__init__(self, None, title="TaskBarIcon Tutorial",
60 | size=(500,500))
61 | panel = wx.Panel(self)
62 | self.tbIcon = PythonIcon(self)
63 | self.Bind(wx.EVT_CLOSE, self.onClose)
64 |
65 | def onClose(self, evt):
66 | """
67 | Destroy the taskbar icon and the frame
68 | """
69 | self.tbIcon.RemoveIcon()
70 | self.tbIcon.Destroy()
71 | self.Destroy()
72 |
73 |
74 | if __name__ == "__main__":
75 | app = wx.App(False)
76 | frame = MyForm().Show()
77 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_29_taskbar_icons/python.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_29_taskbar_icons/python.ico
--------------------------------------------------------------------------------
/recipe_2_screenshots/main.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import wx
3 | import snapshotPrinter
4 |
5 | class MyForm(wx.Frame):
6 |
7 | def __init__(self):
8 | wx.Frame.__init__(self, None, title="Screenshot Tutorial")
9 |
10 | panel = wx.Panel(self)
11 | screenshotBtn = wx.Button(panel, label="Take Screenshot")
12 | screenshotBtn.Bind(wx.EVT_BUTTON, self.onTakeScreenShot)
13 | printBtn = wx.Button(panel, label="Print Screenshot")
14 | printBtn.Bind(wx.EVT_BUTTON, self.onPrint)
15 |
16 | sizer = wx.BoxSizer(wx.HORIZONTAL)
17 | sizer.Add(screenshotBtn, 0, wx.ALL|wx.CENTER, 5)
18 | sizer.Add(printBtn, 0, wx.ALL|wx.CENTER, 5)
19 | panel.SetSizer(sizer)
20 |
21 | def onTakeScreenShot(self, event):
22 | """
23 | Takes a screenshot of the screen at give pos & size (rect).
24 |
25 | Method based on a script by Andrea Gavana
26 | """
27 | print('Taking screenshot...')
28 | rect = self.GetRect()
29 |
30 | # adjust widths for Linux (figured out by John Torres
31 | # http://article.gmane.org/gmane.comp.python.wxpython/67327)
32 | if sys.platform == 'linux2':
33 | client_x, client_y = self.ClientToScreen((0, 0))
34 | border_width = client_x - rect.x
35 | title_bar_height = client_y - rect.y
36 | rect.width += (border_width * 2)
37 | rect.height += title_bar_height + border_width
38 |
39 | # Create a DC for the whole screen area
40 | dcScreen = wx.ScreenDC()
41 |
42 | # Create a Bitmap that will hold the screenshot image later on
43 | # Note that the Bitmap must have a size big enough to hold the screenshot
44 | # -1 means using the current default colour depth
45 | bmp = wx.EmptyBitmap(rect.width, rect.height)
46 |
47 | #Create a memory DC that will be used for actually taking the screenshot
48 | memDC = wx.MemoryDC()
49 |
50 | # Tell the memory DC to use our Bitmap
51 | # all drawing action on the memory DC will go to the Bitmap now
52 | memDC.SelectObject(bmp)
53 |
54 | # Blit (in this case copy) the actual screen on the memory DC
55 | # and thus the Bitmap
56 | memDC.Blit( 0, # Copy to this X coordinate
57 | 0, # Copy to this Y coordinate
58 | rect.width, # Copy this width
59 | rect.height, # Copy this height
60 | dcScreen, # Where to copy from
61 | rect.x, # What's the X offset in the original DC?
62 | rect.y # What's the Y offset in the original DC?
63 | )
64 |
65 | # Select the Bitmap out of the memory DC by selecting a new
66 | # uninitialized Bitmap
67 | memDC.SelectObject(wx.NullBitmap)
68 |
69 | img = bmp.ConvertToImage()
70 | fileName = "myImage.png"
71 | img.SaveFile(fileName, wx.BITMAP_TYPE_PNG)
72 | print('...saving as png!')
73 |
74 | def onPrint(self, event):
75 | """
76 | Send screenshot to the printer
77 | """
78 | printer = snapshotPrinter.SnapshotPrinter()
79 | printer.sendToPrinter()
80 |
81 | # Run the program
82 | if __name__ == "__main__":
83 | app = wx.App(False)
84 | frame = MyForm()
85 | frame.Show()
86 | app.MainLoop()
87 |
--------------------------------------------------------------------------------
/recipe_2_screenshots/myImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_2_screenshots/myImage.png
--------------------------------------------------------------------------------
/recipe_2_screenshots/screenshot.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/recipe_2_screenshots/snapshotPrinter.py:
--------------------------------------------------------------------------------
1 | # snapshotPrinter.py
2 |
3 | import os
4 | import wx
5 | from wx.html import HtmlEasyPrinting, HtmlWindow
6 |
7 | class SnapshotPrinter(wx.Frame):
8 |
9 | def __init__(self, title='Snapshot Printer'):
10 | wx.Frame.__init__(self, None, title=title,
11 | size=(650,400))
12 |
13 | self.panel = wx.Panel(self)
14 | self.printer = HtmlEasyPrinting(
15 | name='Printing', parentWindow=None)
16 |
17 | self.html = HtmlWindow(self.panel)
18 | self.html.SetRelatedFrame(self, self.GetTitle())
19 |
20 | if not os.path.exists('screenshot.htm'):
21 | self.createHtml()
22 | self.html.LoadPage('screenshot.htm')
23 |
24 | pageSetupBtn = wx.Button(self.panel, label='Page Setup')
25 | printBtn = wx.Button(self.panel, label='Print')
26 | cancelBtn = wx.Button(self.panel, label='Cancel')
27 |
28 | self.Bind(wx.EVT_BUTTON, self.onSetup, pageSetupBtn)
29 | self.Bind(wx.EVT_BUTTON, self.onPrint, printBtn)
30 | self.Bind(wx.EVT_BUTTON, self.onCancel, cancelBtn)
31 |
32 | sizer = wx.BoxSizer(wx.VERTICAL)
33 | btnSizer = wx.BoxSizer(wx.HORIZONTAL)
34 |
35 | sizer.Add(self.html, 1, wx.GROW)
36 | btnSizer.Add(pageSetupBtn, 0, wx.ALL, 5)
37 | btnSizer.Add(printBtn, 0, wx.ALL, 5)
38 | btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
39 | sizer.Add(btnSizer)
40 |
41 | self.panel.SetSizer(sizer)
42 | self.panel.SetAutoLayout(True)
43 |
44 | def createHtml(self):
45 | '''
46 | Creates an html file in the home directory of the application
47 | that contains the information to display the snapshot
48 | '''
49 | print('creating html...')
50 |
51 | html = '''\n\n
52 |
53 | \n\n'''
54 | with open('screenshot.htm', 'w') as fobj:
55 | fobj.write(html)
56 |
57 | def onSetup(self, event):
58 | self.printer.PageSetup()
59 |
60 | def onPrint(self, event):
61 | self.sendToPrinter()
62 |
63 | def sendToPrinter(self):
64 | self.printer.GetPrintData().SetPaperId(wx.PAPER_LETTER)
65 | self.printer.PrintFile(self.html.GetOpenedPage())
66 |
67 | def onCancel(self, event):
68 | self.Close()
69 |
70 |
71 | if __name__ == '__main__':
72 | app = wx.App(False)
73 | frame = SnapshotPrinter()
74 | frame.Show()
75 | app.MainLoop()
76 |
--------------------------------------------------------------------------------
/recipe_30_minimize_to_tray/custTray.py:
--------------------------------------------------------------------------------
1 | # custTray.py
2 |
3 | import wx
4 |
5 |
6 | class CustomTaskBarIcon(wx.TaskBarIcon):
7 | """"""
8 |
9 | def __init__(self, frame):
10 | """Constructor"""
11 | wx.TaskBarIcon.__init__(self)
12 | self.frame = frame
13 |
14 | icon = wx.Icon('python.ico', wx.BITMAP_TYPE_ICO)
15 |
16 | self.SetIcon(icon, "Restore")
17 |
18 | self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.OnTaskBarLeftClick)
19 |
20 | def OnTaskBarActivate(self, evt):
21 | """"""
22 | pass
23 |
24 | def OnTaskBarClose(self, evt):
25 | """
26 | Destroy the taskbar icon and frame from the taskbar icon itself
27 | """
28 | self.frame.Close()
29 |
30 | def OnTaskBarLeftClick(self, evt):
31 | """
32 | Create the right-click menu
33 | """
34 | self.frame.Show()
35 | self.frame.Restore()
--------------------------------------------------------------------------------
/recipe_30_minimize_to_tray/custTray_phoenix.py:
--------------------------------------------------------------------------------
1 | # custTray_phoenix.py
2 |
3 | import wx
4 | import wx.adv
5 |
6 |
7 | class CustomTaskBarIcon(wx.adv.TaskBarIcon):
8 | """"""
9 |
10 | def __init__(self, frame):
11 | """Constructor"""
12 | wx.adv.TaskBarIcon.__init__(self)
13 | self.frame = frame
14 |
15 | icon = wx.Icon('python.ico', wx.BITMAP_TYPE_ICO)
16 |
17 | self.SetIcon(icon, "Restore")
18 |
19 | self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.OnTaskBarLeftClick)
20 |
21 | def OnTaskBarActivate(self, evt):
22 | """"""
23 | pass
24 |
25 | def OnTaskBarClose(self, evt):
26 | """
27 | Destroy the taskbar icon and frame from the taskbar icon itself
28 | """
29 | self.frame.Close()
30 |
31 | def OnTaskBarLeftClick(self, evt):
32 | """
33 | Create the right-click menu
34 | """
35 | self.frame.Show()
36 | self.frame.Restore()
--------------------------------------------------------------------------------
/recipe_30_minimize_to_tray/main_classic.py:
--------------------------------------------------------------------------------
1 | import custTray
2 | import wx
3 |
4 |
5 | class MainFrame(wx.Frame):
6 | """"""
7 |
8 | def __init__(self):
9 | """Constructor"""
10 | wx.Frame.__init__(self, None, title="Minimize to Tray")
11 | panel = wx.Panel(self)
12 | self.tbIcon = custTray.CustomTaskBarIcon(self)
13 |
14 | self.Bind(wx.EVT_ICONIZE, self.onMinimize)
15 | self.Bind(wx.EVT_CLOSE, self.onClose)
16 |
17 | self.Show()
18 |
19 | def onClose(self, evt):
20 | """
21 | Destroy the taskbar icon and the frame
22 | """
23 | self.tbIcon.RemoveIcon()
24 | self.tbIcon.Destroy()
25 | self.Destroy()
26 |
27 | def onMinimize(self, event):
28 | """
29 | When minimizing, hide the frame so it "minimizes to tray"
30 | """
31 | if self.IsIconized():
32 | self.Hide()
33 |
34 |
35 | def main():
36 | """"""
37 | app = wx.App(False)
38 | frame = MainFrame()
39 | app.MainLoop()
40 |
41 | if __name__ == "__main__":
42 | main()
--------------------------------------------------------------------------------
/recipe_30_minimize_to_tray/main_phoenix.py:
--------------------------------------------------------------------------------
1 | import custTray_phoenix as custTray
2 | import wx
3 |
4 |
5 | class MainFrame(wx.Frame):
6 | """"""
7 |
8 | def __init__(self):
9 | """Constructor"""
10 | wx.Frame.__init__(self, None, title="Minimize to Tray")
11 | panel = wx.Panel(self)
12 | self.tbIcon = custTray.CustomTaskBarIcon(self)
13 |
14 | self.Bind(wx.EVT_ICONIZE, self.onMinimize)
15 | self.Bind(wx.EVT_CLOSE, self.onClose)
16 |
17 | self.Show()
18 |
19 | def onClose(self, evt):
20 | """
21 | Destroy the taskbar icon and the frame
22 | """
23 | self.tbIcon.RemoveIcon()
24 | self.tbIcon.Destroy()
25 | self.Destroy()
26 |
27 | def onMinimize(self, event):
28 | """
29 | When minimizing, hide the frame so it "minimizes to tray"
30 | """
31 | if self.IsIconized():
32 | self.Hide()
33 |
34 |
35 | def main():
36 | """"""
37 | app = wx.App(False)
38 | frame = MainFrame()
39 | app.MainLoop()
40 |
41 | if __name__ == "__main__":
42 | main()
--------------------------------------------------------------------------------
/recipe_30_minimize_to_tray/python.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_30_minimize_to_tray/python.ico
--------------------------------------------------------------------------------
/recipe_31_children_from_sizers/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyApp(wx.Frame):
5 | """"""
6 |
7 | def __init__(self):
8 | """Constructor"""
9 | title = 'Get Children from Sizer'
10 | wx.Frame.__init__(self, None, title=title)
11 | panel = wx.Panel(self)
12 |
13 | lbl = wx.StaticText(panel, label="I'm a label!")
14 | txt = wx.TextCtrl(panel, value="blah blah")
15 | btn = wx.Button(panel, label="Clear")
16 | btn.Bind(wx.EVT_BUTTON, self.onClear)
17 |
18 | self.sizer = wx.BoxSizer(wx.VERTICAL)
19 | self.sizer.Add(lbl, 0, wx.ALL, 5)
20 | self.sizer.Add(txt, 0, wx.ALL, 5)
21 | self.sizer.Add(btn, 0, wx.ALL, 5)
22 |
23 | panel.SetSizer(self.sizer)
24 |
25 | def onClear(self, event):
26 | """
27 | Button event handler for clearing TextCtrl widgets
28 | """
29 | children = self.sizer.GetChildren()
30 |
31 | for child in children:
32 | widget = child.GetWindow()
33 | print widget
34 | if isinstance(widget, wx.TextCtrl):
35 | widget.Clear()
36 |
37 |
38 | if __name__ == "__main__":
39 | app = wx.App(False)
40 | frame = MyApp()
41 | frame.Show()
42 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_32_clipboard/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class ClipboardPanel(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """Constructor"""
9 | wx.Panel.__init__(self, parent)
10 |
11 | lbl = wx.StaticText(self, label="Enter text to copy to clipboard:")
12 | self.text = wx.TextCtrl(self, style=wx.TE_MULTILINE)
13 | copyBtn = wx.Button(self, label="Copy")
14 | copyBtn.Bind(wx.EVT_BUTTON, self.onCopy)
15 | copyFlushBtn = wx.Button(self, label="Copy and Flush")
16 | copyFlushBtn.Bind(wx.EVT_BUTTON, self.onCopyAndFlush)
17 |
18 | sizer = wx.BoxSizer(wx.VERTICAL)
19 | sizer.Add(lbl, 0, wx.ALL, 5)
20 | sizer.Add(self.text, 1, wx.EXPAND)
21 | sizer.Add(copyBtn, 0, wx.ALL|wx.CENTER, 5)
22 | sizer.Add(copyFlushBtn, 0, wx.ALL|wx.CENTER, 5)
23 | self.SetSizer(sizer)
24 |
25 | def onCopy(self, event):
26 | """"""
27 | self.dataObj = wx.TextDataObject()
28 | self.dataObj.SetText(self.text.GetValue())
29 | if wx.TheClipboard.Open():
30 | wx.TheClipboard.SetData(self.dataObj)
31 | wx.TheClipboard.Close()
32 | else:
33 | wx.MessageBox("Unable to open the clipboard", "Error")
34 |
35 | def onCopyAndFlush(self, event):
36 | """
37 | Copy to the clipboard and close the application
38 | """
39 | self.dataObj = wx.TextDataObject()
40 | self.dataObj.SetText(self.text.GetValue())
41 | if wx.TheClipboard.Open():
42 | wx.TheClipboard.SetData(self.dataObj)
43 | wx.TheClipboard.Flush()
44 | else:
45 | wx.MessageBox("Unable to open the clipboard", "Error")
46 |
47 | self.GetParent().Close()
48 |
49 |
50 | class ClipboardFrame(wx.Frame):
51 | """"""
52 |
53 | def __init__(self):
54 | """Constructor"""
55 | wx.Frame.__init__(self, None, title="Clipboard Tutorial")
56 | panel = ClipboardPanel(self)
57 | self.Show()
58 |
59 |
60 | if __name__ == "__main__":
61 | app = wx.App(False)
62 | frame = ClipboardFrame()
63 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_33_focus/acquire_focus.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title="Focus Tutorial 1")
7 |
8 |
9 | panel = wx.Panel(self)
10 | panel.Bind(wx.EVT_SET_FOCUS, self.onFocus)
11 |
12 | def onFocus(self, event):
13 | print("panel received focus!")
14 |
15 | # Run the program
16 | if __name__ == "__main__":
17 | app = wx.App(False)
18 | frame = MyForm().Show()
19 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_33_focus/acquire_focus_2.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title="Focus Tutorial 1a")
7 |
8 | panel = wx.Panel(self)
9 | panel.Bind(wx.EVT_SET_FOCUS, self.onFocus)
10 | txt = wx.TextCtrl(panel, wx.ID_ANY, "")
11 |
12 | def onFocus(self, event):
13 | print("panel received focus!")
14 |
15 |
16 | if __name__ == "__main__":
17 | app = wx.App(False)
18 | frame = MyForm().Show()
19 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_33_focus/focus_finder.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title="Focus Finder")
7 |
8 | panel = wx.Panel(self, wx.ID_ANY)
9 | panel.Bind(wx.EVT_SET_FOCUS, self.onFocus)
10 | txt = wx.StaticText(
11 | panel, label="This label cannot receive focus")
12 |
13 | self.timer = wx.Timer(self)
14 | self.Bind(wx.EVT_TIMER, self.onTimer)
15 | self.timer.Start(1000)
16 |
17 | def onFocus(self, event):
18 | print("panel received focus!")
19 |
20 | def onTimer(self, evt):
21 | print('Focused window:', wx.Window.FindFocus())
22 |
23 |
24 | if __name__ == "__main__":
25 | app = wx.App(False)
26 | frame = MyForm().Show()
27 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_33_focus/losing_focus.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title="Losing Focus")
7 |
8 | # Add a panel so it looks the correct on all platforms
9 | panel = wx.Panel(self, wx.ID_ANY)
10 |
11 | txt = wx.TextCtrl(panel, value="")
12 | txt.Bind(wx.EVT_SET_FOCUS, self.onFocus)
13 | txt.Bind(wx.EVT_KILL_FOCUS, self.onKillFocus)
14 | btn = wx.Button(panel, wx.ID_ANY, "Test")
15 |
16 | sizer = wx.BoxSizer(wx.VERTICAL)
17 | sizer.Add(txt, 0, wx.ALL, 5)
18 | sizer.Add(btn, 0, wx.ALL, 5)
19 | panel.SetSizer(sizer)
20 |
21 | def onFocus(self, event):
22 | print("widget received focus!")
23 |
24 | def onKillFocus(self, event):
25 | print("widget lost focus!")
26 |
27 |
28 | if __name__ == "__main__":
29 | app = wx.App(False)
30 | frame = MyForm().Show()
31 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_34_url_shortening/ars_example.py:
--------------------------------------------------------------------------------
1 | import re
2 | import urllib
3 | import urllib2
4 | import wx
5 |
6 | class ArsShortener(wx.Frame):
7 |
8 | def __init__(self):
9 | wx.Frame.__init__(self, None, wx.ID_ANY,
10 | 'wxArsShortener', size=(300,70))
11 |
12 | # Add a panel so it looks the correct on all platforms
13 | panel = wx.Panel(self, wx.ID_ANY)
14 |
15 | self.txt = wx.TextCtrl(panel, wx.ID_ANY, "", size=(300, -1))
16 | self.txt.Bind(wx.EVT_TEXT, self.onTextChange)
17 |
18 | sizer = wx.BoxSizer(wx.VERTICAL)
19 | sizer.Add(self.txt, 0, wx.EXPAND, 5)
20 | panel.SetSizer(sizer)
21 |
22 | def onTextChange(self, event):
23 | """"""
24 | text = self.txt.GetValue()
25 | textLength = len(text)
26 | if re.match("^https?://[^ ]+", text) and textLength > 20:
27 | apiURL = "http://is.gd/api.php?" + urllib.urlencode(dict(longURL=text))
28 | shortened_URL = urllib2.urlopen(apiURL).read()
29 | self.txt.SetValue(shortened_URL)
30 |
31 | if __name__ == '__main__':
32 | app = wx.App(False)
33 | frame = ArsShortener()
34 | frame.Show()
35 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_34_url_shortening/ars_example_py3.py:
--------------------------------------------------------------------------------
1 | # Python 3
2 |
3 | import re
4 | import urllib.parse
5 | import urllib.request
6 | import wx
7 |
8 | class ArsShortener(wx.Frame):
9 |
10 | def __init__(self):
11 | wx.Frame.__init__(self, None, wx.ID_ANY,
12 | 'wxArsShortener', size=(300,70))
13 |
14 | # Add a panel so it looks the correct on all platforms
15 | panel = wx.Panel(self, wx.ID_ANY)
16 |
17 | self.txt = wx.TextCtrl(panel, wx.ID_ANY, "", size=(300, -1))
18 | self.txt.Bind(wx.EVT_TEXT, self.onTextChange)
19 |
20 | sizer = wx.BoxSizer(wx.VERTICAL)
21 | sizer.Add(self.txt, 0, wx.EXPAND, 5)
22 | panel.SetSizer(sizer)
23 |
24 | def onTextChange(self, event):
25 | """"""
26 | text = self.txt.GetValue()
27 | textLength = len(text)
28 | if re.match("^https?://[^ ]+", text) and textLength > 20:
29 | apiURL = "http://is.gd/api.php?" + urllib.parse.urlencode(dict(longURL=text))
30 |
31 | shortened_URL = urllib.request.urlopen(apiURL).read()
32 | self.txt.SetValue(shortened_URL)
33 |
34 | if __name__ == '__main__':
35 | app = wx.App(False)
36 | frame = ArsShortener()
37 | frame.Show()
38 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_34_url_shortening/shortening_py2.py:
--------------------------------------------------------------------------------
1 | import re
2 | import urllib
3 | import urllib2
4 | import wx
5 |
6 | bitlyFlag = True
7 | tinyURLFlag = True
8 |
9 | try:
10 | import bitly
11 | except ImportError:
12 | bitlyFlag = False
13 |
14 | try:
15 | import tinyurl
16 | except ImportError:
17 | tinyURLFlag = False
18 |
19 |
20 | class MainPanel(wx.Panel):
21 | """
22 | """
23 |
24 | def __init__(self, parent):
25 | """Constructor"""
26 | wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
27 | self.frame = parent
28 |
29 | # create the widgets
30 | self.createLayout()
31 |
32 | def createLayout(self):
33 | """
34 | Create widgets and lay them out
35 | """
36 | choices = ["is.gd"]
37 | if bitlyFlag:
38 | choices.append("bit.ly")
39 | if tinyURLFlag:
40 | choices.append("tinyURL")
41 | choices.sort()
42 |
43 | # create the widgets
44 | self.URLCbo = wx.ComboBox(self, wx.ID_ANY, "is.gd",
45 | choices=choices,
46 | size=wx.DefaultSize,
47 | style=wx.CB_DROPDOWN)
48 | self.inputURLTxt = wx.TextCtrl(self, value="Paste long URL here")
49 | self.inputURLTxt.Bind(wx.EVT_SET_FOCUS, self.onFocus)
50 | self.outputURLTxt = wx.TextCtrl(self, style=wx.TE_READONLY)
51 |
52 | shortenBtn = wx.Button(self, label="Shorten URL")
53 | shortenBtn.Bind(wx.EVT_BUTTON, self.onShorten)
54 | copyBtn = wx.Button(self, label="Copy to Clipboard")
55 | copyBtn.Bind(wx.EVT_BUTTON, self.onCopy)
56 |
57 | # create the sizers
58 | mainSizer = wx.BoxSizer(wx.VERTICAL)
59 | btnSizer = wx.BoxSizer(wx.HORIZONTAL)
60 |
61 | # layout the widgets
62 | mainSizer.Add(self.URLCbo, 0, wx.ALL, 5)
63 | mainSizer.Add(self.inputURLTxt, 0,
64 | wx.ALL|wx.EXPAND, 5)
65 | mainSizer.Add(self.outputURLTxt, 0,
66 | wx.ALL|wx.EXPAND, 5)
67 | btnSizer.Add(shortenBtn, 0, wx.ALL|wx.CENTER, 5)
68 | btnSizer.Add(copyBtn, 0, wx.ALL|wx.CENTER, 5)
69 | mainSizer.Add(btnSizer, 0, wx.ALL|wx.CENTER, 5)
70 | self.SetSizer(mainSizer)
71 |
72 | def onCopy(self, event):
73 | """
74 | Copies data to the clipboard or displays an error
75 | dialog if the clipboard is inaccessible.
76 | """
77 | text = self.outputURLTxt.GetValue()
78 | self.do = wx.TextDataObject()
79 | self.do.SetText(text)
80 | if wx.TheClipboard.Open():
81 | wx.TheClipboard.SetData(self.do)
82 | wx.TheClipboard.Close()
83 | status = "Copied %s to clipboard" % text
84 | self.frame.statusbar.SetStatusText(status)
85 | else:
86 | wx.MessageBox("Unable to open the clipboard", "Error")
87 |
88 | def onFocus(self, event):
89 | """
90 | When control is given the focus, it is cleared
91 | """
92 | self.inputURLTxt.SetValue("")
93 |
94 | def onShorten(self, event):
95 | """
96 | Shortens a URL using the service specified.
97 | Then sets the text control to the new URL.
98 | """
99 | text = self.inputURLTxt.GetValue()
100 | textLength = len(text)
101 |
102 | if re.match("^https?://[^ ]+", text) and textLength > 20:
103 | pass
104 | else:
105 | wx.MessageBox("URL is already tiny!", "Error")
106 | return
107 |
108 | URL = self.URLCbo.GetValue()
109 | if URL == "is.gd":
110 | self.shortenWithIsGd(text)
111 | elif URL == "bit.ly":
112 | self.shortenWithBitly(text)
113 | elif URL == "tinyurl":
114 | self.shortenWithTinyURL(text)
115 |
116 | def shortenWithBitly(self, text):
117 | """
118 | Shortens the URL in the text control using bit.ly
119 |
120 | Requires a bit.ly account and API key
121 | """
122 | bitly.API_LOGIN = "username"
123 | bitly.API_KEY = "api_key"
124 | URL = bitly.shorten(text)
125 | self.outputURLTxt.SetValue(URL)
126 |
127 | def shortenWithIsGd(self, text):
128 | """
129 | Shortens the URL with is.gd using URLlib and URLlib2
130 | """
131 |
132 | apiURL = "http://is.gd/api.php?" + urllib.urlencode(dict(longURL=text))
133 | shortURL = urllib2.urlopen(apiURL).read()
134 | self.outputURLTxt.SetValue(shortURL)
135 |
136 | def shortenWithTinyURL(self, text):
137 | """
138 | Shortens the URL with tinyURL
139 | """
140 | print "in tinyurl"
141 | URL = tinyurl.create_one(text)
142 | self.outputURLTxt.SetValue(URL)
143 |
144 |
145 | class URLFrame(wx.Frame):
146 | """
147 | wx.Frame class
148 | """
149 |
150 | def __init__(self):
151 | """Constructor"""
152 | title = "URL Shortener"
153 | wx.Frame.__init__(self, None, wx.ID_ANY,
154 | title=title, size=(650, 220))
155 | panel = MainPanel(self)
156 | self.statusbar = self.CreateStatusBar()
157 | self.SetMinSize((650, 220))
158 |
159 |
160 | if __name__ == "__main__":
161 | app = wx.App(False)
162 | frame = URLFrame()
163 | frame.Show()
164 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_35_using_objectlistview/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from ObjectListView import ObjectListView, ColumnDefn
3 |
4 |
5 | class Book(object):
6 | """
7 | Model of the Book object
8 |
9 | Contains the following attributes:
10 | 'ISBN', 'Author', 'Manufacturer', 'Title'
11 | """
12 |
13 | def __init__(self, title, author, isbn, mfg):
14 | self.isbn = isbn
15 | self.author = author
16 | self.mfg = mfg
17 | self.title = title
18 |
19 | class MainPanel(wx.Panel):
20 |
21 | def __init__(self, parent):
22 | wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
23 | self.products = [Book("wxPython in Action", "Robin Dunn",
24 | "1932394621", "Manning"),
25 | Book("Hello World", "Warren and Carter Sande",
26 | "1933988495", "Manning")
27 | ]
28 |
29 | self.dataOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
30 | self.setBooks()
31 |
32 | # Allow the cell values to be edited when double-clicked
33 | self.dataOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK
34 |
35 | # create an update button
36 | updateBtn = wx.Button(self, wx.ID_ANY, "Update OLV")
37 | updateBtn.Bind(wx.EVT_BUTTON, self.updateControl)
38 |
39 | # Create some sizers
40 | mainSizer = wx.BoxSizer(wx.VERTICAL)
41 |
42 | mainSizer.Add(self.dataOlv, 1, wx.ALL|wx.EXPAND, 5)
43 | mainSizer.Add(updateBtn, 0, wx.ALL|wx.CENTER, 5)
44 | self.SetSizer(mainSizer)
45 |
46 |
47 | def updateControl(self, event):
48 | """
49 | Update the object list view widget
50 | """
51 | print "updating..."
52 | product_dict = [{"title":"Core Python Programming", "author":"Wesley Chun",
53 | "isbn":"0132269937", "mfg":"Prentice Hall"},
54 | {"title":"Python Programming for the Absolute Beginner",
55 | "author":"Michael Dawson", "isbn":"1598631128",
56 | "mfg":"Course Technology"},
57 | {"title":"Learning Python", "author":"Mark Lutz",
58 | "isbn":"0596513984", "mfg":"O'Reilly"}
59 | ]
60 | data = self.products + product_dict
61 | self.dataOlv.SetObjects(data)
62 |
63 |
64 | def setBooks(self, data=None):
65 | self.dataOlv.SetColumns([
66 | ColumnDefn("Title", "left", 220, "title"),
67 | ColumnDefn("Author", "left", 200, "author"),
68 | ColumnDefn("ISBN", "right", 100, "isbn"),
69 | ColumnDefn("Mfg", "left", 180, "mfg")
70 | ])
71 |
72 | self.dataOlv.SetObjects(self.products)
73 |
74 |
75 | class MainFrame(wx.Frame):
76 |
77 | def __init__(self):
78 | wx.Frame.__init__(self, parent=None, id=wx.ID_ANY,
79 | title="ObjectListView Demo", size=(800,600))
80 | panel = MainPanel(self)
81 |
82 |
83 | class GenApp(wx.App):
84 |
85 | def __init__(self, redirect=False, filename=None):
86 | wx.App.__init__(self, redirect, filename)
87 |
88 |
89 | def OnInit(self):
90 | # create frame here
91 | frame = MainFrame()
92 | frame.Show()
93 | return True
94 |
95 |
96 | def main():
97 | """
98 | Run the demo
99 | """
100 | app = GenApp()
101 | app.MainLoop()
102 |
103 | if __name__ == "__main__":
104 | main()
--------------------------------------------------------------------------------
/recipe_36_panel_destruction/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class PanelOne(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """Constructor"""
9 | wx.Panel.__init__(self, parent)
10 |
11 | msg = "This panel will self-destruct in 10 seconds"
12 | self.countdown = wx.StaticText(self, label=msg)
13 |
14 |
15 | class PanelTwo(wx.Panel):
16 | """"""
17 |
18 | def __init__(self, parent):
19 | """Constructor"""
20 | wx.Panel.__init__(self, parent)
21 |
22 | txt = wx.StaticText(self, label="Panel Two")
23 |
24 |
25 | class MainFrame(wx.Frame):
26 | """"""
27 |
28 | def __init__(self):
29 | """Constructor"""
30 | wx.Frame.__init__(self, None, title="Panel Smacker")
31 | self.panelOne = PanelOne(self)
32 | self.time2die = 10
33 |
34 | self.timer = wx.Timer(self)
35 | self.Bind(wx.EVT_TIMER, self.update, self.timer)
36 | self.timer.Start(1000)
37 |
38 | self.sizer = wx.BoxSizer(wx.VERTICAL)
39 | self.sizer.Add(self.panelOne, 1, wx.EXPAND)
40 | self.SetSizer(self.sizer)
41 |
42 | def update(self, event):
43 | """"""
44 | if self.time2die < 0:
45 | self.panelOne.Destroy()
46 | self.panelTwo = PanelTwo(self)
47 | self.sizer.Add(self.panelTwo, 1, wx.EXPAND)
48 | self.Layout()
49 | self.timer.Stop()
50 | else:
51 | msg = "This panel will self-destruct in %s seconds" % self.time2die
52 | self.panelOne.countdown.SetLabel(msg)
53 | self.time2die -= 1
54 |
55 |
56 | if __name__ == "__main__":
57 | app = wx.App(False)
58 | frame = MainFrame()
59 | frame.Show()
60 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_37_panel_switching/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.grid as gridlib
3 |
4 |
5 | class PanelOne(wx.Panel):
6 | """"""
7 |
8 | def __init__(self, parent):
9 | """Constructor"""
10 | wx.Panel.__init__(self, parent=parent)
11 | txt = wx.TextCtrl(self)
12 |
13 |
14 | class PanelTwo(wx.Panel):
15 | """"""
16 |
17 | def __init__(self, parent):
18 | """Constructor"""
19 | wx.Panel.__init__(self, parent=parent)
20 |
21 | grid = gridlib.Grid(self)
22 | grid.CreateGrid(25,12)
23 |
24 | sizer = wx.BoxSizer(wx.VERTICAL)
25 | sizer.Add(grid, 0, wx.EXPAND)
26 | self.SetSizer(sizer)
27 |
28 |
29 | class MyForm(wx.Frame):
30 |
31 | def __init__(self):
32 | wx.Frame.__init__(self, None, wx.ID_ANY,
33 | "Panel Switcher Tutorial")
34 |
35 | self.panel_one = PanelOne(self)
36 | self.panel_two = PanelTwo(self)
37 | self.panel_two.Hide()
38 |
39 | self.sizer = wx.BoxSizer(wx.VERTICAL)
40 | self.sizer.Add(self.panel_one, 1, wx.EXPAND)
41 | self.sizer.Add(self.panel_two, 1, wx.EXPAND)
42 | self.SetSizer(self.sizer)
43 |
44 |
45 | menubar = wx.MenuBar()
46 | fileMenu = wx.Menu()
47 | switch_panels_menu_item = fileMenu.Append(
48 | wx.ID_ANY,
49 | "Switch Panels",
50 | "Some text")
51 | self.Bind(wx.EVT_MENU, self.onSwitchPanels,
52 | switch_panels_menu_item)
53 | menubar.Append(fileMenu, '&File')
54 | self.SetMenuBar(menubar)
55 |
56 | def onSwitchPanels(self, event):
57 | """
58 | Event handler called when we want to switch panels
59 | """
60 | if self.panel_one.IsShown():
61 | self.SetTitle("Panel Two Showing")
62 | self.panel_one.Hide()
63 | self.panel_two.Show()
64 | else:
65 | self.SetTitle("Panel One Showing")
66 | self.panel_one.Show()
67 | self.panel_two.Hide()
68 | self.Layout()
69 |
70 |
71 | # Run the program
72 | if __name__ == "__main__":
73 | app = wx.App(False)
74 | frame = MyForm()
75 | frame.Show()
76 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_38_pyplot/bar_graph.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx.lib.plot import PolyLine, PlotCanvas, PlotGraphics
3 |
4 |
5 | def drawBarGraph():
6 | # Bar graph
7 | points1=[(1,0), (1,10)]
8 | line1 = PolyLine(points1, colour='green', legend='Feb.', width=10)
9 | points1g=[(2,0), (2,4)]
10 | line1g = PolyLine(points1g, colour='red', legend='Mar.', width=10)
11 | points1b=[(3,0), (3,6)]
12 | line1b = PolyLine(points1b, colour='blue', legend='Apr.', width=10)
13 |
14 | points2=[(4,0), (4,12)]
15 | line2 = PolyLine(points2, colour='Yellow', legend='May', width=10)
16 | points2g=[(5,0), (5,8)]
17 | line2g = PolyLine(points2g, colour='orange', legend='June', width=10)
18 | points2b=[(6,0), (6,4)]
19 | line2b = PolyLine(points2b, colour='brown', legend='July', width=10)
20 |
21 | return PlotGraphics([line1, line1g, line1b, line2, line2g, line2b],
22 | "Bar Graph - (Turn on Grid, Legend)", "Months",
23 | "Number of Students")
24 |
25 |
26 | class MyGraph(wx.Frame):
27 |
28 |
29 | def __init__(self):
30 | wx.Frame.__init__(self, None, wx.ID_ANY,
31 | 'My First Plot (to take over the world!)')
32 |
33 | # Add a panel so it looks the correct on all platforms
34 | panel = wx.Panel(self, wx.ID_ANY)
35 |
36 | # create some sizers
37 | mainSizer = wx.BoxSizer(wx.VERTICAL)
38 | checkSizer = wx.BoxSizer(wx.HORIZONTAL)
39 |
40 | # create the widgets
41 | self.canvas = PlotCanvas(panel)
42 | self.canvas.Draw(drawBarGraph())
43 | toggleGrid = wx.CheckBox(panel, label="Show Grid")
44 | toggleGrid.Bind(wx.EVT_CHECKBOX, self.onToggleGrid)
45 | toggleLegend = wx.CheckBox(panel, label="Show Legend")
46 | toggleLegend.Bind(wx.EVT_CHECKBOX, self.onToggleLegend)
47 |
48 | # layout the widgets
49 | mainSizer.Add(self.canvas, 1, wx.EXPAND)
50 | checkSizer.Add(toggleGrid, 0, wx.ALL, 5)
51 | checkSizer.Add(toggleLegend, 0, wx.ALL, 5)
52 | mainSizer.Add(checkSizer)
53 | panel.SetSizer(mainSizer)
54 |
55 | def onToggleGrid(self, event):
56 | """"""
57 | self.canvas.SetEnableGrid(event.IsChecked())
58 |
59 | def onToggleLegend(self, event):
60 | """"""
61 | self.canvas.SetEnableLegend(event.IsChecked())
62 |
63 | if __name__ == '__main__':
64 | app = wx.App(False)
65 | frame = MyGraph()
66 | frame.Show()
67 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_38_pyplot/data.txt:
--------------------------------------------------------------------------------
1 | # http://www.wunderground.com/history/airport/KMIW/2010/9/22/WeeklyHistory.html?format=1
2 | CDT,Max TemperatureF,Mean TemperatureF,Min TemperatureF,Max Dew PointF,MeanDew PointF,Min DewpointF,Max Humidity, Mean Humidity, Min Humidity, Max Sea Level PressureIn, Mean Sea Level PressureIn, Min Sea Level PressureIn, Max VisibilityMiles, Mean VisibilityMiles, Min VisibilityMiles, Max Wind SpeedMPH, Mean Wind SpeedMPH, Max Gust SpeedMPH,PrecipitationIn, CloudCover, Events
3 | 2010-9-19,56,52,47,55,49,44,100,97,93,30.21,30.17,30.11,10,5,2,14,9,20,0.34,8,Rain-Thunderstorm
4 | 2010-9-20,88,72,56,71,62,55,100,73,46,30.10,29.94,29.77,10,6,0,25,12,32,T,4,Fog-Rain
5 | 2010-9-21,75,70,64,66,64,63,93,83,73,29.89,29.83,29.75,10,7,0,22,7,30,1.79,5,Fog-Rain-Thunderstorm
6 | 2010-9-22,75,70,64,68,64,63,100,93,69,30.00,29.96,29.86,10,5,1,15,4,,0.26,8,Rain
7 |
8 |
--------------------------------------------------------------------------------
/recipe_38_pyplot/plotting_25000_points.py:
--------------------------------------------------------------------------------
1 | import numpy as _Numeric
2 | import wx
3 | from wx.lib.plot import PlotCanvas, PlotGraphics, PolyLine, PolyMarker
4 |
5 |
6 | def drawLinePlot():
7 | # 25,000 point line
8 | data1 = _Numeric.arange(5e5,1e6,10)
9 | data1.shape = (25000, 2)
10 | line1 = PolyLine(data1, legend='Wide Line', colour='green', width=5)
11 |
12 | # A few more points...
13 | markers2 = PolyMarker(data1, legend='Square', colour='blue',
14 | marker='square')
15 | return PlotGraphics([line1, markers2], "25,000 Points", "Value X", "")
16 |
17 |
18 | class MyGraph(wx.Frame):
19 |
20 |
21 | def __init__(self):
22 | wx.Frame.__init__(self, None, wx.ID_ANY,
23 | 'It Looks Like a Line Graph!')
24 |
25 | # Add a panel so it looks the correct on all platforms
26 | panel = wx.Panel(self, wx.ID_ANY)
27 |
28 | # create some sizers
29 | mainSizer = wx.BoxSizer(wx.VERTICAL)
30 | checkSizer = wx.BoxSizer(wx.HORIZONTAL)
31 |
32 | # create the widgets
33 | self.canvas = PlotCanvas(panel)
34 | self.canvas.Draw(drawLinePlot())
35 | toggleGrid = wx.CheckBox(panel, label="Show Grid")
36 | toggleGrid.Bind(wx.EVT_CHECKBOX, self.onToggleGrid)
37 | toggleLegend = wx.CheckBox(panel, label="Show Legend")
38 | toggleLegend.Bind(wx.EVT_CHECKBOX, self.onToggleLegend)
39 |
40 | # layout the widgets
41 | mainSizer.Add(self.canvas, 1, wx.EXPAND)
42 | checkSizer.Add(toggleGrid, 0, wx.ALL, 5)
43 | checkSizer.Add(toggleLegend, 0, wx.ALL, 5)
44 | mainSizer.Add(checkSizer)
45 | panel.SetSizer(mainSizer)
46 |
47 |
48 | def onToggleGrid(self, event):
49 | """"""
50 | self.canvas.SetEnableGrid(event.IsChecked())
51 |
52 |
53 | def onToggleLegend(self, event):
54 | """"""
55 | self.canvas.SetEnableLegend(event.IsChecked())
56 |
57 | if __name__ == '__main__':
58 | app = wx.App(False)
59 | frame = MyGraph()
60 | frame.Show()
61 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_38_pyplot/plotting_saved_data.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx.lib.plot import PolyLine, PlotCanvas, PlotGraphics
3 |
4 | class MyGraph(wx.Frame):
5 |
6 | def __init__(self):
7 | wx.Frame.__init__(self, None, wx.ID_ANY,
8 | 'Plotting File Data')
9 |
10 | # Add a panel so it looks the correct on all platforms
11 | panel = wx.Panel(self, wx.ID_ANY)
12 | self.canvas = PlotCanvas(panel)
13 | self.canvas.Draw(self.createPlotGraphics())
14 |
15 | sizer = wx.BoxSizer(wx.VERTICAL)
16 | sizer.Add(self.canvas, 1, wx.EXPAND)
17 | panel.SetSizer(sizer)
18 |
19 | def readFile(self):
20 | """
21 | Reads the hard-coded file
22 | """
23 | # normally you would want to pass a file path in, NOT hard code it!
24 | with open("data.txt") as fobj:
25 | # skip the first two lines of text in the file
26 | data = fobj.readlines()[2:-1]
27 |
28 | temps = []
29 | for line in data:
30 | parts = line.split(",")
31 | date = parts[0].split("-")
32 | day = date[2]
33 | points = [(day, parts[3]), (day, parts[1])]
34 | temps.append(points)
35 | return temps
36 |
37 | def createPlotGraphics(self):
38 | """
39 | Create the plot's graphics
40 | """
41 | temps = self.readFile()
42 | lines = []
43 | for temp in temps:
44 | tempInt = int(temp[1][1])
45 | if tempInt < 60:
46 | color = "blue"
47 | elif tempInt >=60 and tempInt <= 75:
48 | color = "orange"
49 | else:
50 | color = "red"
51 | lines.append(PolyLine(temp, colour=color, width=10))
52 |
53 | return PlotGraphics(lines, "Bar Graph of Temperatures",
54 | "Days", "Temperatures")
55 |
56 | if __name__ == '__main__':
57 | app = wx.App(False)
58 | frame = MyGraph()
59 | frame.Show()
60 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_38_pyplot/sin_cos.py:
--------------------------------------------------------------------------------
1 | import numpy as _Numeric
2 | import wx
3 | from wx.lib.plot import PlotCanvas, PlotGraphics, PolyLine, PolyMarker
4 |
5 |
6 | def drawSinCosWaves():
7 | # 100 points sin function, plotted as green circles
8 | data1 = 2.*_Numeric.pi*_Numeric.arange(200)/200.
9 | data1.shape = (100, 2)
10 | data1[:,1] = _Numeric.sin(data1[:,0])
11 | markers1 = PolyMarker(data1, legend='Green Markers', colour='green', marker='circle',size=1)
12 |
13 | # 50 points cos function, plotted as red line
14 | data1 = 2.*_Numeric.pi*_Numeric.arange(100)/100.
15 | data1.shape = (50,2)
16 | data1[:,1] = _Numeric.cos(data1[:,0])
17 | lines = PolyLine(data1, legend= 'Red Line', colour='red')
18 |
19 | # A few more points...
20 | pi = _Numeric.pi
21 | markers2 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.),
22 | (3.*pi/4., -1)], legend='Cross Legend', colour='blue',
23 | marker='cross')
24 |
25 | return PlotGraphics([markers1, lines, markers2],"Graph Title", "X Axis", "Y Axis")
26 |
27 |
28 | class MyGraph(wx.Frame):
29 |
30 |
31 | def __init__(self):
32 | wx.Frame.__init__(self, None, wx.ID_ANY,
33 | 'Sin / Cos Plot')
34 |
35 | # Add a panel so it looks the correct on all platforms
36 | panel = wx.Panel(self, wx.ID_ANY)
37 |
38 | # create some sizers
39 | mainSizer = wx.BoxSizer(wx.VERTICAL)
40 | checkSizer = wx.BoxSizer(wx.HORIZONTAL)
41 |
42 | # create the widgets
43 | self.canvas = PlotCanvas(panel)
44 | self.canvas.Draw(drawSinCosWaves())
45 | toggleGrid = wx.CheckBox(panel, label="Show Grid")
46 | toggleGrid.Bind(wx.EVT_CHECKBOX, self.onToggleGrid)
47 | toggleLegend = wx.CheckBox(panel, label="Show Legend")
48 | toggleLegend.Bind(wx.EVT_CHECKBOX, self.onToggleLegend)
49 |
50 | # layout the widgets
51 | mainSizer.Add(self.canvas, 1, wx.EXPAND)
52 | checkSizer.Add(toggleGrid, 0, wx.ALL, 5)
53 | checkSizer.Add(toggleLegend, 0, wx.ALL, 5)
54 | mainSizer.Add(checkSizer)
55 | panel.SetSizer(mainSizer)
56 |
57 |
58 | def onToggleGrid(self, event):
59 | """"""
60 | self.canvas.SetEnableGrid(event.IsChecked())
61 |
62 |
63 | def onToggleLegend(self, event):
64 | """"""
65 | self.canvas.SetEnableLegend(event.IsChecked())
66 |
67 | if __name__ == '__main__':
68 | app = wx.App(False)
69 | frame = MyGraph()
70 | frame.Show()
71 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_39_logging_textctrl/main.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import logging.config
3 | import wx
4 |
5 |
6 | class CustomConsoleHandler(logging.StreamHandler):
7 | """"""
8 |
9 | def __init__(self, textctrl):
10 | """"""
11 | logging.StreamHandler.__init__(self)
12 | self.textctrl = textctrl
13 |
14 | def emit(self, record):
15 | """Constructor"""
16 | msg = self.format(record)
17 | self.textctrl.WriteText(msg + "\n")
18 | self.flush()
19 |
20 |
21 | class MyPanel(wx.Panel):
22 | """"""
23 |
24 | def __init__(self, parent):
25 | """Constructor"""
26 | wx.Panel.__init__(self, parent)
27 | self.logger = logging.getLogger("wxApp")
28 |
29 | self.logger.info("Test from MyPanel __init__")
30 |
31 | logText = wx.TextCtrl(
32 | self,
33 | style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
34 |
35 | btn = wx.Button(self, label="Press Me")
36 | btn.Bind(wx.EVT_BUTTON, self.onPress)
37 |
38 | sizer = wx.BoxSizer(wx.VERTICAL)
39 | sizer.Add(logText, 1, wx.EXPAND|wx.ALL, 5)
40 | sizer.Add(btn, 0, wx.ALL, 5)
41 | self.SetSizer(sizer)
42 |
43 | txtHandler = CustomConsoleHandler(logText)
44 | self.logger.addHandler(txtHandler)
45 |
46 | def onPress(self, event):
47 | """
48 | On the press of a button, log some messages
49 | """
50 | self.logger.error("Error Will Robinson!")
51 | self.logger.info("Informational message")
52 |
53 |
54 | class MyFrame(wx.Frame):
55 | """"""
56 |
57 | def __init__(self):
58 | """Constructor"""
59 | wx.Frame.__init__(self, None, title="Logging test")
60 | panel = MyPanel(self)
61 | self.logger = logging.getLogger("wxApp")
62 | self.Show()
63 |
64 |
65 | def main():
66 | """
67 | Run the program
68 | """
69 | dictLogConfig = {
70 | "version":1,
71 | "handlers":{
72 | "fileHandler":{
73 | "class":"logging.FileHandler",
74 | "formatter":"myFormatter",
75 | "filename":"test.log"
76 | },
77 | "consoleHandler":{
78 | "class":"logging.StreamHandler",
79 | "formatter":"myFormatter"
80 | }
81 | },
82 | "loggers":{
83 | "wxApp":{
84 | "handlers":["fileHandler", "consoleHandler"],
85 | "level":"INFO",
86 | }
87 | },
88 |
89 | "formatters":{
90 | "myFormatter":{
91 | "format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
92 | }
93 | }
94 | }
95 | logging.config.dictConfig(dictLogConfig)
96 | logger = logging.getLogger("wxApp")
97 |
98 | logger.info("This message came from main!")
99 |
100 | app = wx.App(False)
101 | frame = MyFrame()
102 | app.MainLoop()
103 |
104 |
105 | if __name__ == "__main__":
106 | main()
--------------------------------------------------------------------------------
/recipe_3_embedding_image/custom_icon.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title='Custom Image')
7 |
8 | self.panel = wx.Panel(self, wx.ID_ANY)
9 |
10 | ico = wx.Icon('py.ico', wx.BITMAP_TYPE_ICO)
11 | self.SetIcon(ico)
12 |
13 |
14 | if __name__ == '__main__':
15 | app = wx.App(False)
16 | frame = MyForm().Show()
17 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_3_embedding_image/image_from_exe.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, title='Image Extractor')
7 |
8 | self.panel = wx.Panel(self)
9 |
10 | loc = wx.IconLocation(r'C:\Python35\python.exe', 0)
11 | self.SetIcon(wx.Icon(loc))
12 |
13 |
14 | if __name__ == '__main__':
15 | app = wx.App(False)
16 | frame = MyForm().Show()
17 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_3_embedding_image/img_from_python_code.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import my_icon
3 |
4 | class MyForm(wx.Frame):
5 |
6 | def __init__(self):
7 | wx.Frame.__init__(self, None, title='Python Image Title')
8 |
9 | self.panel = wx.Panel(self, wx.ID_ANY)
10 |
11 | ico = my_icon.PyEmbeddedImage(my_icon.py)
12 | self.SetIcon(ico.data.GetIcon())
13 |
14 |
15 | # Run the program
16 | if __name__ == '__main__':
17 | app = wx.App(False)
18 | frame = MyForm().Show()
19 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_3_embedding_image/py.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_3_embedding_image/py.ico
--------------------------------------------------------------------------------
/recipe_40_redirect_stdout/main_non_thread_safe.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import wx
3 |
4 | class MyForm(wx.Frame):
5 |
6 | def __init__(self):
7 | wx.Frame.__init__(self, None,
8 | title="wxPython Redirect Tutorial")
9 |
10 | # Add a panel so it looks the correct on all platforms
11 | panel = wx.Panel(self, wx.ID_ANY)
12 | style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL
13 | log = wx.TextCtrl(panel, wx.ID_ANY, size=(300,100),
14 | style=style)
15 | btn = wx.Button(panel, wx.ID_ANY, 'Push me!')
16 | self.Bind(wx.EVT_BUTTON, self.onButton, btn)
17 |
18 | # Add widgets to a sizer
19 | sizer = wx.BoxSizer(wx.VERTICAL)
20 | sizer.Add(log, 1, wx.ALL|wx.EXPAND, 5)
21 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
22 | panel.SetSizer(sizer)
23 |
24 | # redirect text here
25 | sys.stdout = log
26 |
27 | def onButton(self, event):
28 | print("You pressed the button!")
29 |
30 |
31 | if __name__ == "__main__":
32 | app = wx.App(False)
33 | frame = MyForm().Show()
34 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_40_redirect_stdout/main_non_thread_safe_phoenix.py:
--------------------------------------------------------------------------------
1 | # wxPython Phoenix
2 |
3 | import sys
4 | import wx
5 |
6 | class MyCustomTextCtrl(wx.TextCtrl):
7 |
8 | def __init__(self, *args, **kwargs):
9 | """
10 | Initial the text control
11 | """
12 | wx.TextCtrl.__init__(self, *args, **kwargs)
13 |
14 | def write(self, text):
15 | self.WriteText(text)
16 |
17 |
18 | class MyForm(wx.Frame):
19 |
20 | def __init__(self):
21 | wx.Frame.__init__(self, None,
22 | title="wxPython Redirect Tutorial")
23 |
24 | # Add a panel so it looks the correct on all platforms
25 | panel = wx.Panel(self, wx.ID_ANY)
26 | style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL
27 | log = MyCustomTextCtrl(panel, wx.ID_ANY, size=(300,100),
28 | style=style)
29 | btn = wx.Button(panel, wx.ID_ANY, 'Push me!')
30 | self.Bind(wx.EVT_BUTTON, self.onButton, btn)
31 |
32 | # Add widgets to a sizer
33 | sizer = wx.BoxSizer(wx.VERTICAL)
34 | sizer.Add(log, 1, wx.ALL|wx.EXPAND, 5)
35 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
36 | panel.SetSizer(sizer)
37 |
38 | # redirect text here
39 | sys.stdout = log
40 |
41 | def onButton(self, event):
42 | print("You pressed the button!")
43 |
44 |
45 | if __name__ == "__main__":
46 | app = wx.App(False)
47 | frame = MyForm().Show()
48 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_40_redirect_stdout/main_thread_safe.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import wx
3 |
4 |
5 | class RedirectText():
6 |
7 | def __init__(self, my_text_ctrl):
8 | self.out = my_text_ctrl
9 |
10 | def write(self,string):
11 | wx.CallAfter(self.out.WriteText, string)
12 |
13 |
14 | class MyForm(wx.Frame):
15 |
16 | def __init__(self):
17 | wx.Frame.__init__(self, None, title="wxPython Redirect Tutorial")
18 |
19 | # Add a panel so it looks the correct on all platforms
20 | panel = wx.Panel(self, wx.ID_ANY)
21 | log = wx.TextCtrl(panel, wx.ID_ANY, size=(300,100),
22 | style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
23 | btn = wx.Button(panel, wx.ID_ANY, 'Push me!')
24 | self.Bind(wx.EVT_BUTTON, self.onButton, btn)
25 |
26 | # Add widgets to a sizer
27 | sizer = wx.BoxSizer(wx.VERTICAL)
28 | sizer.Add(log, 1, wx.ALL|wx.EXPAND, 5)
29 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
30 | panel.SetSizer(sizer)
31 |
32 | # redirect text here
33 | redir = RedirectText(log)
34 | sys.stdout = redir
35 |
36 | def onButton(self, event):
37 | print("You pressed the button!")
38 |
39 |
40 | if __name__ == "__main__":
41 | app = wx.App(False)
42 | frame = MyForm().Show()
43 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_41_simple_notebook/simple.py:
--------------------------------------------------------------------------------
1 | import random
2 | import wx
3 |
4 |
5 | class TabPanel(wx.Panel):
6 |
7 | def __init__(self, parent):
8 | """"""
9 | wx.Panel.__init__(self, parent=parent)
10 |
11 | colors = ["red", "blue", "gray", "yellow", "green"]
12 | self.SetBackgroundColour(random.choice(colors))
13 |
14 | btn = wx.Button(self, label="Press Me")
15 | sizer = wx.BoxSizer(wx.VERTICAL)
16 | sizer.Add(btn, 0, wx.ALL, 10)
17 | self.SetSizer(sizer)
18 |
19 |
20 | class DemoFrame(wx.Frame):
21 | """
22 | Frame that holds all other widgets
23 | """
24 |
25 | def __init__(self):
26 | """Constructor"""
27 | wx.Frame.__init__(self, None, wx.ID_ANY,
28 | "Notebook Tutorial",
29 | size=(600,400)
30 | )
31 | panel = wx.Panel(self)
32 |
33 | notebook = wx.Notebook(panel)
34 | tabOne = TabPanel(notebook)
35 | notebook.AddPage(tabOne, "Tab 1")
36 |
37 | tabTwo = TabPanel(notebook)
38 | notebook.AddPage(tabTwo, "Tab 2")
39 |
40 | sizer = wx.BoxSizer(wx.VERTICAL)
41 | sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
42 | panel.SetSizer(sizer)
43 | self.Layout()
44 |
45 | self.Show()
46 |
47 |
48 | if __name__ == "__main__":
49 | app = wx.App(False)
50 | frame = DemoFrame()
51 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_41_simple_notebook/simple_refactored.py:
--------------------------------------------------------------------------------
1 | import random
2 | import wx
3 |
4 |
5 | class TabPanel(wx.Panel):
6 | """
7 | The panel class to derive the tabs of the Notebook from
8 | """
9 |
10 | def __init__(self, parent):
11 | """"""
12 | wx.Panel.__init__(self, parent=parent)
13 |
14 | colors = ["red", "blue", "gray", "yellow", "green"]
15 | self.SetBackgroundColour(random.choice(colors))
16 |
17 | btn = wx.Button(self, label="Press Me")
18 | sizer = wx.BoxSizer(wx.VERTICAL)
19 | sizer.Add(btn, 0, wx.ALL, 10)
20 | self.SetSizer(sizer)
21 |
22 |
23 | class DemoNotebook(wx.Notebook):
24 | """
25 | Our Notebook class
26 | """
27 |
28 | def __init__(self, parent):
29 | wx.Notebook.__init__(self, parent)
30 |
31 | tabOne = TabPanel(self)
32 | self.AddPage(tabOne, "Tab 1")
33 |
34 | tabTwo = TabPanel(self)
35 | self.AddPage(tabTwo, "Tab 2")
36 |
37 |
38 | class DemoPanel(wx.Panel):
39 | """
40 | The main panel used by the frame
41 | """
42 |
43 | def __init__(self, parent):
44 | """"""
45 | wx.Panel.__init__(self, parent=parent)
46 |
47 | notebook = DemoNotebook(self)
48 |
49 | sizer = wx.BoxSizer(wx.VERTICAL)
50 | sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
51 | self.SetSizer(sizer)
52 |
53 |
54 | class DemoFrame(wx.Frame):
55 | """
56 | Frame that holds all other widgets
57 | """
58 |
59 | def __init__(self):
60 | """Constructor"""
61 | wx.Frame.__init__(self, None, wx.ID_ANY,
62 | "Notebook Tutorial",
63 | size=(600,400)
64 | )
65 | panel = DemoPanel(self)
66 |
67 | self.Layout()
68 |
69 | self.Show()
70 |
71 |
72 | if __name__ == "__main__":
73 | app = wx.App(False)
74 | frame = DemoFrame()
75 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_42_singleton_frame/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MyPanel(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """Constructor"""
9 | wx.Panel.__init__(self, parent)
10 |
11 |
12 | class SingleInstanceFrame(wx.Frame):
13 | """"""
14 |
15 | instance = None
16 | init = 0
17 |
18 | def __new__(self, *args, **kwargs):
19 | """"""
20 | if self.instance is None:
21 | self.instance = wx.Frame.__new__(self)
22 | elif not self.instance:
23 | self.instance = wx.Frame.__new__(self)
24 |
25 | return self.instance
26 |
27 | def __init__(self):
28 | """Constructor"""
29 | print(id(self))
30 | if self.init:
31 | return
32 | self.init = 1
33 |
34 | wx.Frame.__init__(self, None, title="Single Instance Frame")
35 | panel = MyPanel(self)
36 | self.Show()
37 |
38 |
39 | class MainFrame(wx.Frame):
40 | """"""
41 |
42 | def __init__(self):
43 | """Constructor"""
44 | wx.Frame.__init__(self, None, title="Main Frame")
45 | panel = MyPanel(self)
46 | btn = wx.Button(panel, label="Open Frame")
47 | btn.Bind(wx.EVT_BUTTON, self.open_frame)
48 | self.Show()
49 |
50 | def open_frame(self, event):
51 | frame = SingleInstanceFrame()
52 |
53 |
54 | if __name__ == '__main__':
55 | app = wx.App(False)
56 | frame = MainFrame()
57 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_43_storing_objects/objects_in_combobox.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class Car:
5 | """"""
6 |
7 | def __init__(self, id, model, make, year):
8 | """Constructor"""
9 | self.id = id
10 | self.model = model
11 | self.make = make
12 | self.year = year
13 |
14 |
15 | class MyForm(wx.Frame):
16 |
17 | def __init__(self):
18 | wx.Frame.__init__(self, None, title="Tutorial")
19 |
20 | panel = wx.Panel(self, wx.ID_ANY)
21 |
22 | cars = [Car(0, "Ford", "F-150", "2008"),
23 | Car(1, "Chevrolet", "Camaro", "2010"),
24 | Car(2, "Nissan", "370Z", "2005")]
25 |
26 | sampleList = []
27 | self.cb = wx.ComboBox(panel,
28 | size=wx.DefaultSize,
29 | choices=sampleList)
30 | self.widgetMaker(self.cb, cars)
31 |
32 | sizer = wx.BoxSizer(wx.VERTICAL)
33 | sizer.Add(self.cb, 0, wx.ALL, 5)
34 | panel.SetSizer(sizer)
35 |
36 | def widgetMaker(self, widget, objects):
37 | """"""
38 | for obj in objects:
39 | widget.Append(obj.make, obj)
40 | widget.Bind(wx.EVT_COMBOBOX, self.onSelect)
41 |
42 | def onSelect(self, event):
43 | """"""
44 | print("You selected: " + self.cb.GetStringSelection())
45 | obj = self.cb.GetClientData(self.cb.GetSelection())
46 | text = """
47 | The object's attributes are:
48 | %s %s %s %s
49 |
50 | """ % (obj.id, obj.make, obj.model, obj.year)
51 | print(text)
52 |
53 |
54 | if __name__ == "__main__":
55 | app = wx.App(False)
56 | frame = MyForm()
57 | frame.Show()
58 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_43_storing_objects/objects_in_listbox.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class Car:
5 | """"""
6 |
7 | def __init__(self, id, model, make, year):
8 | """Constructor"""
9 | self.id = id
10 | self.model = model
11 | self.make = make
12 | self.year = year
13 |
14 |
15 | class MyForm(wx.Frame):
16 |
17 | def __init__(self):
18 | wx.Frame.__init__(self, None, title="ListBox Obj Tutorial")
19 |
20 | panel = wx.Panel(self, wx.ID_ANY)
21 |
22 | ford = Car(0, "Ford", "F-150", "2008")
23 | chevy = Car(1, "Chevrolet", "Camaro", "2010")
24 | nissan = Car(2, "Nissan", "370Z", "2005")
25 |
26 | sampleList = []
27 | lb = wx.ListBox(panel,
28 | size=wx.DefaultSize,
29 | choices=sampleList)
30 | self.lb = lb
31 | lb.Append(ford.make, ford)
32 | lb.Append(chevy.make, chevy)
33 | lb.Append(nissan.make, nissan)
34 | lb.Bind(wx.EVT_LISTBOX, self.onSelect)
35 |
36 | sizer = wx.BoxSizer(wx.VERTICAL)
37 | sizer.Add(lb, 0, wx.ALL, 5)
38 | panel.SetSizer(sizer)
39 |
40 | def onSelect(self, event):
41 | """"""
42 | selection = self.lb.GetStringSelection()
43 | if selection:
44 | print("You selected: " + selection)
45 | obj = self.lb.GetClientData(self.lb.GetSelection())
46 | text = """
47 | The object's attributes are:
48 | %s %s %s %s
49 |
50 | """ % (obj.id, obj.make, obj.model, obj.year)
51 | print(text)
52 |
53 |
54 | if __name__ == "__main__":
55 | app = wx.App(False)
56 | frame = MyForm()
57 | frame.Show()
58 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_44_syncing_grid_scroll/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.grid as gridlib
3 |
4 |
5 | class ScrollSync(object):
6 | def __init__(self, panel1, panel2):
7 | self.panel1 = panel1
8 | self.panel2 = panel2
9 | self.panel1.grid.Bind(wx.EVT_SCROLLWIN, self.onScrollWin1)
10 | self.panel2.grid.Bind(wx.EVT_SCROLLWIN, self.onScrollWin2)
11 |
12 | def onScrollWin1(self, event):
13 | if event.Orientation == wx.SB_HORIZONTAL:
14 | self.panel2.grid.Scroll(event.Position, -1)
15 | else:
16 | self.panel2.grid.Scroll(-1, event.Position)
17 | event.Skip()
18 |
19 | def onScrollWin2(self, event):
20 | if event.Orientation == wx.SB_HORIZONTAL:
21 | self.panel1.grid.Scroll(event.Position, -1)
22 | else:
23 | self.panel1.grid.Scroll(-1, event.Position)
24 | event.Skip()
25 |
26 |
27 | class GridPanel(wx.Panel):
28 | """"""
29 |
30 | def __init__(self, parent):
31 | """Constructor"""
32 | wx.Panel.__init__(self, parent)
33 | self.grid = gridlib.Grid(self, style=wx.BORDER_SUNKEN)
34 | self.grid.CreateGrid(25,8)
35 |
36 | sizer = wx.BoxSizer(wx.VERTICAL)
37 | sizer.Add(self.grid, 1, wx.EXPAND)
38 | self.SetSizer(sizer)
39 |
40 |
41 | class MainPanel(wx.Panel):
42 | """"""
43 |
44 | def __init__(self, parent):
45 | """Constructor"""
46 | wx.Panel.__init__(self, parent)
47 |
48 |
49 | split = wx.SplitterWindow(self)
50 |
51 | panelOne = GridPanel(split)
52 | panelTwo = GridPanel(split)
53 | ScrollSync(panelOne, panelTwo)
54 |
55 | split.SplitVertically(panelOne, panelTwo)
56 | split.SetSashGravity(0.5)
57 |
58 | sizer = wx.BoxSizer(wx.VERTICAL)
59 | sizer.Add(split, 1, wx.EXPAND)
60 | self.SetSizer(sizer)
61 |
62 |
63 | class MainFrame(wx.Frame):
64 | """"""
65 |
66 | def __init__(self):
67 | """Constructor"""
68 | wx.Frame.__init__(self, None, title="Sync Grids",
69 | size=(800,400))
70 | panel = MainPanel(self)
71 | self.Show()
72 |
73 |
74 | if __name__ == "__main__":
75 | app = wx.App(False)
76 | frame = MainFrame()
77 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_45_timers/multiple_timers.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import time
3 |
4 | TIMER_ID1 = 2000
5 | TIMER_ID2 = 2001
6 |
7 | class MyForm(wx.Frame):
8 |
9 | def __init__(self):
10 | wx.Frame.__init__(self, None, title="Timer Tutorial 2")
11 |
12 | panel = wx.Panel(self, wx.ID_ANY)
13 |
14 | self.timer = wx.Timer(self, id=TIMER_ID1)
15 | self.Bind(wx.EVT_TIMER, self.update, self.timer)
16 | self.timer2 = wx.Timer(self, id=TIMER_ID2)
17 | self.Bind(wx.EVT_TIMER, self.update, self.timer2)
18 |
19 | self.toggleBtn = wx.Button(panel, wx.ID_ANY, "Start Timer 1")
20 | self.toggleBtn.Bind(wx.EVT_BUTTON, self.onStartTimerOne)
21 | self.toggleBtn2 = wx.Button(panel, wx.ID_ANY, "Start Timer 2")
22 | self.toggleBtn2.Bind(wx.EVT_BUTTON, self.onStartTimerOne)
23 |
24 | sizer = wx.BoxSizer(wx.VERTICAL)
25 | sizer.Add(self.toggleBtn, 0, wx.ALL|wx.CENTER, 5)
26 | sizer.Add(self.toggleBtn2, 0, wx.ALL|wx.CENTER, 5)
27 | panel.SetSizer(sizer)
28 |
29 | def onStartTimerOne(self, event):
30 | buttonObj = event.GetEventObject()
31 | btnLabel = buttonObj.GetLabel()
32 | timerNum = int(btnLabel[-1:])
33 | print(timerNum)
34 |
35 | if btnLabel == "Start Timer %s" % timerNum:
36 | if timerNum == 1:
37 | print("starting timer 1...")
38 | self.timer.Start(1000)
39 | else:
40 | print("starting timer 2...")
41 | self.timer2.Start(3000)
42 | buttonObj.SetLabel("Stop Timer %s" % timerNum)
43 | else:
44 | if timerNum == 1:
45 | self.timer.Stop()
46 | print("timer 1 stopped!")
47 | else:
48 | self.timer2.Stop()
49 | print("timer 2 stopped!")
50 | buttonObj.SetLabel("Start Timer %s" % timerNum)
51 |
52 | def update(self, event):
53 | timerId = event.GetId()
54 | if timerId == TIMER_ID1:
55 | print("\ntimer 1 updated: ", time.ctime())
56 | else:
57 | print("\ntimer 2 updated: ", time.ctime())
58 |
59 |
60 | # Run the program
61 | if __name__ == "__main__":
62 | app = wx.App()
63 | frame = MyForm().Show()
64 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_45_timers/multiple_timers_2.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import time
3 |
4 | class MyForm(wx.Frame):
5 |
6 | def __init__(self):
7 | wx.Frame.__init__(self, None, title="Timer Tutorial 2")
8 |
9 | panel = wx.Panel(self, wx.ID_ANY)
10 |
11 | self.timer = wx.Timer(self, wx.ID_ANY)
12 | self.Bind(wx.EVT_TIMER, self.update, self.timer)
13 | self.timer2 = wx.Timer(self, wx.ID_ANY)
14 | self.Bind(wx.EVT_TIMER, self.update, self.timer2)
15 |
16 | self.toggleBtn = wx.Button(panel, wx.ID_ANY, "Start Timer 1")
17 | self.toggleBtn.Bind(wx.EVT_BUTTON, self.onStartTimer)
18 | self.toggleBtn2 = wx.Button(panel, wx.ID_ANY, "Start Timer 2")
19 | self.toggleBtn2.Bind(wx.EVT_BUTTON, self.onStartTimer)
20 |
21 | sizer = wx.BoxSizer(wx.VERTICAL)
22 | sizer.Add(self.toggleBtn, 0, wx.ALL|wx.CENTER, 5)
23 | sizer.Add(self.toggleBtn2, 0, wx.ALL|wx.CENTER, 5)
24 | panel.SetSizer(sizer)
25 |
26 | # Each value in the following dict is formatted as follows:
27 | # (timerNum, timerObj, secs between timer events)
28 | self.objDict = {self.toggleBtn: (1, self.timer, 1000),
29 | self.toggleBtn2: (2, self.timer2, 3000)}
30 |
31 | def onStartTimer(self, event):
32 | btn = event.GetEventObject()
33 | timerNum, timer, secs = self.objDict[btn]
34 | if timer.IsRunning():
35 | timer.Stop()
36 | btn.SetLabel("Start Timer %s" % timerNum)
37 | print("timer %s stopped!" % timerNum)
38 | else:
39 | print("starting timer %s..." % timerNum)
40 | timer.Start(secs)
41 | btn.SetLabel("Stop Timer %s" % timerNum)
42 |
43 | def update(self, event):
44 | timerId = event.GetId()
45 | if timerId == self.timer.GetId():
46 | print("\ntimer 1 updated: ", time.ctime())
47 | else:
48 | print ("\ntimer 2 updated: ", time.ctime())
49 |
50 |
51 | # Run the program
52 | if __name__ == "__main__":
53 | app = wx.App()
54 | frame = MyForm().Show()
55 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_45_timers/simple_timer.py:
--------------------------------------------------------------------------------
1 | import time
2 | import wx
3 |
4 | class MyForm(wx.Frame):
5 |
6 | def __init__(self):
7 | wx.Frame.__init__(self, None, title="Timer Tutorial 1",
8 | size=(500,500))
9 |
10 | panel = wx.Panel(self, wx.ID_ANY)
11 |
12 | self.timer = wx.Timer(self)
13 | self.Bind(wx.EVT_TIMER, self.update, self.timer)
14 |
15 | self.toggleBtn = wx.Button(panel, wx.ID_ANY, "Start")
16 | self.toggleBtn.Bind(wx.EVT_BUTTON, self.onToggle)
17 |
18 | def onToggle(self, event):
19 | btnLabel = self.toggleBtn.GetLabel()
20 | if btnLabel == "Start":
21 | print("starting timer...")
22 | self.timer.Start(1000)
23 | self.toggleBtn.SetLabel("Stop")
24 | else:
25 | print("timer stopped!")
26 | self.timer.Stop()
27 | self.toggleBtn.SetLabel("Start")
28 |
29 | def update(self, event):
30 | print("\nupdated: ", time.ctime())
31 |
32 |
33 | # Run the program
34 | if __name__ == "__main__":
35 | app = wx.App(True)
36 | frame = MyForm().Show()
37 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_45_timers/simple_timer_2.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import time
3 |
4 | class MyForm(wx.Frame):
5 |
6 | def __init__(self):
7 | wx.Frame.__init__(self, None, title="Timer Tutorial 1",
8 | size=(500,500))
9 |
10 | panel = wx.Panel(self, wx.ID_ANY)
11 |
12 | self.timer = wx.Timer(self)
13 | self.Bind(wx.EVT_TIMER, self.update, self.timer)
14 |
15 | self.toggleBtn = wx.Button(panel, wx.ID_ANY, "Start")
16 | self.toggleBtn.Bind(wx.EVT_BUTTON, self.onToggle)
17 |
18 | def onToggle(self, event):
19 | if self.timer.IsRunning():
20 | self.timer.Stop()
21 | self.toggleBtn.SetLabel("Start")
22 | print("timer stopped!")
23 | else:
24 | print("starting timer...")
25 | self.timer.Start(1000)
26 | self.toggleBtn.SetLabel("Stop")
27 |
28 | def update(self, event):
29 | print("\nupdated: ", time.ctime())
30 |
31 |
32 | # Run the program
33 | if __name__ == "__main__":
34 | app = wx.App(True)
35 | frame = MyForm().Show()
36 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_46_update_progress_thread/main_2.8.py:
--------------------------------------------------------------------------------
1 | # This code works with wxPython 2.8.12 and Python 2
2 |
3 | import time
4 | import wx
5 |
6 | from threading import Thread
7 | from wx.lib.pubsub import Publisher
8 |
9 |
10 | class TestThread(Thread):
11 | """Test Worker Thread Class."""
12 |
13 | def __init__(self):
14 | """Init Worker Thread Class."""
15 | Thread.__init__(self)
16 | self.start() # start the thread
17 |
18 | def run(self):
19 | """Run Worker Thread."""
20 | # This is the code executing in the new thread.
21 | for i in range(20):
22 | time.sleep(1)
23 | wx.CallAfter(Publisher().sendMessage, "update", "")
24 |
25 |
26 | class MyProgressDialog(wx.Dialog):
27 | """"""
28 |
29 | def __init__(self):
30 | """Constructor"""
31 | wx.Dialog.__init__(self, None, title="Progress")
32 | self.count = 0
33 |
34 | self.progress = wx.Gauge(self, range=20)
35 |
36 | sizer = wx.BoxSizer(wx.VERTICAL)
37 | sizer.Add(self.progress, 0, wx.EXPAND)
38 | self.SetSizer(sizer)
39 |
40 | # create a pubsub listener
41 | Publisher().subscribe(self.updateProgress, "update")
42 |
43 | def updateProgress(self, msg):
44 | """
45 | Update the progress bar
46 | """
47 | self.count += 1
48 |
49 | if self.count >= 20:
50 | self.Destroy()
51 |
52 | self.progress.SetValue(self.count)
53 |
54 |
55 | class MyFrame(wx.Frame):
56 |
57 | def __init__(self):
58 | wx.Frame.__init__(self, None, title="Progress Bar Tutorial")
59 |
60 | # Add a panel so it looks the correct on all platforms
61 | panel = wx.Panel(self, wx.ID_ANY)
62 | self.btn = btn = wx.Button(panel, label="Start Thread")
63 | btn.Bind(wx.EVT_BUTTON, self.onButton)
64 |
65 | sizer = wx.BoxSizer(wx.VERTICAL)
66 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
67 | panel.SetSizer(sizer)
68 |
69 | def onButton(self, event):
70 | """
71 | Runs the thread
72 | """
73 | btn = event.GetEventObject()
74 | btn.Disable()
75 |
76 | TestThread()
77 | dlg = MyProgressDialog()
78 | dlg.ShowModal()
79 |
80 | btn.Enable()
81 |
82 | # Run the program
83 | if __name__ == "__main__":
84 | app = wx.App(False)
85 | frame = MyFrame()
86 | frame.Show()
87 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_46_update_progress_thread/main_3.0.py:
--------------------------------------------------------------------------------
1 | # This code works for wxPython 3.0+ and Phoenix
2 | # So you can run this code with Python 2 or 3
3 |
4 | import time
5 | import wx
6 |
7 | from threading import Thread
8 | from wx.lib.pubsub import pub
9 |
10 |
11 | class TestThread(Thread):
12 | """Test Worker Thread Class."""
13 |
14 | def __init__(self):
15 | """Init Worker Thread Class."""
16 | Thread.__init__(self)
17 | self.start() # start the thread
18 |
19 | def run(self):
20 | """Run Worker Thread."""
21 | # This is the code executing in the new thread.
22 | for i in range(20):
23 | time.sleep(1)
24 | wx.CallAfter(pub.sendMessage, "update", msg="")
25 |
26 |
27 | class MyProgressDialog(wx.Dialog):
28 | """"""
29 |
30 | def __init__(self):
31 | """Constructor"""
32 | wx.Dialog.__init__(self, None, title="Progress")
33 | self.count = 0
34 |
35 | self.progress = wx.Gauge(self, range=20)
36 |
37 | sizer = wx.BoxSizer(wx.VERTICAL)
38 | sizer.Add(self.progress, 0, wx.EXPAND)
39 | self.SetSizer(sizer)
40 |
41 | # create a pubsub receiver
42 | pub.subscribe(self.updateProgress, "update")
43 |
44 | def updateProgress(self, msg):
45 | """"""
46 | self.count += 1
47 |
48 | if self.count >= 20:
49 | self.Destroy()
50 |
51 | self.progress.SetValue(self.count)
52 |
53 |
54 | class MyForm(wx.Frame):
55 |
56 | def __init__(self):
57 | wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")
58 |
59 | # Add a panel so it looks the correct on all platforms
60 | panel = wx.Panel(self, wx.ID_ANY)
61 | self.btn = btn = wx.Button(panel, label="Start Thread")
62 | btn.Bind(wx.EVT_BUTTON, self.onButton)
63 |
64 | sizer = wx.BoxSizer(wx.VERTICAL)
65 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
66 | panel.SetSizer(sizer)
67 |
68 | def onButton(self, event):
69 | """
70 | Runs the thread
71 | """
72 | btn = event.GetEventObject()
73 | btn.Disable()
74 |
75 | TestThread()
76 | dlg = MyProgressDialog()
77 | dlg.ShowModal()
78 |
79 | btn.Enable()
80 |
81 |
82 | # Run the program
83 | if __name__ == "__main__":
84 | app = wx.App(False)
85 | frame = MyForm().Show()
86 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_47_wx_and_threads/main.py:
--------------------------------------------------------------------------------
1 | # wxPython 3.0 and Phoenix
2 |
3 | import time
4 | import wx
5 |
6 | from threading import Thread
7 | from wx.lib.pubsub import pub
8 |
9 |
10 | class TestThread(Thread):
11 | """Test Worker Thread Class."""
12 |
13 | def __init__(self):
14 | """Init Worker Thread Class."""
15 | Thread.__init__(self)
16 | self.start() # start the thread
17 |
18 | def run(self):
19 | """Run Worker Thread."""
20 | # This is the code executing in the new thread.
21 | for i in range(6):
22 | time.sleep(10)
23 | wx.CallAfter(self.postTime, i)
24 | time.sleep(5)
25 | wx.CallAfter(pub.sendMessage, "update", msg="Thread finished!")
26 |
27 | def postTime(self, amt):
28 | """
29 | Send time to GUI
30 | """
31 | amtOfTime = (amt + 1) * 10
32 | pub.sendMessage("update", msg=amtOfTime)
33 |
34 |
35 | class MyForm(wx.Frame):
36 |
37 | def __init__(self):
38 | wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")
39 |
40 | # Add a panel so it looks the correct on all platforms
41 | panel = wx.Panel(self, wx.ID_ANY)
42 | self.displayLbl = wx.StaticText(panel,
43 | label="Amount of time since thread started goes here")
44 | self.btn = btn = wx.Button(panel, label="Start Thread")
45 |
46 | btn.Bind(wx.EVT_BUTTON, self.onButton)
47 |
48 | sizer = wx.BoxSizer(wx.VERTICAL)
49 | sizer.Add(self.displayLbl, 0, wx.ALL|wx.CENTER, 5)
50 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
51 | panel.SetSizer(sizer)
52 |
53 | # create a pubsub receiver
54 | pub.subscribe(self.updateDisplay, "update")
55 |
56 | def onButton(self, event):
57 | """
58 | Runs the thread
59 | """
60 | TestThread()
61 | self.displayLbl.SetLabel("Thread started!")
62 | btn = event.GetEventObject()
63 | btn.Disable()
64 |
65 | def updateDisplay(self, msg):
66 | """
67 | Receives data from thread and updates the display
68 | """
69 | t = msg
70 | if isinstance(t, int):
71 | self.displayLbl.SetLabel("Time since thread started: %s seconds" % t)
72 | else:
73 | self.displayLbl.SetLabel("%s" % t)
74 | self.btn.Enable()
75 |
76 |
77 | # Run the program
78 | if __name__ == "__main__":
79 | app = wx.App(False)
80 | frame = MyForm().Show()
81 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_47_wx_and_threads/main_legacy.py:
--------------------------------------------------------------------------------
1 | # wxPython 2.8.12
2 |
3 | import time
4 | import wx
5 |
6 | from threading import Thread
7 | from wx.lib.pubsub import Publisher
8 |
9 |
10 | class TestThread(Thread):
11 | """Test Worker Thread Class."""
12 |
13 | def __init__(self):
14 | """Init Worker Thread Class."""
15 | Thread.__init__(self)
16 | self.start() # start the thread
17 |
18 | def run(self):
19 | """Run Worker Thread."""
20 | # This is the code executing in the new thread.
21 | for i in range(6):
22 | time.sleep(10)
23 | wx.CallAfter(self.postTime, i)
24 | time.sleep(5)
25 | wx.CallAfter(Publisher().sendMessage, "update", "Thread finished!")
26 |
27 | def postTime(self, amt):
28 | """
29 | Send time to GUI
30 | """
31 | amtOfTime = (amt + 1) * 10
32 | Publisher().sendMessage("update", amtOfTime)
33 |
34 |
35 | class MyForm(wx.Frame):
36 |
37 | def __init__(self):
38 | wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")
39 |
40 | # Add a panel so it looks the correct on all platforms
41 | panel = wx.Panel(self, wx.ID_ANY)
42 | self.displayLbl = wx.StaticText(panel,
43 | label="Amount of time since thread started goes here")
44 | self.btn = btn = wx.Button(panel, label="Start Thread")
45 |
46 | btn.Bind(wx.EVT_BUTTON, self.onButton)
47 |
48 | sizer = wx.BoxSizer(wx.VERTICAL)
49 | sizer.Add(self.displayLbl, 0, wx.ALL|wx.CENTER, 5)
50 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
51 | panel.SetSizer(sizer)
52 |
53 | # create a pubsub receiver
54 | Publisher().subscribe(self.updateDisplay, "update")
55 |
56 | def onButton(self, event):
57 | """
58 | Runs the thread
59 | """
60 | TestThread()
61 | self.displayLbl.SetLabel("Thread started!")
62 | btn = event.GetEventObject()
63 | btn.Disable()
64 |
65 | def updateDisplay(self, msg):
66 | """
67 | Receives data from thread and updates the display
68 | """
69 | t = msg.data
70 | if isinstance(t, int):
71 | self.displayLbl.SetLabel("Time since thread started: %s seconds" % t)
72 | else:
73 | self.displayLbl.SetLabel("%s" % t)
74 | self.btn.Enable()
75 |
76 |
77 | # Run the program
78 | if __name__ == "__main__":
79 | app = wx.App(False)
80 | frame = MyForm().Show()
81 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_47_wx_and_threads/post_event_example.py:
--------------------------------------------------------------------------------
1 | import time
2 | import wx
3 |
4 | from threading import Thread
5 |
6 | # Define notification event for thread completion
7 | EVT_RESULT_ID = wx.NewId()
8 |
9 | def EVT_RESULT(win, func):
10 | """Define Result Event."""
11 | win.Connect(-1, -1, EVT_RESULT_ID, func)
12 |
13 | class ResultEvent(wx.PyEvent):
14 | """Simple event to carry arbitrary result data."""
15 | def __init__(self, data):
16 | """Init Result Event."""
17 | wx.PyEvent.__init__(self)
18 | self.SetEventType(EVT_RESULT_ID)
19 | self.data = data
20 |
21 |
22 | class TestThread(Thread):
23 | """Test Worker Thread Class."""
24 |
25 | def __init__(self, wxObject):
26 | """Init Worker Thread Class."""
27 | Thread.__init__(self)
28 | self.wxObject = wxObject
29 | self.start() # start the thread
30 |
31 | def run(self):
32 | """Run Worker Thread."""
33 | # This is the code executing in the new thread.
34 | for i in range(6):
35 | time.sleep(10)
36 | amtOfTime = (i + 1) * 10
37 | wx.PostEvent(self.wxObject, ResultEvent(amtOfTime))
38 | time.sleep(5)
39 | wx.PostEvent(self.wxObject, ResultEvent("Thread finished!"))
40 |
41 |
42 | class MyForm(wx.Frame):
43 |
44 | def __init__(self):
45 | wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")
46 |
47 | # Add a panel so it looks the correct on all platforms
48 | panel = wx.Panel(self, wx.ID_ANY)
49 | self.displayLbl = wx.StaticText(panel, label="Amount of time since thread started goes here")
50 | self.btn = btn = wx.Button(panel, label="Start Thread")
51 |
52 | btn.Bind(wx.EVT_BUTTON, self.onButton)
53 |
54 | sizer = wx.BoxSizer(wx.VERTICAL)
55 | sizer.Add(self.displayLbl, 0, wx.ALL|wx.CENTER, 5)
56 | sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
57 | panel.SetSizer(sizer)
58 |
59 | # Set up event handler for any worker thread results
60 | EVT_RESULT(self, self.updateDisplay)
61 |
62 | def onButton(self, event):
63 | """
64 | Runs the thread
65 | """
66 | TestThread(self)
67 | self.displayLbl.SetLabel("Thread started!")
68 | btn = event.GetEventObject()
69 | btn.Disable()
70 |
71 | def updateDisplay(self, msg):
72 | """
73 | Receives data from thread and updates the display
74 | """
75 | t = msg.data
76 | if isinstance(t, int):
77 | self.displayLbl.SetLabel("Time since thread started: %s seconds" % t)
78 | else:
79 | self.displayLbl.SetLabel("%s" % t)
80 | self.btn.Enable()
81 |
82 |
83 | # Run the program
84 | if __name__ == "__main__":
85 | app = wx.App(False)
86 | frame = MyForm().Show()
87 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.1/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | import wx
3 | from wx.lib.softwareupdate import SoftwareUpdate
4 |
5 |
6 | class PhotoCtrl(wx.App, SoftwareUpdate):
7 | """
8 | The Photo Viewer App Class
9 | """
10 |
11 | def __init__(self, redirect=False, filename=None):
12 | wx.App.__init__(self, redirect, filename)
13 |
14 | BASEURL = "http://127.0.0.1:8000"
15 | self.InitUpdates(BASEURL,
16 | BASEURL + "/" + 'ChangeLog.txt')
17 | self.SetAppDisplayName('Image Viewer')
18 | self.CheckForUpdate()
19 |
20 | self.frame = wx.Frame(None, title='Photo Control')
21 |
22 | self.panel = wx.Panel(self.frame)
23 |
24 | self.PhotoMaxSize = 500
25 |
26 | self.createWidgets()
27 | self.frame.Show()
28 |
29 | def createWidgets(self):
30 | instructions = 'Browse for an image'
31 | img = wx.Image(240,240)
32 | self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY,
33 | wx.Bitmap(img))
34 |
35 | instructLbl = wx.StaticText(self.panel, label=instructions)
36 | self.photoTxt = wx.TextCtrl(self.panel, size=(200,-1))
37 | browseBtn = wx.Button(self.panel, label='Browse')
38 | browseBtn.Bind(wx.EVT_BUTTON, self.onBrowse)
39 |
40 | self.mainSizer = wx.BoxSizer(wx.VERTICAL)
41 | self.sizer = wx.BoxSizer(wx.HORIZONTAL)
42 |
43 | self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY),
44 | 0, wx.ALL|wx.EXPAND, 5)
45 | self.mainSizer.Add(instructLbl, 0, wx.ALL, 5)
46 | self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5)
47 | self.sizer.Add(self.photoTxt, 0, wx.ALL, 5)
48 | self.sizer.Add(browseBtn, 0, wx.ALL, 5)
49 | self.mainSizer.Add(self.sizer, 0, wx.ALL, 5)
50 |
51 | self.panel.SetSizer(self.mainSizer)
52 | self.mainSizer.Fit(self.frame)
53 |
54 | self.panel.Layout()
55 |
56 | def onBrowse(self, event):
57 | """
58 | Browse for file
59 | """
60 | wildcard = "JPEG files (*.jpg)|*.jpg"
61 | dialog = wx.FileDialog(None, "Choose a file",
62 | wildcard=wildcard,
63 | style=wx.FD_OPEN)
64 | if dialog.ShowModal() == wx.ID_OK:
65 | self.photoTxt.SetValue(dialog.GetPath())
66 | dialog.Destroy()
67 | self.onView()
68 |
69 | def onView(self):
70 | """
71 | Attempts to load the image and display it
72 | """
73 | filepath = self.photoTxt.GetValue()
74 | img = wx.Image(filepath, wx.BITMAP_TYPE_ANY)
75 | # scale the image, preserving the aspect ratio
76 | W = img.GetWidth()
77 | H = img.GetHeight()
78 | if W > H:
79 | NewW = self.PhotoMaxSize
80 | NewH = self.PhotoMaxSize * H / W
81 | else:
82 | NewH = self.PhotoMaxSize
83 | NewW = self.PhotoMaxSize * W / H
84 | img = img.Scale(NewW,NewH)
85 |
86 | self.imageCtrl.SetBitmap(wx.Bitmap(img))
87 | self.panel.Refresh()
88 | self.mainSizer.Fit(self.frame)
89 |
90 |
91 | if __name__ == '__main__':
92 | app = PhotoCtrl()
93 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.1/mondrian.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_48_updating_your_app/Releases/image_viewer-0.0.1/mondrian.icns
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.1/mondrian.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_48_updating_your_app/Releases/image_viewer-0.0.1/mondrian.ico
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.1/setup.py:
--------------------------------------------------------------------------------
1 | import sys, os
2 | from esky import bdist_esky
3 | from setuptools import setup
4 |
5 | import version
6 |
7 |
8 | # platform specific settings for Windows/py2exe
9 | if sys.platform == "win32":
10 | import py2exe
11 |
12 | FREEZER = 'py2exe'
13 | FREEZER_OPTIONS = dict(compressed = 0,
14 | optimize = 0,
15 | bundle_files = 3,
16 | dll_excludes = ['MSVCP90.dll',
17 | 'mswsock.dll',
18 | 'powrprof.dll',
19 | 'USP10.dll',],
20 | )
21 | exeICON = 'mondrian.ico'
22 |
23 |
24 | # platform specific settings for Mac/py2app
25 | elif sys.platform == "darwin":
26 | import py2app
27 |
28 | FREEZER = 'py2app'
29 | FREEZER_OPTIONS = dict(argv_emulation = False,
30 | iconfile = 'mondrian.icns',
31 | )
32 | exeICON = None
33 |
34 |
35 |
36 | # Common settings
37 | NAME = "wxImageViewer"
38 | APP = [bdist_esky.Executable("image_viewer.py",
39 | gui_only=True,
40 | icon=exeICON,
41 | )]
42 | DATA_FILES = [ 'mondrian.ico' ]
43 | ESKY_OPTIONS = dict( freezer_module = FREEZER,
44 | freezer_options = FREEZER_OPTIONS,
45 | enable_appdata_dir = True,
46 | bundle_msvcrt = True,
47 | )
48 |
49 |
50 | # Build the app and the esky bundle
51 | setup( name = NAME,
52 | scripts = APP,
53 | version = version.VERSION,
54 | data_files = DATA_FILES,
55 | options = dict(bdist_esky=ESKY_OPTIONS),
56 | )
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.1/version.py:
--------------------------------------------------------------------------------
1 | VERSION='0.0.1'
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.2/mondrian.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_48_updating_your_app/Releases/image_viewer-0.0.2/mondrian.icns
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.2/mondrian.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_48_updating_your_app/Releases/image_viewer-0.0.2/mondrian.ico
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.2/setup.py:
--------------------------------------------------------------------------------
1 | import sys, os
2 | from esky import bdist_esky
3 | from setuptools import setup
4 |
5 | import version
6 |
7 |
8 | # platform specific settings for Windows/py2exe
9 | if sys.platform == "win32":
10 | import py2exe
11 | includes = ["wx.lib.pubsub.*",
12 | "wx.lib.pubsub.core.*",
13 | "wx.lib.pubsub.core.kwargs.*"]
14 |
15 | FREEZER = 'py2exe'
16 | FREEZER_OPTIONS = dict(compressed = 0,
17 | optimize = 0,
18 | bundle_files = 3,
19 | dll_excludes = ['MSVCP90.dll',
20 | 'mswsock.dll',
21 | 'powrprof.dll',
22 | 'USP10.dll',],
23 | includes = includes
24 | )
25 | exeICON = 'mondrian.ico'
26 |
27 |
28 | # platform specific settings for Mac/py2app
29 | elif sys.platform == "darwin":
30 | import py2app
31 |
32 | FREEZER = 'py2app'
33 | FREEZER_OPTIONS = dict(argv_emulation = False,
34 | iconfile = 'mondrian.icns',
35 | )
36 | exeICON = None
37 |
38 |
39 |
40 | # Common settings
41 | NAME = "wxImageViewer"
42 | APP = [bdist_esky.Executable("image_viewer.py",
43 | gui_only=True,
44 | icon=exeICON,
45 | )]
46 | DATA_FILES = [ 'mondrian.ico' ]
47 |
48 | ESKY_OPTIONS = dict( freezer_module = FREEZER,
49 | freezer_options = FREEZER_OPTIONS,
50 | enable_appdata_dir = True,
51 | bundle_msvcrt = True,
52 | )
53 |
54 |
55 | # Build the app and the esky bundle
56 | setup( name = NAME,
57 | scripts = APP,
58 | version = version.VERSION,
59 | data_files = DATA_FILES,
60 | options = dict(bdist_esky=ESKY_OPTIONS)
61 | )
--------------------------------------------------------------------------------
/recipe_48_updating_your_app/Releases/image_viewer-0.0.2/version.py:
--------------------------------------------------------------------------------
1 | VERSION='0.0.2'
--------------------------------------------------------------------------------
/recipe_49_xrc/login.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx import xrc
3 |
4 | class MyApp(wx.App):
5 | def OnInit(self):
6 | res = xrc.XmlResource("login.xrc")
7 |
8 | frame = res.LoadFrame(None, 'mainFrame')
9 |
10 | frame.Show()
11 | return True
12 |
13 | if __name__ == "__main__":
14 | app = MyApp(False)
15 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_49_xrc/login.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
64 |
--------------------------------------------------------------------------------
/recipe_49_xrc/notebook.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | wxVERTICAL
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | wxALL|wxEXPAND
20 | 5
21 |
22 |
23 |
24 | XRC Notebook Demo
25 |
26 |
--------------------------------------------------------------------------------
/recipe_49_xrc/notebook2.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | wxVERTICAL
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | wxALL|wxEXPAND
20 | 5
21 |
22 |
23 |
24 | XRC Notebook Demo
25 |
26 |
--------------------------------------------------------------------------------
/recipe_49_xrc/notebookXrcDemo.py:
--------------------------------------------------------------------------------
1 | # notebookXrcDemo.py
2 | import wx
3 | from wx import xrc
4 |
5 | class MyApp(wx.App):
6 | def OnInit(self):
7 | self.res = xrc.XmlResource("notebook.xrc")
8 |
9 | self.frame = self.res.LoadFrame(None, 'DemoFrame')
10 |
11 | self.frame.Show()
12 | return True
13 |
14 | if __name__ == "__main__":
15 | app = MyApp(False)
16 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_49_xrc/notebookXrcDemo2.py:
--------------------------------------------------------------------------------
1 | # notebookXrcDemo2.py
2 | import wx
3 | from wx import xrc
4 |
5 | class MyApp(wx.App):
6 | def OnInit(self):
7 | res = xrc.XmlResource("notebook2.xrc")
8 | frame = res.LoadFrame(None, "DemoFrame")
9 | panel = xrc.XRCCTRL(frame, "DemoPanel")
10 | notebook = xrc.XRCCTRL(panel, "DemoNotebook")
11 |
12 | # load another xrc file
13 | res = xrc.XmlResource("panelOne.xrc")
14 | tabOne = res.LoadPanel(notebook, "panelOne")
15 | notebook.AddPage(tabOne, "TabOne")
16 |
17 | # load the last xrc file
18 | res = xrc.XmlResource("panelTwo.xrc")
19 | tabTwo = res.LoadPanel(notebook, "panelTwo")
20 | notebook.AddPage(tabTwo, "tabTwo")
21 |
22 | frame.Show()
23 | return True
24 |
25 | if __name__ == "__main__":
26 | app = MyApp(False)
27 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_49_xrc/panelOne.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | wxVERTICAL
6 |
7 |
8 |
9 | wxALL
10 | 5
11 |
12 |
13 |
14 |
15 | wxALL
16 | 5
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/recipe_49_xrc/panelTwo.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | wxVERTICAL
6 |
7 |
8 |
9 |
10 |
11 | wxEXPAND
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/recipe_4_background_image/big_cat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_4_background_image/big_cat.jpg
--------------------------------------------------------------------------------
/recipe_4_background_image/daniweb_example.py:
--------------------------------------------------------------------------------
1 | # create a background image on a wxPython panel
2 | # and show a button on top of the image
3 |
4 | import wx
5 |
6 | class Panel1(wx.Panel):
7 | """class Panel1 creates a panel with an image on it, inherits wx.Panel"""
8 | def __init__(self, parent, id):
9 | # create the panel
10 | wx.Panel.__init__(self, parent, id)
11 | try:
12 | # pick an image file you have in the working
13 | # folder you can load .jpg .png .bmp or
14 | # .gif files
15 | image_file = 'big_cat.jpg'
16 | bmp1 = wx.Image(
17 | image_file,
18 | wx.BITMAP_TYPE_ANY).ConvertToBitmap()
19 | # image's upper left corner anchors at panel
20 | # coordinates (0, 0)
21 | self.bitmap1 = wx.StaticBitmap(
22 | self, -1, bmp1, (0, 0))
23 | # show some image details
24 | str1 = "%s %dx%d" % (image_file, bmp1.GetWidth(),
25 | bmp1.GetHeight())
26 | parent.SetTitle(str1)
27 | except IOError:
28 | print("Image file %s not found" % imageFile)
29 | raise SystemExit
30 |
31 | # button goes on the image --> self.bitmap1 is the
32 | # parent
33 | self.button1 = wx.Button(
34 | self.bitmap1, label='Button1',
35 | pos=(8, 8))
36 |
37 | app = wx.App(False)
38 |
39 | # create a window/frame, no parent, -1 is default ID
40 | # change the size of the frame to fit the backgound images
41 | frame1 = wx.Frame(None, -1, "An image on a panel",
42 | size=(350, 400))
43 |
44 | # create the class instance
45 | panel1 = Panel1(frame1, -1)
46 | frame1.Show(True)
47 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_4_background_image/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MainPanel(wx.Panel):
5 | """"""
6 |
7 | def __init__(self, parent):
8 | """Constructor"""
9 | wx.Panel.__init__(self, parent=parent)
10 | self.frame = parent
11 |
12 | sizer = wx.BoxSizer(wx.VERTICAL)
13 | hSizer = wx.BoxSizer(wx.HORIZONTAL)
14 |
15 | for num in range(4):
16 | label = "Button %s" % num
17 | btn = wx.Button(self, label=label)
18 | sizer.Add(btn, 0, wx.ALL, 5)
19 | hSizer.Add((1,1), 1, wx.EXPAND)
20 | hSizer.Add(sizer, 0, wx.TOP, 100)
21 | hSizer.Add((1,1), 0, wx.ALL, 75)
22 | self.SetSizer(hSizer)
23 | self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
24 |
25 | def OnEraseBackground(self, evt):
26 | """
27 | Add a picture to the background
28 | """
29 | # yanked from ColourDB.py
30 | dc = evt.GetDC()
31 |
32 | if not dc:
33 | dc = wx.ClientDC(self)
34 | rect = self.GetUpdateRegion().GetBox()
35 | dc.SetClippingRect(rect)
36 | dc.Clear()
37 | bmp = wx.Bitmap("big_cat.jpg")
38 | dc.DrawBitmap(bmp, 0, 0)
39 |
40 |
41 | class MainFrame(wx.Frame):
42 | """"""
43 |
44 | def __init__(self):
45 | """Constructor"""
46 | wx.Frame.__init__(self, None, size=(600,450))
47 | panel = MainPanel(self)
48 | self.Center()
49 |
50 |
51 | class Main(wx.App):
52 | """"""
53 |
54 | def __init__(self, redirect=False, filename=None):
55 | """Constructor"""
56 | wx.App.__init__(self, redirect, filename)
57 | dlg = MainFrame()
58 | dlg.Show()
59 |
60 |
61 | if __name__ == "__main__":
62 | app = Main()
63 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_50_xrc_grid/broken_grid.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx import xrc
3 |
4 |
5 | class MyApp(wx.App):
6 | def OnInit(self):
7 | self.res = xrc.XmlResource("grid.xrc")
8 |
9 | frame = self.res.LoadFrame(None, 'MyFrame')
10 | panel = xrc.XRCCTRL(frame, "MyPanel")
11 | grid = xrc.XRCCTRL(panel, "MyGrid")
12 | print(type(grid))
13 | grid.CreateGrid(25, 6)
14 |
15 | sizer = wx.BoxSizer(wx.VERTICAL)
16 | sizer.Add(grid, 1, wx.EXPAND|wx.ALL, 5)
17 |
18 | panel.SetSizer(sizer)
19 |
20 | frame.Show()
21 | return True
22 |
23 | if __name__ == "__main__":
24 | app = MyApp(False)
25 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_50_xrc_grid/grid.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | XRC Grid
8 |
9 |
--------------------------------------------------------------------------------
/recipe_50_xrc_grid/working_grid.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.grid
3 | from wx import xrc
4 |
5 |
6 | class MyApp(wx.App):
7 | def OnInit(self):
8 | self.res = xrc.XmlResource("grid.xrc")
9 |
10 | frame = self.res.LoadFrame(None, 'MyFrame')
11 | panel = xrc.XRCCTRL(frame, "MyPanel")
12 | grid = xrc.XRCCTRL(panel, "MyGrid")
13 | print(type(grid))
14 | grid.CreateGrid(25, 6)
15 |
16 | sizer = wx.BoxSizer(wx.VERTICAL)
17 | sizer.Add(grid, 1, wx.EXPAND|wx.ALL, 5)
18 |
19 | panel.SetSizer(sizer)
20 |
21 | frame.Show()
22 | return True
23 |
24 | if __name__ == "__main__":
25 | app = MyApp(False)
26 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_51_xrced/first_app.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx import xrc
3 |
4 | class MyApp(wx.App):
5 | def OnInit(self):
6 | self.res = xrc.XmlResource("twoBtns.xrc")
7 |
8 | self.frame = self.res.LoadFrame(None, 'MainFrame')
9 |
10 | self.frame.Show()
11 | return True
12 |
13 | if __name__ == "__main__":
14 | app = MyApp(False)
15 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_51_xrced/notebook.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | wxVERTICAL
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | wxALL|wxEXPAND
20 | 5
21 |
22 |
23 |
24 | XRC Notebook Demo
25 |
26 |
--------------------------------------------------------------------------------
/recipe_51_xrced/notebook_example.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx import xrc
3 | import wx.lib.platebtn as platebtn
4 |
5 |
6 | class MyApp(wx.App):
7 | def OnInit(self):
8 | self.res = xrc.XmlResource("notebook.xrc")
9 |
10 | frame = self.res.LoadFrame(None, 'DemoFrame')
11 | panel = xrc.XRCCTRL(frame, "DemoPanel")
12 | notebook = xrc.XRCCTRL(panel, "DemoNotebook")
13 |
14 | sizer = wx.BoxSizer(wx.VERTICAL)
15 | btn = platebtn.PlateButton(panel, label="Test",
16 | style=platebtn.PB_STYLE_DEFAULT)
17 | btn.Bind(wx.EVT_BUTTON, self.onButton)
18 | sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
19 | sizer.Add(btn)
20 | panel.SetSizer(sizer)
21 |
22 | frame.Show()
23 | return True
24 |
25 |
26 | def onButton(self, event):
27 | """"""
28 | print("You pressed the button!")
29 |
30 |
31 | if __name__ == "__main__":
32 | app = MyApp(False)
33 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_51_xrced/twoBtns.xrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | wxHORIZONTAL
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/recipe_51_xrced/twoBtns_xrc.py:
--------------------------------------------------------------------------------
1 | # This file was automatically generated by pywxrc.
2 | # -*- coding: UTF-8 -*-
3 |
4 | import wx
5 | import wx.xrc as xrc
6 |
7 | __res = None
8 |
9 | def get_resources():
10 | """ This function provides access to the XML resources in this module."""
11 | global __res
12 | if __res == None:
13 | __init_resources()
14 | return __res
15 |
16 |
17 |
18 |
19 | class xrcMainFrame(wx.Frame):
20 | #!XRCED:begin-block:xrcMainFrame.PreCreate
21 | def PreCreate(self, pre):
22 | """ This function is called during the class's initialization.
23 |
24 | Override it for custom setup before the window is created usually to
25 | set additional window styles using SetWindowStyle() and SetExtraStyle().
26 | """
27 | pass
28 |
29 | #!XRCED:end-block:xrcMainFrame.PreCreate
30 |
31 | def __init__(self, parent):
32 | # Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoStageCreation)
33 | pre = wx.PreFrame()
34 | self.PreCreate(pre)
35 | get_resources().LoadOnFrame(pre, parent, "MainFrame")
36 | self.PostCreate(pre)
37 |
38 | # Define variables for the controls, bind event handlers
39 |
40 | # ------------------------ Resource data ----------------------
41 |
42 | def __init_resources():
43 | global __res
44 | __res = xrc.EmptyXmlResource()
45 |
46 | __res.Load('twoBtns.xrc')
47 |
--------------------------------------------------------------------------------
/recipe_51_xrced/twoBtns_xrc_subclass.py:
--------------------------------------------------------------------------------
1 | # twoBtns_xrc_subclass.py
2 |
3 | import twoBtns_xrc
4 | import wx
5 |
6 |
7 | class XrcFrameSubClass(twoBtns_xrc.xrcMainFrame):
8 | """"""
9 |
10 | def __init__(self):
11 | """Constructor"""
12 | twoBtns_xrc.xrcMainFrame.__init__(self, parent=None)
13 | self.Show()
14 |
15 | if __name__ == "__main__":
16 | app = wx.App(False)
17 | frame = XrcFrameSubClass()
18 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_52_centering_widgets/faux_spacers.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MainFrame(wx.Frame):
5 | """"""
6 |
7 | def __init__(self):
8 | """Constructor"""
9 | wx.Frame.__init__(self, None, title="Center the Button")
10 | panel = wx.Panel(self)
11 |
12 | h_sizer = wx.BoxSizer(wx.HORIZONTAL)
13 | main_sizer = wx.BoxSizer(wx.VERTICAL)
14 |
15 | btn = wx.Button(panel, label="Centered")
16 | h_sizer.Add(btn, 0, wx.CENTER)
17 |
18 | main_sizer.Add((0,0), 1, wx.EXPAND)
19 | main_sizer.Add(h_sizer, 0, wx.CENTER)
20 | main_sizer.Add((0,0), 1, wx.EXPAND)
21 |
22 | panel.SetSizer(main_sizer)
23 |
24 | self.Show()
25 |
26 |
27 | if __name__ == "__main__":
28 | app = wx.App(False)
29 | frame = MainFrame()
30 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_52_centering_widgets/nested_sizers.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MainFrame(wx.Frame):
4 | """"""
5 |
6 |
7 | def __init__(self):
8 | """Constructor"""
9 | wx.Frame.__init__(self, None, title="Center the Button")
10 | panel = wx.Panel(self)
11 |
12 | main_sizer = wx.BoxSizer(wx.VERTICAL)
13 |
14 | btn = wx.Button(panel, label="Centered")
15 | main_sizer.AddStretchSpacer()
16 | main_sizer.Add(btn, 0, wx.CENTER)
17 | main_sizer.AddStretchSpacer()
18 |
19 | panel.SetSizer(main_sizer)
20 |
21 | self.Show()
22 |
23 |
24 | if __name__ == "__main__":
25 | app = wx.App(False)
26 | frame = MainFrame()
27 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_52_centering_widgets/stretch_spacer.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 |
4 | class MainFrame(wx.Frame):
5 | """"""
6 |
7 |
8 | def __init__(self):
9 | """Constructor"""
10 | wx.Frame.__init__(self, None, title="Center the Button")
11 | panel = wx.Panel(self)
12 |
13 | h_sizer = wx.BoxSizer(wx.HORIZONTAL)
14 | main_sizer = wx.BoxSizer(wx.VERTICAL)
15 |
16 | btn = wx.Button(panel, label="Centered")
17 | h_sizer.Add(btn, 0, wx.CENTER)
18 |
19 | main_sizer.AddStretchSpacer(prop=1)
20 | main_sizer.Add(h_sizer, 0, wx.CENTER)
21 | main_sizer.AddStretchSpacer(prop=1)
22 |
23 | panel.SetSizer(main_sizer)
24 |
25 | self.Show()
26 |
27 |
28 | if __name__ == "__main__":
29 | app = wx.App(False)
30 | frame = MainFrame()
31 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_53_widget_wrapping/main.py:
--------------------------------------------------------------------------------
1 | import random
2 | import wx
3 | from wx.lib.buttons import GenButton
4 |
5 |
6 | class MyPanel(wx.Panel):
7 | """"""
8 |
9 | def __init__(self, parent):
10 | """Constructor"""
11 | wx.Panel.__init__(self, parent)
12 |
13 | text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
14 | sizer = wx.WrapSizer()
15 | for letter in text:
16 | btn = GenButton(self, label=letter)
17 | r = random.randint(128, 255)
18 | g = random.randint(128, 255)
19 | b = random.randint(128, 255)
20 | btn.SetBackgroundColour(wx.Colour(r,g,b))
21 | btn.Refresh()
22 | sizer.Add(btn, 0, wx.ALL, 5)
23 |
24 | self.SetSizer(sizer)
25 |
26 |
27 | class MyFrame(wx.Frame):
28 | """"""
29 |
30 | def __init__(self):
31 | """Constructor"""
32 | wx.Frame.__init__(self, None, title="WrapSizers", size=(400,500))
33 | panel = MyPanel(self)
34 | self.Show()
35 |
36 |
37 | if __name__ == "__main__":
38 | app = wx.App(False)
39 | frame = MyFrame()
40 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_54_getting_selected_cells/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import wx.grid as gridlib
3 |
4 |
5 | class MyPanel(wx.Panel):
6 | """"""
7 |
8 | def __init__(self, parent):
9 | """Constructor"""
10 | wx.Panel.__init__(self, parent)
11 | self.currentlySelectedCell = (0, 0)
12 |
13 | self.myGrid = gridlib.Grid(self)
14 | self.myGrid.CreateGrid(12, 8)
15 | self.myGrid.Bind(gridlib.EVT_GRID_SELECT_CELL, self.onSingleSelect)
16 | self.myGrid.Bind(gridlib.EVT_GRID_RANGE_SELECT, self.onDragSelection)
17 |
18 | selectBtn = wx.Button(self, label="Get Selected Cells")
19 | selectBtn.Bind(wx.EVT_BUTTON, self.onGetSelection)
20 |
21 | sizer = wx.BoxSizer(wx.VERTICAL)
22 | sizer.Add(self.myGrid, 1, wx.EXPAND)
23 | sizer.Add(selectBtn, 0, wx.ALL|wx.CENTER, 5)
24 | self.SetSizer(sizer)
25 |
26 | def onDragSelection(self, event):
27 | """
28 | Gets the cells that are selected by holding the left
29 | mouse button down and dragging
30 | """
31 | if self.myGrid.GetSelectionBlockTopLeft():
32 | top_left = self.myGrid.GetSelectionBlockTopLeft()[0]
33 | bottom_right = self.myGrid.GetSelectionBlockBottomRight()[0]
34 | self.printSelectedCells(top_left, bottom_right)
35 |
36 | def onGetSelection(self, event):
37 | """
38 | Get whatever cells are currently selected
39 | """
40 | cells = self.myGrid.GetSelectedCells()
41 | if not cells:
42 | if self.myGrid.GetSelectionBlockTopLeft():
43 | top_left = self.myGrid.GetSelectionBlockTopLeft()[0]
44 | bottom_right = self.myGrid.GetSelectionBlockBottomRight()[0]
45 | self.printSelectedCells(top_left, bottom_right)
46 | else:
47 | print(self.currentlySelectedCell)
48 | else:
49 | print(cells)
50 |
51 | def onSingleSelect(self, event):
52 | """
53 | Get the selection of a single cell by clicking or
54 | moving the selection with the arrow keys
55 | """
56 | print("You selected Row %s, Col %s" % (event.GetRow(),
57 | event.GetCol()))
58 | self.currentlySelectedCell = (event.GetRow(),
59 | event.GetCol())
60 | event.Skip()
61 |
62 | def printSelectedCells(self, top_left, bottom_right):
63 | """
64 | Based on code from
65 | http://ginstrom.com/scribbles/2008/09/07/getting-the-selected-cells-from-a-wxpython-grid/
66 | """
67 | cells = []
68 |
69 | rows_start = top_left[0]
70 | rows_end = bottom_right[0]
71 |
72 | cols_start = top_left[1]
73 | cols_end = bottom_right[1]
74 |
75 | rows = range(rows_start, rows_end+1)
76 | cols = range(cols_start, cols_end+1)
77 |
78 | cells.extend([(row, col)
79 | for row in rows
80 | for col in cols])
81 |
82 | print("You selected the following cells: ", cells)
83 |
84 | for cell in cells:
85 | row, col = cell
86 | print(self.myGrid.GetCellValue(row, col))
87 |
88 |
89 | class MyFrame(wx.Frame):
90 | """"""
91 |
92 | def __init__(self):
93 | """Constructor"""
94 | wx.Frame.__init__(self, parent=None, title="Single Cell Selection")
95 | panel = MyPanel(self)
96 | self.Show()
97 |
98 |
99 | if __name__ == "__main__":
100 | app = wx.App(False)
101 | frame = MyFrame()
102 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_5_resetting_background_color/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 |
3 | class MyForm(wx.Frame):
4 |
5 | def __init__(self):
6 | wx.Frame.__init__(self, None, wx.ID_ANY,
7 | "Background Reset Tutorial")
8 |
9 | # Add a panel so it looks the correct on all platforms
10 | self.panel = wx.Panel(self, wx.ID_ANY)
11 |
12 | self.txt = wx.TextCtrl(self.panel)
13 | self.txt.SetBackgroundColour("Yellow")
14 |
15 | blueBtn = wx.Button(self.panel,
16 | label="Change Background Color")
17 | blueBtn.Bind(wx.EVT_BUTTON, self.onChangeBackground)
18 | resetBtn = wx.Button(self.panel, label="Reset")
19 | resetBtn.Bind(wx.EVT_BUTTON, self.onReset)
20 |
21 | topSizer = wx.BoxSizer(wx.VERTICAL)
22 | btnSizer = wx.BoxSizer(wx.HORIZONTAL)
23 |
24 | btnSizer.Add(blueBtn, 0, wx.ALL|wx.CENTER, 5)
25 | btnSizer.Add(resetBtn, 0, wx.ALL|wx.CENTER, 5)
26 |
27 | topSizer.Add(self.txt, 0, wx.ALL, 5)
28 | topSizer.Add(btnSizer, 0, wx.CENTER)
29 | self.panel.SetSizer(topSizer)
30 |
31 | def onChangeBackground(self, event):
32 | """
33 | Change the background color of the panel
34 | """
35 | self.panel.SetBackgroundColour("Blue")
36 | self.panel.Refresh()
37 |
38 | def onReset(self, event):
39 | """
40 | Reset the color of the panel to the default color
41 | """
42 | self.panel.SetBackgroundColour(wx.NullColour)
43 | self.txt.SetBackgroundColour(wx.NullColour)
44 | self.panel.Refresh()
45 |
46 |
47 | if __name__ == "__main__":
48 | app = wx.App(False)
49 | frame = MyForm()
50 | frame.Show()
51 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_6_dark_mode/__pycache__/dark_mode.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/driscollis/wxpythoncookbookcode/aed9d14c4e51d54acc8b6a645fedf27896c44a6f/recipe_6_dark_mode/__pycache__/dark_mode.cpython-35.pyc
--------------------------------------------------------------------------------
/recipe_6_dark_mode/dark_mode.py:
--------------------------------------------------------------------------------
1 | # dark_mode.py
2 | import wx
3 |
4 | try:
5 | from ObjectListView import ObjectListView
6 | except:
7 | ObjectListView = False
8 |
9 |
10 | def getWidgets(parent):
11 | """
12 | Return a list of all the child widgets
13 | """
14 | items = [parent]
15 | for item in parent.GetChildren():
16 | items.append(item)
17 | if hasattr(item, "GetChildren"):
18 | for child in item.GetChildren():
19 | items.append(child)
20 | return items
21 |
22 |
23 | def darkRowFormatter(listctrl, dark=False):
24 | """
25 | Toggles the rows in a ListCtrl or ObjectListView widget.
26 | """
27 |
28 | listItems = [listctrl.GetItem(i) for i
29 | in range(listctrl.GetItemCount())]
30 | for index, item in enumerate(listItems):
31 | if dark:
32 | if index % 2:
33 | item.SetBackgroundColour("Dark Grey")
34 | else:
35 | item.SetBackgroundColour("Light Grey")
36 | else:
37 | if index % 2:
38 | item.SetBackgroundColour("Light Blue")
39 | else:
40 | item.SetBackgroundColour("Yellow")
41 | listctrl.SetItem(item)
42 |
43 |
44 | def darkMode(self, normalPanelColor):
45 | """
46 | Toggles dark mode
47 | """
48 | widgets = getWidgets(self)
49 | panel = widgets[0]
50 | if normalPanelColor == panel.GetBackgroundColour():
51 | dark_mode = True
52 | else:
53 | dark_mode = False
54 | for widget in widgets:
55 | if dark_mode:
56 | if isinstance(widget, ObjectListView) or isinstance(widget, wx.ListCtrl):
57 | darkRowFormatter(widget, dark=True)
58 | widget.SetBackgroundColour("Dark Grey")
59 | widget.SetForegroundColour("White")
60 | else:
61 | if isinstance(widget, ObjectListView) or isinstance(widget, wx.ListCtrl):
62 | darkRowFormatter(widget)
63 | widget.SetBackgroundColour("White")
64 | widget.SetForegroundColour("Black")
65 | continue
66 | widget.SetBackgroundColour(wx.NullColour)
67 | widget.SetForegroundColour("Black")
68 | self.Refresh()
69 | return dark_mode
--------------------------------------------------------------------------------
/recipe_6_dark_mode/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | import dark_mode
3 |
4 |
5 | class MyPanel(wx.Panel):
6 | """"""
7 |
8 | def __init__(self, parent):
9 | """Constructor"""
10 | wx.Panel.__init__(self, parent)
11 | self.defaultColor = self.GetBackgroundColour()
12 |
13 | rows = [("Ford", "Taurus", "1996", "Blue"),
14 | ("Nissan", "370Z", "2010", "Green"),
15 | ("Porche", "911", "2009", "Red")
16 | ]
17 | self.list_ctrl = wx.ListCtrl(self, style=wx.LC_REPORT)
18 |
19 | self.list_ctrl.InsertColumn(0, "Make")
20 | self.list_ctrl.InsertColumn(1, "Model")
21 | self.list_ctrl.InsertColumn(2, "Year")
22 | self.list_ctrl.InsertColumn(3, "Color")
23 |
24 | index = 0
25 | for row in rows:
26 | self.list_ctrl.InsertStringItem(index, row[0])
27 | self.list_ctrl.SetStringItem(index, 1, row[1])
28 | self.list_ctrl.SetStringItem(index, 2, row[2])
29 | self.list_ctrl.SetStringItem(index, 3, row[3])
30 | if index % 2:
31 | self.list_ctrl.SetItemBackgroundColour(index, "white")
32 | else:
33 | self.list_ctrl.SetItemBackgroundColour(index, "yellow")
34 | index += 1
35 |
36 | btn = wx.ToggleButton(self, label="Toggle Dark")
37 | btn.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleDark)
38 | normalBtn = wx.Button(self, label="Test")
39 |
40 | sizer = wx.BoxSizer(wx.VERTICAL)
41 | sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
42 | sizer.Add(btn, 0, wx.ALL, 5)
43 | sizer.Add(normalBtn, 0, wx.ALL, 5)
44 | self.SetSizer(sizer)
45 |
46 | def onToggleDark(self, event):
47 | """"""
48 | dark_mode.darkMode(self, self.defaultColor)
49 |
50 |
51 | class MyFrame(wx.Frame):
52 | """"""
53 |
54 | def __init__(self):
55 | """Constructor"""
56 | wx.Frame.__init__(self, None,
57 | title="MvP ListCtrl Dark Mode Demo",
58 | size=(400, 400))
59 | panel = MyPanel(self)
60 | self.Show()
61 |
62 |
63 | if __name__ == "__main__":
64 | app = wx.App(False)
65 | frame = MyFrame()
66 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_7_pubsub/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from wx.lib.pubsub import pub
3 |
4 |
5 | class OtherFrame(wx.Frame):
6 | """"""
7 |
8 | def __init__(self):
9 | """Constructor"""
10 | wx.Frame.__init__(self, None, wx.ID_ANY, "Secondary Frame")
11 | panel = wx.Panel(self)
12 |
13 | msg = "Enter a Message to send to the main frame"
14 | instructions = wx.StaticText(panel, label=msg)
15 | self.msgTxt = wx.TextCtrl(panel, value="")
16 | closeBtn = wx.Button(panel, label="Send and Close")
17 | closeBtn.Bind(wx.EVT_BUTTON, self.onSendAndClose)
18 |
19 | sizer = wx.BoxSizer(wx.VERTICAL)
20 | flags = wx.ALL|wx.CENTER
21 | sizer.Add(instructions, 0, flags, 5)
22 | sizer.Add(self.msgTxt, 0, flags, 5)
23 | sizer.Add(closeBtn, 0, flags, 5)
24 | panel.SetSizer(sizer)
25 |
26 | def onSendAndClose(self, event):
27 | """
28 | Send a message and close frame
29 | """
30 | msg = self.msgTxt.GetValue()
31 | pub.sendMessage("panelListener", message=msg)
32 | pub.sendMessage("panelListener", message="test2", arg2="2nd argument!")
33 | self.Close()
34 |
35 |
36 | class MyPanel(wx.Panel):
37 | """"""
38 |
39 | def __init__(self, parent):
40 | """Constructor"""
41 | wx.Panel.__init__(self, parent)
42 | pub.subscribe(self.myListener, "panelListener")
43 |
44 | btn = wx.Button(self, label="Open Frame")
45 | btn.Bind(wx.EVT_BUTTON, self.onOpenFrame)
46 |
47 | def myListener(self, message, arg2=None):
48 | """
49 | Listener function
50 | """
51 | print("Received the following message: " + message)
52 | if arg2:
53 | print("Received another arguments: " + str(arg2))
54 |
55 | def onOpenFrame(self, event):
56 | """
57 | Opens secondary frame
58 | """
59 | frame = OtherFrame()
60 | frame.Show()
61 |
62 |
63 | class MyFrame(wx.Frame):
64 | """"""
65 |
66 | def __init__(self):
67 | """Constructor"""
68 | wx.Frame.__init__(self, None, title="New PubSub API Tutorial")
69 | panel = MyPanel(self)
70 | self.Show()
71 |
72 |
73 | if __name__ == "__main__":
74 | app = wx.App(False)
75 | frame = MyFrame()
76 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_8_pydispatcher/main.py:
--------------------------------------------------------------------------------
1 | import wx
2 | from pydispatch import dispatcher
3 |
4 |
5 | class OtherFrame(wx.Frame):
6 | """"""
7 |
8 |
9 | def __init__(self):
10 | """Constructor"""
11 | wx.Frame.__init__(self, None, wx.ID_ANY, "Secondary Frame")
12 | panel = wx.Panel(self)
13 |
14 | msg = "Enter a Message to send to the main frame"
15 | instructions = wx.StaticText(panel, label=msg)
16 | self.msgTxt = wx.TextCtrl(panel, value="")
17 | closeBtn = wx.Button(panel, label="Send and Close")
18 | closeBtn.Bind(wx.EVT_BUTTON, self.onSendAndClose)
19 |
20 | sizer = wx.BoxSizer(wx.VERTICAL)
21 | flags = wx.ALL|wx.CENTER
22 | sizer.Add(instructions, 0, flags, 5)
23 | sizer.Add(self.msgTxt, 0, flags, 5)
24 | sizer.Add(closeBtn, 0, flags, 5)
25 | panel.SetSizer(sizer)
26 |
27 |
28 | def onSendAndClose(self, event):
29 | """
30 | Send a message and close frame
31 | """
32 | msg = self.msgTxt.GetValue()
33 | dispatcher.send("panelListener", message=msg)
34 | dispatcher.send("panelListener", message="test2", arg2="2nd argument!")
35 | self.Close()
36 |
37 |
38 | class MyPanel(wx.Panel):
39 | """"""
40 |
41 |
42 | def __init__(self, parent):
43 | """Constructor"""
44 | wx.Panel.__init__(self, parent)
45 |
46 | dispatcher.connect(self.myListener, signal="panelListener",
47 | sender=dispatcher.Any)
48 |
49 | btn = wx.Button(self, label="Open Frame")
50 | btn.Bind(wx.EVT_BUTTON, self.onOpenFrame)
51 |
52 |
53 | def myListener(self, message, arg2=None):
54 | """
55 | Listener function
56 | """
57 | print("Received the following message: " + message)
58 | if arg2:
59 | print("Received another arguments: " + str(arg2))
60 |
61 |
62 | def onOpenFrame(self, event):
63 | """
64 | Opens secondary frame
65 | """
66 | frame = OtherFrame()
67 | frame.Show()
68 |
69 |
70 | class MyFrame(wx.Frame):
71 | """"""
72 |
73 |
74 | def __init__(self):
75 | """Constructor"""
76 | wx.Frame.__init__(self, None, title="PyDispatcher Tutorial")
77 | panel = MyPanel(self)
78 | self.Show()
79 |
80 |
81 | if __name__ == "__main__":
82 | app = wx.App(False)
83 | frame = MyFrame()
84 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_9_disable_wizard_next/main_classic.py:
--------------------------------------------------------------------------------
1 | # wxPython Classic Edition
2 |
3 | import wx
4 | import wx.wizard
5 |
6 |
7 | class WizardPage(wx.wizard.PyWizardPage):
8 |
9 | def __init__(self, parent, title):
10 | wx.wizard.PyWizardPage.__init__(self, parent)
11 | self.next = None
12 | self.prev = None
13 | self.initializeUI(title)
14 |
15 | def initializeUI(self, title):
16 | # create grid layout manager
17 | self.sizer = wx.GridBagSizer()
18 | self.SetSizerAndFit(self.sizer)
19 |
20 | def addWidget(self, widget, pos, span):
21 | self.sizer.Add(widget, pos, span, wx.EXPAND)
22 |
23 | # getters and setters
24 | def SetPrev(self, prev):
25 | self.prev = prev
26 |
27 | def SetNext(self, next):
28 | self.next = next
29 |
30 | def GetPrev(self):
31 | return self.prev
32 |
33 | def GetNext(self):
34 | return self.next
35 |
36 |
37 | class MyWizard(wx.wizard.Wizard):
38 | """"""
39 |
40 | def __init__(self):
41 | """Constructor"""
42 | wx.wizard.Wizard.__init__(self, None,
43 | title="Disable Next")
44 | self.SetPageSize((500, 350))
45 |
46 | mypage1 = self.create_page1()
47 |
48 | forward_btn = self.FindWindowById(wx.ID_FORWARD)
49 | forward_btn.Disable()
50 |
51 | self.timer = wx.Timer(self)
52 | self.Bind(wx.EVT_TIMER, self.onUpdate, self.timer)
53 | self.timer.Start(1)
54 |
55 | self.RunWizard(mypage1)
56 |
57 | def create_page1(self):
58 | page1 = WizardPage(self, "Page 1")
59 | d = wx.StaticText(page1, label="test")
60 | page1.addWidget(d, (2, 1), (1,5))
61 |
62 | self.text1 = wx.TextCtrl(page1)
63 | page1.addWidget(self.text1, (3,1), (1,5))
64 |
65 | self.text2 = wx.TextCtrl(page1)
66 | page1.addWidget(self.text2, (4,1), (1,5))
67 |
68 | page2 = WizardPage(self, "Page 2")
69 | page2.SetName("page2")
70 | self.text3 = wx.TextCtrl(page2)
71 | self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.onPageChanged)
72 | page3 = WizardPage(self, "Page 3")
73 |
74 | # Set links
75 | page2.SetPrev(page1)
76 | page1.SetNext(page2)
77 | page3.SetPrev(page2)
78 | page2.SetNext(page3)
79 |
80 | return page1
81 |
82 | def onPageChanged(self, event):
83 | """"""
84 | page = event.GetPage()
85 |
86 | if page.GetName() == "page2":
87 | self.text3.SetValue(self.text2.GetValue())
88 |
89 | def onUpdate(self, event):
90 | """
91 | Enables the Next button if both text controls have values
92 | """
93 | value_one = self.text1.GetValue()
94 | value_two = self.text2.GetValue()
95 | if value_one and value_two:
96 | forward_btn = self.FindWindowById(wx.ID_FORWARD)
97 | forward_btn.Enable()
98 | self.timer.Stop()
99 |
100 |
101 | def main():
102 | """"""
103 | wizard = MyWizard()
104 |
105 |
106 | if __name__ == "__main__":
107 | app = wx.App(False)
108 | main()
109 | app.MainLoop()
--------------------------------------------------------------------------------
/recipe_9_disable_wizard_next/main_phoenix.py:
--------------------------------------------------------------------------------
1 | # wxPython Phoenix Version
2 |
3 | import wx
4 | from wx.adv import Wizard, WizardPage
5 |
6 | class MyWizardPage(WizardPage):
7 |
8 | def __init__(self, parent, title):
9 | WizardPage.__init__(self, parent)
10 | self.next = None
11 | self.prev = None
12 | self.initializeUI(title)
13 |
14 | def initializeUI(self, title):
15 | # create grid layout manager
16 | self.sizer = wx.GridBagSizer()
17 | self.SetSizer(self.sizer)
18 |
19 | def addWidget(self, widget, pos, span):
20 | self.sizer.Add(widget, pos, span, wx.EXPAND)
21 |
22 | # getters and setters
23 | def SetPrev(self, prev):
24 | self.prev = prev
25 |
26 | def SetNext(self, next):
27 | self.next = next
28 |
29 | def GetPrev(self):
30 | return self.prev
31 |
32 | def GetNext(self):
33 | return self.next
34 |
35 |
36 | class MyWizard(Wizard):
37 | """"""
38 |
39 | def __init__(self):
40 | """Constructor"""
41 | Wizard.__init__(self, None,
42 | title="Disable Next")
43 | self.SetPageSize((500, 350))
44 |
45 | mypage1 = self.create_page1()
46 |
47 | forward_btn = self.FindWindowById(wx.ID_FORWARD)
48 | forward_btn.Disable()
49 |
50 | self.timer = wx.Timer(self)
51 | self.Bind(wx.EVT_TIMER, self.onUpdate, self.timer)
52 | self.timer.Start(1)
53 |
54 | self.RunWizard(mypage1)
55 |
56 | def create_page1(self):
57 | page1 = MyWizardPage(self, "Page 1")
58 | d = wx.StaticText(page1, label="test")
59 | page1.addWidget(d, (2, 1), (1,5))
60 |
61 | self.text1 = wx.TextCtrl(page1)
62 | page1.addWidget(self.text1, (3,1), (1,5))
63 |
64 | self.text2 = wx.TextCtrl(page1)
65 | page1.addWidget(self.text2, (4,1), (1,5))
66 |
67 | page2 = MyWizardPage(self, "Page 2")
68 | page2.SetName("page2")
69 | self.text3 = wx.TextCtrl(page2)
70 | self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGED, self.onPageChanged)
71 |
72 | page3 = MyWizardPage(self, "Page 3")
73 |
74 | # Set links
75 | page2.SetPrev(page1)
76 | page1.SetNext(page2)
77 | page3.SetPrev(page2)
78 | page2.SetNext(page3)
79 |
80 | return page1
81 |
82 | def onPageChanged(self, event):
83 | """"""
84 | page = event.GetPage()
85 |
86 | if page.GetName() == "page2":
87 | self.text3.SetValue(self.text2.GetValue())
88 |
89 | def onUpdate(self, event):
90 | """
91 | Enables the Next button if both text controls have values
92 | """
93 | value_one = self.text1.GetValue()
94 | value_two = self.text2.GetValue()
95 | if value_one and value_two:
96 | forward_btn = self.FindWindowById(wx.ID_FORWARD)
97 | forward_btn.Enable()
98 | self.timer.Stop()
99 |
100 |
101 | def main():
102 | """"""
103 | wizard = MyWizard()
104 |
105 |
106 | if __name__ == "__main__":
107 | app = wx.App(False)
108 | main()
109 | app.MainLoop()
--------------------------------------------------------------------------------