Wxpython dynamically changes the content of Choice - user-interface

The problem is that there are two Choice drop-down boxes in the UI, the content of the second box is initially empty, and when the user selects an option in the first box, the corresponding option appears in the second box。
For example, if the first box is month, the second box is day, and the user selects January, then the second box has 1... . 31, the user chooses February, the second frame is 1... 28。
My code is as follows.
`
import wx
class myFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__ ( self, None, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
bSizer9 = wx.BoxSizer( wx.VERTICAL )
self.m_staticText14 = wx.StaticText( self, wx.ID_ANY, u"select Month", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText14.Wrap( -1 )
bSizer9.Add( self.m_staticText14, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
# select month
m_choice1Choices = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
self.m_choice1 = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice1Choices, 0 )
self.m_choice1.SetSelection( 0 )
bSizer9.Add( self.m_choice1, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.m_staticText15 = wx.StaticText( self, wx.ID_ANY, u"select Day", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText15.Wrap( -1 )
bSizer9.Add( self.m_staticText15, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
# select day
m_choice2Choices = [str(i) for i in range(1,31)]
self.m_choice2 = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice2Choices, 0 )
self.m_choice2.SetSelection( 0 )
bSizer9.Add( self.m_choice2, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.SetSizer( bSizer9 )
self.Layout()
self.Centre( wx.BOTH )
app = wx.App()
myFrame().Show()
app.MainLoop()
`

