[Tutor] Program Review: startup_user script -and- TimedMultiChoiceDialog class
ethan s
callethan at gmail.com
Sun Jan 20 23:16:18 CET 2008
Hi folks. I'd love some feedback for two scripts.
-startup_user: Intended to be called from a users logon script to
present a list of apps to launch. List items can be set to default on or
off. I run it from my system logon script like this:
if exist "c:\_utils\scripts\logon_%USERNAME%.py" pythonw
"c:\_utils\scripts\logon_%USERNAME%.py"
-timedmultichoicedialog: A derivative of wx.MultiChoiceDialog. Added:
Timeout, statusbar countdown, default selected status of list items.
Prerequisites: wxPython
OS: Tested WinXP. Since only imports basically are wx.MultiChoiceDialog
and subprocess.Popen it they may/should work on on *nix.
Questions/Notes:
Left startup_user as simple script in line with simple nature of logon
scripts rather than do 'if __name__ == '__main__': Does that choice make
sense?
Script prints result info to stdout on theory that will run from pythonw or
redirect to NUL if want quiet. Could control with command line switch if
implement a main. Again, good choice or does in rankle?
Could not get to/change message on dialog after setting it, so update
the dialogs titlebar instead. Acceptable? Better ideas? Know how to
change the message on a wx.MultiChoiceDialog when after ShowModal()?
Are these (after any fixes suggested) of use enough to submit wxPython
list for comment or otherwise publish?
----start startup_user.py----
#!/usr/bin/env python
# startup_user.py - default programs launcher GUI
# Author: Ethan Shames - my.first.name NatO SPdogdiniAM.com
# Created: 2007-12-19
# last edit: 2008-01-19
# Version: .8
# lessons learned:
# Event incantations:
# (D'oh)Event Binds must be to function w/o '()'s or function will
# be __called__ when mentioned.
# No parameter passing when Binding. (use self)
# Event functions must be of form "def (self, event):" or they don't
work right.
# Don't try to guess the event, get it from the docs.
# Since this is a wx derived modal dialog, these changes to behavior
# work. Not necessarily so if system derived like MessageBox
# TODO runas domain/user as LST parameter. Encode password.
# TODO 'save selections' button to remember on/off status of list item
# TODO program list maintenance
from wx import App, ID_OK
from subprocess import Popen
from timedmultichoicedialog import TimedMultiChoiceDialog
def launch(apps):
#Launch a list of targets, return results
results = []
for app in apps:
try:
results.append(Popen(app))
except WindowsError, e: # Not sure what error raised if *nix
results.append(" subprocess.Popen: %s\n Starting File: %s" %
(e, app))
continue
return results
# List of items to launch. True/False flag sets default
# checked/unchecked status of item on list.
LST = [[True, r"C:\WINDOWS\system32\notepad.exe"],
[True, r"C:\WINDOWS\system32\calc.exe"],
[False, r"C:\you have fail.test"],
]
SELECTED = []
DELAY = 5000
MESSAGE = "Starting these in %s seconds. Click any item to stop timer" %
(DELAY/1000)
TITLE = "startup manager"
app = App()
dlg = TimedMultiChoiceDialog(message=MESSAGE, title=TITLE, lst=LST,
delay=DELAY)
# Clever idiom: ()calling ShowModal, which blocks processing until the
dialog dismissed,
# then check the return value for OK (vs. CANCEL)
if (dlg.ShowModal() == ID_OK):
selections = dlg.GetSelections ()
SELECTED = [LST[x][1] for x in selections]
##print("Selections: %s --> %s" % (selections, SELECTED)) #uncomment
to test
# Destroy dialog before moving on to launch selected items.
dlg.Destroy() #Breakpoint here to test
results = launch(SELECTED)
for r in results:
try:
print(r.__dict__)
except AttributeError:
print(r)
----end startup_user.py----
----start timedmultichoicedialog.py----
#!/usr/bin/env python
# timedmultchoicedialog.py - multi-choice dialog box with timeout
# Author: Ethan Shames - my.first.name NatO SPdogdiniAM.com
# Created: 2007-12-19
# last edit: 2008-01-19
# Version: .8
# TODO Add group as parameter to lst; Create button for each unique
# group to deselect/select group.
# TODO click anywhere to stop timer
import wx
class TimedMultiChoiceDialog(wx.MultiChoiceDialog):
"""
MultiChoiceDialog with added timeout delay and countdown in titlebar.
Timer stops on change.
lst: [[True|False, item], ...] True/False flag sets default
checked/unchecked status of item on list.
message: Message on header of dialog.
title: Titlebar text.
delay: Delay before timeout. Default value 10000ms.
tic: Update titlebar text interval.
"""
def __init__(self, message, lst, title=None, parent=None, delay=10000,
tic=1000):
self.tic = tic # timer tick interval
self.timeout = delay # init timeout for countdown
if title == None: title = "TimedMultiChoiceDialog"
self.title = title
mytitle = '%s - "T-%ss"' % (title, delay/1000)
items = [i[1] for i in lst]
wx.MultiChoiceDialog.__init__(self, None, message, mytitle, items)
self.SetWindowStyle(self.WindowStyle|wx.STAY_ON_TOP)
selections = [i for i in range(len(lst)) if lst[i][0] == True]
self.SetSelections(selections)
self.Bind(wx.EVT_TIMER, self.countdown )
# stop timer on change. would prefer on click, but no sus.
self.Bind(wx.EVT_CHECKLISTBOX, self.on_change)
self.t1 = wx.Timer(self)
self.t1.Start(1000)
def on_change(self, evt):
# stop timer if item on list is changed.
if self.t1.IsRunning():
self.t1.Stop()
self.SetLabel(self.title +" - timer stopped")
def countdown(self, evt):
# update titlebar with time remaining until launch
# TODO Update header message text, not titlebar.
# -There is no SetMessage(?) SetLabel, SetTitle change titlebar
self.timeout -= self.tic
if self.timeout > 0:
title = '%s - "T-%ss"' % (self.title, self.timeout/1000)
self.SetLabel(title)
self.t1.Start (self.tic)
return
self.press_ok()
def press_ok(self):
# Create 'pushed OK' event, post it to dlg
ok = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED , wx.ID_OK )
wx.PostEvent(self, ok)
----end timedmultichoicedialog.py----
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20080120/cb5993b4/attachment-0001.htm
More information about the Tutor
mailing list