#!/bin/env python
"""
Filename: evmui.py
Project : The Electronic Voting Machine 2003
Purpose : This file contains initial source code for a
rudimentary electronic PC based voting machine
Description: A simple tkinter based GUI which allows you
to select candidates and sumbit a vote.
Created : Matt Shomphe, Jul 2003
Review/Modification History
---------------------------
Reviewed by Anand Pillai Aug 07 2003
1. Added this history/file comment header
2. Added comments for functions which did not have them
3. Comment strings use \" and internal strings use \'
4. Renamed file to evmui.py
"""
## import all of the wxPython GUI package
from wxPython.wx import *
from random import random
from time import time
def ShowVotingMessage(parentFrame, title, message):
dlg = wxMessageDialog(parentFrame, message,
title, wxOK | wxICON_INFORMATION)
#wxYES_NO | wxNO_DEFAULT | wxCANCEL | wxICON_INFORMATION)
dlg.ShowModal()
dlg.Destroy()
#---------------------------------------------------------------------------
class BallotObject:
def __init__(self, voterid):
self.voterid = voterid
self.president = None
self.id = int(time())
def ballot(self):
s = """
%s
""" % (self.id, self.voterid, self.president)
return(s.strip())
#---------------------------------------------------------------------------
## Create a new frame class, derived from the wxPython Frame.
class VoteFrame(wxFrame):
def __init__(self, parent, id, title):
# First, call the base class' __init__ method to create the frame
wxFrame.__init__(self, parent, id, title,
wxPoint(100, 100), wxSize(210, 270))
self.candidates = []
self.actions = [['Vote', 10, self.OnVote],
['Quit', 20, self.OnQuit],
['Print', 30, self.OnPrint]]
self.chosenCandidate = -1
self.other = None
self.otherStr = 'Other'
self.voter = str(random())[2:] #generate randdom id
self.ballot = BallotObject(self.voter)
self.candDelta = 30
# Add a panel and some controls to display the size and position
panel = wxPanel(self, -1)
self.panel = panel
def OnQuit(self, event=None):
""" Event handler for quitting the UI """
#TODO
#if askyesno('Verify Quit', 'Really quit?'): OnCloseWindow(self, event)
# This method is called automatically when the CLOSE event is
# sent to this window
def OnCloseWindow(self, event):
# tell the window to kill itself
self.Destroy()
# This method is called by the System when the window is resized,
# because of the association above.
def OnSize(self, event):
size = event.GetSize()
self.sizeCtrl.SetValue("%s, %s" % (size.width, size.height))
# tell the event system to continue looking for an event handler,
# so the default handler will get called.
event.Skip()
# This method is called by the System when the window is moved,
# because of the association above.
def OnMove(self, event):
pos = event.GetPosition()
self.posCtrl.SetValue("%s, %s" % (pos.x, pos.y))
def OnSelectCandidate( self, event ):
radioSelected = event.GetEventObject()
candidateCount = 0
for radio in self.candidate_ctrls:
if radio is radioSelected:
self.chosenCandidate = candidateCount
candidateCount += 1
def OnEvtText(self, event):
self.otherStr = event.GetString()
def OnButtonClick( self, event):
pass
def OnVote(self, event=None):
"""
Called when the 'Vote' button is pressed. In theory,
this should create a 'VoteObject' that can be printed or handled
in some way. """
candId = self.chosenCandidate
if(candId >= 0 and candId < (len(self.candidates)+1)):
if(candId == len(self.candidates)):
candidate = self.otherStr
else:
candidate = self.candidates[candId]
else:
ShowVotingMesssage(self, 'Error!', 'You need to pick someone to vote for!')
return(None)
ShowVotingMessage(self, 'You voted for...', candidate)
return(None)
def OnPrint(self, event=None):
""" Prints to a file named 'ballot' """
filename = 'ballot%s.xml'%int(time())
open(filename, 'w').write(self.ballot.ballot())
return (None)
def Build(self):
""" Creates the Voting UI """
self.__buildCandidates()
self.__buildActions()
return(self)
def __buildCandidates(self, event=None):
""" Builds gui elements populating them
with list of candidates """
candidates = self.candidates
if not candidates:
raise ValueError, (1, 'Failed to provide the object with cadidates')
self.candidate_ctrls = []
candidateCount = 0
posY = 0
for candidate in candidates:
posY = 10 + self.candDelta*candidateCount
pos = wxPoint(10, posY)
radio = wxRadioButton(self.panel, -1, candidate, pos)
self.candidate_ctrls.append(radio)
candidateCount += 1
#other
posY += self.candDelta
pos = wxPoint(10, posY)
radio = wxRadioButton(self.panel, -1, "Other", pos)
self.candidate_ctrls.append(radio)
for radio in self.candidate_ctrls:
EVT_RADIOBUTTON( self, radio.GetId(), self.OnSelectCandidate )
pos = wxPoint(60, posY)
otherTc = wxTextCtrl(self.panel, -1, "", pos, (125, -1))
otherTc.SetInsertionPoint(0)
self.otherTc = otherTc
EVT_TEXT(self, otherTc.GetId(), self.OnEvtText)
def __buildActions(self, event=None):
""" Creates buttons and associates them with user
actions """
actions = self.actions
actionCount = 0
for action in actions:
size = wxSize(60, 30)
pos = wxPoint(10+size.GetWidth()*actionCount, self.candDelta * (len(self.candidates)+1) + 20)
txt, id, act = action
b = wxButton(self.panel, id, txt, pos, size)
EVT_BUTTON(self, id, act)
actionCount += 1
# b.SetToolTipString()
#---------------------------------------------------------------------------
# Every wxWindows application must have a class derived from wxApp
class EVMApp(wxApp):
# wxWindows calls this method to initialize the application
def OnInit(self):
# Create an instance of our customized Frame class
frame = VoteFrame(NULL, -1, "Vote for President")
frame.candidates = [ 'Howard Dean',
'George W. Bush',
'John Kerry',
'Richard Gephardt',
'Bob Graham']
frame.Build()
frame.Show(true)
# Tell wxWindows that this is our main window
self.SetTopWindow(frame)
# Return a success flag
return true
#---------------------------------------------------------------------------
app = EVMApp(0) # Create an instance of the application class
app.MainLoop() # Tell it to start processing events
#----------------------------------------------------------------------------
#