#!/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 #---------------------------------------------------------------------------- #