The problem does not really reside in the wx.Choice instead it's how do I offer different day options for different months.
The Choice issue is simply addressed by changes to the items in its list and that can be done by a Bind to the Month choice.
Simply put, if the Month is changed, alter the list of days as appropriate to the month. (The ditty, "30 days hath September, April, June and November. All the rest have 31, excepting February alone")
Below, somewhat untested but you get the idea, I Bind the month choice to a callback which resets the list of days for the chosen month.
As a side note, check your range command, the stop value is where it stops, so range(1,31) will give you 1...30
import wx
import datetime
from calendar import monthrange
year = datetime.datetime.now().year
month_days = []
for i in range(1,13):
month_days.append(monthrange(year,i)[1])
class myFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__ ( self, None, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
bSizer9 = wx.BoxSizer( wx.VERTICAL )
self.m_staticText14 = wx.StaticText( self, wx.ID_ANY, u"select Month", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText14.Wrap( -1 )
bSizer9.Add( self.m_staticText14, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
# select month
m_choice1Choices = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
self.m_choice1 = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_choice1Choices, 0 )
self.m_choice1.SetSelection( 0 )
bSizer9.Add( self.m_choice1, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.m_staticText15 = wx.StaticText( self, wx.ID_ANY, u"select Day", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText15.Wrap( -1 )
bSizer9.Add( self.m_staticText15, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
# select day
#m_choice2Choices = [str(i) for i in range(1,31)]
mth_idx = self.m_choice1.GetSelection()
self.m_choice2Choices = [str(i) for i in range(1,month_days[mth_idx]+1)]
self.m_choice2 = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, self.m_choice2Choices, 0 )
self.m_choice2.SetSelection( 0 )
bSizer9.Add( self.m_choice2, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.m_choice1.Bind(wx.EVT_CHOICE, self.DaysInMonth)
self.SetSizer( bSizer9 )
self.Layout()
self.Centre( wx.BOTH )
def DaysInMonth(self, event):
mth_idx = self.m_choice1.GetSelection()
self.m_choice2Choices = [str(i) for i in range(1,month_days[mth_idx]+1)]
self.m_choice2.SetItems(self.m_choice2Choices)
app = wx.App()
myFrame().Show()
app.MainLoop()

Related

micropython temp sensor gives CRC error when in larger code file

I have a temp sensor taht i need to use for a school project it works perfectly when i dont put it together with the rest of the code but when I do it gives a CRC error after giving me the temp 3 or 4 times.
import onewire
import time, ds18x20
from machine import Pin
ow = onewire.OneWire(Pin(26))
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
print("roms=",roms) # roms= [bytearray(b'(\x19\x1e\xbf\x0b\x00\x00\xc7'), bytearray(b'(\xd2*y\x97\x13\x03\xc3')]
# https://web.alfredstate.edu/faculty/weimandn/miscellaneous/ascii/ascii_index.html
last_reading_time = 0
while(1):
ds.convert_temp()
for rom in roms:
temp=ds.read_temp(rom)
current_time = time.time() # get the current time
if current_time - last_reading_time >= 10:
last_reading_time = current_time
print(temp)
this works without a problem.
from wifi import ssid, password, mqtt_server, client_id
from machine import Pin, I2C
from time import sleep, ticks_ms
from sh1106 import SH1106_I2C
import utime
import machine
import network
from umqttsimple import MQTTClient
from var import *
import time
import urequests
import json
from Pins import *
import onewire
import time, ds18x20
buzzer.freq(500)
buzzer.duty(0)
ow = onewire.OneWire(Pin(26))
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
print("roms=",roms)
topic_sub = b'CVOFOCUS/RP3/*******'
topic_pub = b'CVOFOCUS/RP3/*******'
topic_pub2 = b'CVOFOCUS/RP3/******'
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
while station.isconnected() == False:
pass
print('Connection successful')
print(station.ifconfig())
WIDTH = 128
HEIGHT = 64
i2c = I2C(scl=Pin(22), sda=Pin(27)) #Init i2c
oled= SH1106_I2C(128, 64, i2c)
# CONSTANTS
KEY_UP = const(0)
KEY_DOWN = const(1)
gewenste_code = "7ADC"
ingegeven_code = ""
keys = [['1', '2', '3', 'A'], ['4', '5', '6', 'B'], ['7', '8', '9', 'C'], ['*', '0', '#', 'D']]
# Pin names for Pico
cols = [19,16,15,23]
rows = [2,4,5,18]
# set pins for rows as outputs
row_pins = [Pin(pin_name, mode=Pin.OUT) for pin_name in rows]
# set pins for cols as inputs
col_pins = [Pin(pin_name, mode=Pin.IN, pull=Pin.PULL_DOWN) for pin_name in cols]
def init():
for row in range(0,4):
for col in range(0,4):
row_pins[row].value(0)
def scan(row, col):
""" scan the keypad """
# set the current column to high
row_pins[row].value(1)
key = None
# check for keypressed events
if col_pins[col].value() == KEY_DOWN:
key = KEY_DOWN
if col_pins[col].value() == KEY_UP:
key = KEY_UP
row_pins[row].value(0)
# return the key state
return key
print("starting")
# set all the columns to low
init()
def oled_text(text):
oled.fill(0)
oled.text(text, 10, 10)
oled.show()
def trigger_alarm(trig_by = ""):
global is_alarm_on, is_alarm_trigered, alarm_timer
if is_alarm_on and not is_alarm_trigered:
print("Alarm trigered by", trig_by)
is_alarm_trigered = 1
alarm_timer = ticks_ms()
def subscribe_callback(topic, msg): #b'cvofocus/wimverlinden/msg_for_esp'
print((topic, msg))
global is_alarm_on
if topic == b'CVOFOCUS/RP3/Matteo_Alarm':
if msg== b'Alarm aan':
if is_alarm_on == 0:
is_alarm_on = not is_alarm_on
print("alarm_on =" , str(is_alarm_on))
msg = b'Alarm aan'
client.publish(topic_pub, msg)
oled.text('van afstand', 10, 30)
oled.text('bediend', 10, 38)
oled.show()
elif msg ==b'Alarm off':
print("correct")
if is_alarm_on == 1:
is_alarm_on = not is_alarm_on
print("alarm_on =" , str(is_alarm_on))
if is_alarm_on == 0:
# alles uitschakelen
is_alarm_trigered = 0
led_red.value(0)
buzzer.duty(0)
oled.text('van afstand', 10, 30)
oled.text('bediend', 10, 38)
oled.show()
msg = b'Alarm uit'
client.publish(topic_pub, msg)
led_green.value(1)
sleep(0.2)
led_green.value(0)
sleep(0.2)
led_green.value(1)
sleep(0.2)
led_green.value(0)
ingegeven_code = ""
def connect_and_subscribe():
global client_id, mqtt_server, topic_sub
client = MQTTClient(client_id, mqtt_server)
client.set_callback(subscribe_callback)
client.connect()
client.subscribe(topic_sub)
print('Connected to %s MQTT broker, subscribed to %s topic' % (mqtt_server, topic_sub))
return client
def restart_and_reconnect():
print('Failed to connect to MQTT broker. Reconnecting...')
time.sleep(10)
machine.reset()
try:
client = connect_and_subscribe()
except OSError as e:
restart_and_reconnect()
###############################
###############################
while True:
ds.convert_temp()
for rom in roms:
temp= ds.read_temp(rom)
current_time = time.time() # get the current time
if current_time - last_reading_time >= 60:
last_reading_time = current_time
msg = b"%d" % temp
client.publish(topic_pub2, msg)
print(f"temp send ({temp})")
try:
client.check_msg() # needed in loop?
status_button2 = button2.value()
if status_button_before2 != status_button2:
status_button_before2 = status_button2
if status_button2 == 0:
msg = b'PANIC PANIC PANIC PANIC!'
client.publish(topic_pub, msg)
response = urequests.post(api_endpoint, data=json.dumps({
"token": app_token,
"user": user_key,
"message": message,
"sound": sound,
"priority": priority,
"retry": retry,
"expire": expire,
}), headers={"Content-type": "application/json"})
print(response.text)
except OSError as e:
restart_and_reconnect()
status_button = button.value()
if status_button_before != status_button:
status_button_before = status_button
if status_button == 0:
if is_alarm_on == 0:
is_alarm_on = not is_alarm_on
print("alarm_on =" , str(is_alarm_on))
msg = b'Alarm aan'
client.publish(topic_pub, msg)
sleep(0.05)
if is_alarm_on:
if ticks_ms() - timestamp_led > 200:
timestamp_led = ticks_ms()
is_led_on = not is_led_on
#print("is_led_on", is_led_on)
pir_status = pir.value()
if pir_status != status_pir_before:
status_pir_before = pir_status
print("PIR=" , pir_status)
if pir_status == 1:
trigger_alarm("PIR")
if is_alarm_trigered:
if ticks_ms() - timestamp_buzzer > 500:
timestamp_buzzer = ticks_ms()
is_buzzer_on = not is_buzzer_on
#print("is_buzzer_on", is_buzzer_on)
buzzer.duty(512 * is_buzzer_on)
if is_alarm_on == True:
led_red.value(1)
oled.fill(0)
for row in range(4):
for col in range(4):
key = scan(row, col)
if key == KEY_DOWN:
oled.text("Key Pressed: ",10,0)
print("Key Pressed", keys[row][col])
oled.text(keys[row][col], 55, 30)
oled.show()
##MATTEO
ingegeven_code += keys[row][col]
print(ingegeven_code)
if len(ingegeven_code) > 3:
oled.fill(0)
oled.show()
if ingegeven_code == gewenste_code:
oled.text("correct",35,0)
print("correct")
if is_alarm_on == 1:
is_alarm_on = not is_alarm_on
print("alarm_on =" , str(is_alarm_on))
if is_alarm_on == 0:
# alles uitschakelen
is_alarm_trigered = 0
led_red.value(0)
buzzer.duty(0)
oled.text(ingegeven_code, 45, 30)
oled.show()
led_green.value(1)
sleep(0.2)
led_green.value(0)
sleep(0.2)
led_green.value(1)
sleep(0.2)
led_green.value(0)
msg = b'Alarm uit'
client.publish(topic_pub, msg)
oled.fill(0)
oled.show()
ingegeven_code = ""
else:
oled.text("incorrect", 29,0)
print("incorrect")
oled.text(ingegeven_code, 45, 30)
oled.show()
oled.show()
ingegeven_code = ""
sleep(0.3)
last_key_press = keys[row][col]
And here it doesn't.
(I know some of the code might be mesy but the stuf about the temp sensor is on line 20-24 and 165-175)
Traceback (most recent call last):
File "main.py", line 169, in <module>
File "ds18x20.py", line 40, in read_temp
File "ds18x20.py", line 30, in read_scratch
Exception: CRC error
and this is the error i get.
i have tried connecting it to a different ESP32 and it gives the same.
I'm mostly confused beacouse it does work apart but not toggeter with the rest of my code.

Is there any way to retrieve real time data from sql server on GUI interface with wxpython?

I have a simple application about GUI with wxpython , I'd like to display real time value from database. Currently what I can do is to display the value from database , but I can not figure out how to make it REAL TIME , I mean when the data changed in database then I hope the data on this interface will synchronize with database. Hope it's clear. Anyone who can help on this ? Any suggestion will be appreciated.
Here I attached my code: Python 3.5 , Win 10
# -*- coding: utf-8 -*-
import wx
import wx.adv
import wx.grid
import sys
import pyodbc
import time
bgcolor = (220,220,220)
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title, size = (600,320))
self.InitUI()
def InitUI(self):
nb = wx.Notebook(self)
nb.AddPage(MyPanel3(nb), "Table")
self.Centre()
self.Show(True)
def retrieve_data_fromdb():
# SQL Server configuration
server = 'localhost'
db = '***'
user = 'sa'
pwd = '******'
src_db = pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=' + server + ';DATABASE=' + db + ';UID=' + user + ';PWD=' + pwd)
cur = src_db.cursor()
select = 'select * from real_time_test'
cur.execute(select)
rows = cur.fetchone()
wind_spd = rows[0]
site_pwr = rows[1]
acv_pr_setpnt = rows[2]
park_pbl_cap = rows[3]
tol_cur = rows[4]
tol_non_prod = rows[5]
data = []
data.append(wind_spd)
data.append(site_pwr)
data.append(acv_pr_setpnt)
data.append(park_pbl_cap)
data.append(tol_cur)
data.append(tol_non_prod)
return data
cur.commit()
cur.close()
src_db.close()
class MyPanel3(wx.Panel):
def __init__(self, parent):
super(MyPanel3, self).__init__(parent)
self.SetBackgroundColour(bgcolor)
self.Bind(wx.EVT_PAINT, self.OnPaint)
title_NDC = wx.StaticText(self, -1, " Real time signals ", (30, 22))
title_NDC.SetForegroundColour((0, 0, 255))
wx.StaticText(self, -1, "1. Wind Speed", (35, 75))
wx.StaticText(self, -1, "2. Site Power", (35, 95))
wx.StaticText(self, -1, "Instant", (300, 45))
wx.StaticText(self, -1, "m/s", (340, 75))
wx.StaticText(self, -1, "kW", (340, 95))
a = retrieve_data_fromdb()
wind_spd_val = wx.StaticText(self, -1, a[0], (300, 75))
wind_spd_val.SetForegroundColour((0, 0, 255))
def OnPaint(self, event):
pdc = wx.PaintDC(self)
gc = wx.GCDC(pdc)
gc.Clear()
brush_rec = wx.Brush(bgcolor)
gc.SetBrush(brush_rec)
gc.SetPen(wx.Pen("black", 2))
x1 = 20
y1 = 30
w1 = 500
h1 = 180
radius = 3
gc.DrawRoundedRectangle(x1, y1, w1, h1, radius)
ex = wx.App()
Mywin(None,'My example')
ex.MainLoop()
An easy, if inefficient, way to achieve this is using a simple Timer.
Simply read the database once every x amount of time and update the screen.
Forgive the messy code but you'll get the idea.
Use the input box to update the value.
You'll have to fiddle with the database code, as I've used sqlite3, which is already on my box.
import wx
import sqlite3
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
#Dummy database
self.data = [['1111','Lots'],['2222','Fast'],['3333','Low']]
self.db = sqlite3.connect("test1.db")
self.cursor = self.db.cursor()
self.cursor.execute('CREATE TABLE IF NOT EXISTS TEST(Id Text, Value Text)')
self.cursor.execute("select * from TEST");
test = self.cursor.fetchone()
if not test:
for i in self.data:
result = self.db.execute("insert into Test (Id, Value) values (?,?)",(i[0],i[1]))
self.db.commit()
wx.StaticText(self, -1, "1. Wind Speed", (35, 75))
wx.StaticText(self, -1, "2. Site Power", (35, 95))
wx.StaticText(self, -1, "Instant", (300, 45))
wx.StaticText(self, -1, "m/s", (340, 75))
wx.StaticText(self, -1, "kW", (340, 95))
self.wind = wx.TextCtrl(self, -1, pos=(35,200),style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER)
a = self.retrieve_data_fromdb()
self.wind_spd_val = wx.StaticText(self, -1, a[1], (300, 75))
#Bind the callbacks for the timer and the update function
self.wind.Bind(wx.EVT_TEXT_ENTER, self.OnUpdate)
self.dbtimer = wx.Timer(self)
self.Bind(wx.EVT_TIMER,self.OnTimer, self.dbtimer)
self.dbtimer.Start(1000)
def retrieve_data_fromdb(self):
self.cursor.execute("SELECT * FROM Test where Id = ?",['2222'])
a = self.cursor.fetchone()
return a
def OnUpdate(self,event):
self.cursor.execute("update Test set Value=? where Id=?" , (self.wind.GetValue(),'2222'))
self.db.commit()
def OnTimer(self,event):
a = self.retrieve_data_fromdb()
self.wind_spd_val.SetLabel(a[1])
print("Updated with "+str(a[1]))
if __name__ == '__main__':
app = wx.App()
frame = Frame()
frame.Show()
app.MainLoop()

wxPython: onPaint event not called on panel update

The following code is supposed to create a window consisting of a "calibrate" button and a canvas. When the "calibrate" button is clicked, the red dot is supposed to be re-drawn on a random location on the canvas.
Instead, I see the OnPaint event is called once, in the beginning, and not afterwards. Any idea what's going on?
import wx
import datetime
import threading
import random
class frmMain ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 839,553 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.pos = (300,100)
self.initGUI()
def initGUI(self):
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
topSizer = wx.BoxSizer( wx.HORIZONTAL )
buttonsSizer = wx.BoxSizer( wx.VERTICAL )
self.btnCalibrate = wx.Button( self, wx.ID_ANY, u"Calibrate", wx.DefaultPosition, wx.DefaultSize, 0 )
buttonsSizer.Add( self.btnCalibrate, 0, wx.ALL, 5 )
topSizer.Add( buttonsSizer, 0, wx.LEFT, 5 )
sizeCanvas = wx.BoxSizer( wx.VERTICAL )
sizeCanvas.SetMinSize( wx.Size( 600,600 ) )
self.panel=wx.Panel(self, size=(600,600))
self.panel.SetBackgroundColour('white')
self.firstpoint=wx.Point(300,300)
self.secondpoint=wx.Point(400,400)
self.panel.Bind(wx.EVT_PAINT, self.onPaint)
sizeCanvas.Add(self.panel, 0, wx.ALIGN_LEFT, 5)
topSizer.Add( sizeCanvas, 1, wx.ALIGN_RIGHT, 5 )
self.SetSizer( topSizer )
self.Layout()
self.Centre( wx.BOTH )
# Connect Events
self.btnCalibrate.Bind( wx.EVT_BUTTON, self.StartCalibrate )
self.Show(True)
def onPaint(self,event):
print "lalal"
dc = wx.WindowDC(self.panel)
color = wx.Colour(255,0,0)
b = wx.Brush(color)
dc.SetBrush(b)
dc.DrawCircle(self.pos[0], self.pos[1], 10)
def __del__( self ):
pass
def StartCalibrate( self, event ):
size = self.GetSize()
self.pos = (random.randrange(0, size[0] - 1, 1), random.randrange(0, size[1] - 1, 1))
print "fixation at %d, %d" % (self.pos[0], self.pos[1])
self.panel.Update()
event.Skip()
if __name__ == "__main__":
app = wx.App()
frmMain(None)
app.MainLoop()
Use Refresh instead of Update. Update causes any pending paint events to be processed immediately, but if there are no pending paint events then nothing will be done. On the other hand, Refresh causes a paint event to be sent to the widget.

MT4 - PERIOD 's

I use below code for #1 screenshot.
int _objfnd = ObjectFind( name );
if ( _objfnd == -1 )
{
ObjectCreate ( _vlineName, OBJ_VLINE, 0, Time[i], 0 );
...
}
and I use below code for #2 screenshot.
int _objfnd = ObjectFind( name );
if ( _objfnd == -1 )
{
datetime _dayTime = Time[i] ;
int _dayNext = PeriodSeconds( _Session_Breaks_Day_Prd ) ;
_dayTime = _dayTime - ( _dayTime % _dayNext ) + _dayNext ;
ObjectCreate ( _vlineName, OBJ_VLINE, 0, _dayTime, 0 ) ;
}
If you figure out my concern,please give me good advice, much appreciate.
A: the code has not handled Daylight Saving Time Shift 2016, Nov-06

Python compiled code crashes

I made this game in python 2.7 and it worked in .py format but when I compiled it with py2exe it suddenly broke. It gave me this error:
"Microsoft Visuak C++ Runtime Library
Runtime Error!
Program C:\Python27\Helmetdodger\Stuffz\main.exe
This application has requested the Runtime to terminate it in an unusual way.
Please contact the program's support team."
The code:
import pygame
import random, sys, os
from pygame.locals import *
WINDOWWIDTH = 1200
WINDOWHEIGHT = 900
TEXTCOLOR = (255, 255, 255)
BACKGROUNDCOLOR = (0, 0, 0)
FPS = 40
BADDIEMINSIZE = 10
BADDIEMAXSIZE = 40
BADDIEMINSPEED = 1
BADDIEMAXSPEED = 8
ADDNEWBADDIERATE = 6
PLAYERMOVERATE = 5
def terminate():
pygame.quit()
os.exit(1)
def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # pressing escape quits
terminate()
return
def playerHasHitBaddie(playerRect, baddies):
for b in baddies:
if playerRect.colliderect(b['rect']):
return True
return False
def drawText(text, font, surface, x, y):
textobj = font.render(text, 1, TEXTCOLOR)
textrect = textobj.get_rect()
textrect.topleft = (x, y)
surface.blit(textobj, textrect)
# set up pygame, the window, and the mouse cursor
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Helmetdodger')
pygame.mouse.set_visible(False)
# set up fonts
font = pygame.font.SysFont(None, 48)
# set up sounds
gameOverSound = pygame.mixer.Sound('gameover.wav')
pygame.mixer.music.load('background.mid')
# set up images
playerImage1 = pygame.image.load('player1.png')
powerImage = pygame.image.load('power.png')
playerRect = playerImage1.get_rect()
baddieImage1 = pygame.image.load('baddie.png')
baddieImage2 = pygame.image.load('baddie1.png')
baddieImage3 = pygame.image.load('baddie2.png')
baddieImage4 = pygame.image.load('baddie3.png')
baddieImage5 = pygame.image.load('baddie4.png')
baddieImage6 = pygame.image.load('baddie5.png')
baddieImage7 = pygame.image.load('baddie6.png')
baddieImage8 = pygame.image.load('baddie7.png')
baddieImage9 = pygame.image.load('baddie8.png')
baddieImage10 = pygame.image.load('baddie9.png')
baddieImage11 = pygame.image.load('baddie10.png')
baddieImage12 = pygame.image.load('baddie11.png')
baddieImage13 = pygame.image.load('baddie12.png')
baddieImage14 = pygame.image.load('baddie13.png')
baddieImage15 = pygame.image.load('baddie14.png')
baddieImage16 = pygame.image.load('baddie15.png')
baddieImage17 = pygame.image.load('baddie16.png')
baddieImage18 = pygame.image.load('baddie17.png')
baddieImage19 = pygame.image.load('baddie18.png')
baddieImage20 = pygame.image.load('baddie19.png')
baddieImage21 = pygame.image.load('baddie20.png')
baddieImage22 = pygame.image.load('baddie21.png')
baddieImage23 = pygame.image.load('baddie22.png')
baddieImage24 = pygame.image.load('baddie23.png')
baddieImage25 = pygame.image.load('baddie24.png')
baddieImage26 = pygame.image.load('baddie25.png')
baddieImage27 = pygame.image.load('baddie26.png')
baddieImage28 = pygame.image.load('baddie27.png')
baddieImage29 = pygame.image.load('baddie28.png')
baddieImage30 = pygame.image.load('baddie29.png')
baddieImages = [baddieImage1, baddieImage2, baddieImage3, baddieImage4, baddieImage5, baddieImage6, baddieImage7, baddieImage8, baddieImage9, baddieImage10, baddieImage11, baddieImage12, baddieImage13, baddieImage14, baddieImage15, baddieImage16, baddieImage17, baddieImage18, baddieImage19, baddieImage20, baddieImage21, baddieImage22, baddieImage23, baddieImage24, baddieImage25, baddieImage26, baddieImage27, baddieImage28, baddieImage29, baddieImage20]
# show the "Start" screen
drawText('Helmetdodger', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to start.', font, windowSurface, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
#Get highscore
topScore = 0
try:
file = open('hs.txt', "r")
topScore = file.read()
topScore = int(topScore)
file.close()
except:
topScore = 0
while True:
# set up the start of the game
baddies = []
score = 0
playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50)
moveLeft = moveRight = moveUp = moveDown = False
reverseCheat = slowCheat = False
baddieAddCounter = 0
pygame.mixer.music.play(-1, 0.0)
powerCount = 0
while True: # the game loop runs while the game part is playing
score += 1 # increase score
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == ord('z'):
reverseCheat = True
if event.key == ord('x'):
slowCheat = True
if event.key == K_LEFT or event.key == ord('a'):
moveRight = False
moveLeft = True
if event.key == K_RIGHT or event.key == ord('d'):
moveLeft = False
moveRight = True
if event.key == K_UP or event.key == ord('w'):
moveDown = False
moveUp = True
if event.key == K_DOWN or event.key == ord('s'):
moveUp = False
moveDown = True
if event.type == KEYUP:
if event.key == ord('z'):
reverseCheat = False
score = 0
if event.key == ord('x'):
slowCheat = False
score = 0
if event.key == K_ESCAPE:
terminate()
if event.key == K_LEFT or event.key == ord('a'):
moveLeft = False
if event.key == K_RIGHT or event.key == ord('d'):
moveRight = False
if event.key == K_UP or event.key == ord('w'):
moveUp = False
if event.key == K_DOWN or event.key == ord('s'):
moveDown = False
if event.type == MOUSEMOTION:
# If the mouse moves, move the player where the cursor is.
playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery)
# Add new baddies at the top of the screen, if needed.
if not reverseCheat and not slowCheat:
baddieAddCounter += 1
if baddieAddCounter == ADDNEWBADDIERATE:
baddieCount = random.randrange(len(baddieImages))
baddieAddCounter = 0
baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE)
newBaddie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-baddieSize), 0 - baddieSize, baddieSize, baddieSize),
'speed': random.randint(BADDIEMINSPEED, BADDIEMAXSPEED),
'surface':pygame.transform.scale(baddieImages[baddieCount], (baddieSize, baddieSize)),
}
baddies.append(newBaddie)
# Move the player around.
if moveLeft and playerRect.left > 0:
playerRect.move_ip(-1 * PLAYERMOVERATE, 0)
if moveRight and playerRect.right < WINDOWWIDTH:
playerRect.move_ip(PLAYERMOVERATE, 0)
if moveUp and playerRect.top > 0:
playerRect.move_ip(0, -1 * PLAYERMOVERATE)
if moveDown and playerRect.bottom < WINDOWHEIGHT:
playerRect.move_ip(0, PLAYERMOVERATE)
# Move the mouse cursor to match the player.
pygame.mouse.set_pos(playerRect.centerx, playerRect.centery)
# Move the baddies down.
for b in baddies:
if not reverseCheat and not slowCheat:
b['rect'].move_ip(0, b['speed'])
elif reverseCheat:
b['rect'].move_ip(0, -5)
elif slowCheat:
b['rect'].move_ip(0, 1)
# Delete baddies that have fallen past the bottom.
for b in baddies[:]:
if b['rect'].top > WINDOWHEIGHT:
baddies.remove(b)
# Draw the game world on the window.
windowSurface.fill(BACKGROUNDCOLOR)
# Draw the score and top score.
drawText('Score: %s' % (score), font, windowSurface, 10, 0)
drawText('Top Score: %s' % (topScore), font, windowSurface, 10, 40)
# Draw the player's rectangle
windowSurface.blit(playerImage1, playerRect)
# Draw each baddie
for b in baddies:
windowSurface.blit(b['surface'], b['rect'])
pygame.display.update()
# Check if any of the baddies have hit the player.
if playerHasHitBaddie(playerRect, baddies):
if score > topScore:
topScore = score # set new top score
file = open("hs.txt", "w")
score = str(score)
file.write(score)
file.close()
break
mainClock.tick(FPS)
# Stop the game and show the "Game Over" screen.
pygame.mixer.music.stop()
gameOverSound.play()
drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to play again.', font, windowSurface, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()
gameOverSound.stop()
My buildscript was incorrect, I found a better buildscript online to use instead
try:
from distutils.core import setup
import py2exe, pygame
from modulefinder import Module
import glob, fnmatch
import sys, os, shutil
import operator
except ImportError, message:
raise SystemExit, "Unable to load module. %s" % message
#hack which fixes the pygame mixer and pygame font
origIsSystemDLL = py2exe.build_exe.isSystemDLL # save the orginal before we edit it
def isSystemDLL(pathname):
# checks if the freetype and ogg dll files are being included
if os.path.basename(pathname).lower() in ("libfreetype-6.dll", "libogg-0.dll","sdl_ttf.dll"): # "sdl_ttf.dll" added by arit.
return 0
return origIsSystemDLL(pathname) # return the orginal function
py2exe.build_exe.isSystemDLL = isSystemDLL # override the default function with this one
class pygame2exe(py2exe.build_exe.py2exe): #This hack make sure that pygame default font is copied: no need to modify code for specifying default font
def copy_extensions(self, extensions):
#Get pygame default font
pygamedir = os.path.split(pygame.base.__file__)[0]
pygame_default_font = os.path.join(pygamedir, pygame.font.get_default_font())
#Add font to list of extension to be copied
extensions.append(Module("pygame.font", pygame_default_font))
py2exe.build_exe.py2exe.copy_extensions(self, extensions)
class BuildExe:
def __init__(self):
#Name of starting + .py
self.script = "raw.py"
#Name of program
self.project_name = "main"
#Project url
self.project_url = "about:none"
#Version of program
self.project_version = "0.0"
#License of the program
self.license = "MyApps License"
#Auhor of program
self.author_name = "Me"
self.author_email = "example#example.com"
self.copyright = "Copyright (c) 2009 Me."
#Description
self.project_description = "MyApps Description"
#Icon file (None will use pygame default icon)
self.icon_file = None
#Extra files/dirs copied to game
self.extra_datas = []
#Extra/excludes python modules
self.extra_modules = []
self.exclude_modules = []
#DLL Excludes
self.exclude_dll = ['']
#python scripts (strings) to be included, seperated by a comma
self.extra_scripts = []
#Zip file name (None will bundle files in exe instead of zip file)
self.zipfile_name = None
#Dist directory
self.dist_dir ='C:\Python27\dist'
## Code from DistUtils tutorial at http://wiki.python.org/moin/Distutils/Tutorial
## Originally borrowed from wxPython's setup and config files
def opj(self, *args):
path = os.path.join(*args)
return os.path.normpath(path)
def find_data_files(self, srcdir, *wildcards, **kw):
# get a list of all files under the srcdir matching wildcards,
# returned in a format to be used for install_data
def walk_helper(arg, dirname, files):
if '.svn' in dirname:
return
names = []
lst, wildcards = arg
for wc in wildcards:
wc_name = self.opj(dirname, wc)
for f in files:
filename = self.opj(dirname, f)
if fnmatch.fnmatch(filename, wc_name) and not os.path.isdir(filename):
names.append(filename)
if names:
lst.append( (dirname, names ) )
file_list = []
recursive = kw.get('recursive', True)
if recursive:
os.path.walk(srcdir, walk_helper, (file_list, wildcards))
else:
walk_helper((file_list, wildcards),
srcdir,
[os.path.basename(f) for f in glob.glob(self.opj(srcdir, '*'))])
return file_list
def run(self):
if os.path.isdir(self.dist_dir): #Erase previous destination dir
shutil.rmtree(self.dist_dir)
#Use the default pygame icon, if none given
if self.icon_file == None:
path = os.path.split(pygame.__file__)[0]
self.icon_file = os.path.join(path, 'pygame.ico')
#List all data files to add
extra_datas = []
for data in self.extra_datas:
if os.path.isdir(data):
extra_datas.extend(self.find_data_files(data, '*'))
else:
extra_datas.append(('.', [data]))
setup(
cmdclass = {'py2exe': pygame2exe},
version = self.project_version,
description = self.project_description,
name = self.project_name,
url = self.project_url,
author = self.author_name,
author_email = self.author_email,
license = self.license,
# targets to build
windows = [{
'script': self.script,
'icon_resources': [(0, self.icon_file)],
'copyright': self.copyright
}],
options = {'py2exe': {'optimize': 2, 'bundle_files': 2, 'compressed': True, \
'excludes': self.exclude_modules, 'packages': self.extra_modules, \
'dll_excludes': self.exclude_dll,
'includes': self.extra_scripts} },
zipfile = self.zipfile_name,
data_files = extra_datas,
dist_dir = self.dist_dir
)
if os.path.isdir('build'): #Clean up build dir
shutil.rmtree('build')
if __name__ == '__main__':
if operator.lt(len(sys.argv), 2):
sys.argv.append('py2exe')
BuildExe().run() #Run generation
raw_input("Press any key to continue") #Pause to let user see that things ends

Resources