前一篇
在C,C++代码重复工作用宏表示。举例。我用Msp430编程写的宏。
宏可以理解为文本替换。它的好处在于可以灵活地替换变量,举个例子。
#define SETOUT(IONAME,IONUMBER) \
P##IONAME##DIR|=BIT##IONUMBER;
这个解释##,##之间就是变量文本链接 具体SETOUT(1,3) 展开宏就是IONAME=1,
IONUMBER=3
P##IONAME##DIR|=BIT##IONUMBER;
相当于 “P”+IONAME+“DIR|=BIT”+IONUMBER+";"
结果是P1DIR|=BIT3
这样写的好处可以自己体会,至少每次置位不用费脑计算,也不用特意写一个函数,几个Msp430系列底层很实用的宏,其它单片机可以依据这个思路修改。
#define DIM(a,b) \
int a,b;
#define SETOUT(IONAME,IONUMBER) \
P##IONAME##DIR|=BIT##IONUMBER;
#define SETB(IONAME,IONUMBER) \
P##IONAME##OUT|=BIT##IONUMBER;
#define SETIN(IONAME,IONUMBER) \
P##IONAME##DIR&=~BIT##IONUMBER;
#define CLRB(IONAME,IONUMBER) \
P##IONAME##OUT&=~BIT##IONUMBER;
#define SET_XOR(IONAME,IONUMBER) \
P##IONAME##OUT ^= (1<<IONUMBER);
#define SETONEBITH(NAME,NUMER)\
NAME|=(128>>NUMER)
#define SETONEBITL(NAME,NUMER)\
NAME &=~(128>>NUMER)
#define CHECK_IO(IONAME,IONUMBER) \
(P##IONAME##IN & (1<<IONUMBER))
#define CHECK_IOOUT(IONAME,IONUMBER) \
(P##IONAME##OUT & (1<<IONUMBER))
在python里使用exec可以达到宏的效果,上一个例子。设想一下,我们放置两个按钮可以butto1.SetPo(); butto2.SetPo()。如果多个,多个实例化,就会显得很臃肿。所以这里我们需要编辑一个添加,简化程序。这里希望吧所有的按钮作为Dict保存起来。这样设置:
ButtonDict["butto1"] = [(12, 13), 'feid1.png'] #全局变量,判定
ButtonDict["butto2"] = [(52, 73), 'feid1.png']
ButtonDict["butto3"] = [(102, 203), 'feid1.png']
在这里为了让自己省心,第一段需要优化。可以编写一个添加函数(这是因为我精力不行,容易出错。不过程序员应该根据自己的习惯调整代码)很简单,自己按照自己的习惯编写吧。
butto1 = Jbutton((12, 13), 'feid1.png')
butto2 = Jbutton((52, 73), 'feid1.png')
butto3 = Jbutton((102, 203), 'feid1.png')
#这里的意思是初始化完成根据字典判断按钮的位置,实际上可以用按钮的属性高判断
ButtonDict["butto1"] = [ButtonDict["butto1"][0], (butto1.BoPo[0], butto1.BoPo[1])]
ButtonDict["butto2"] = [ButtonDict["butto2"][0], (butto2.BoPo[0], butto2.BoPo[1])]
ButtonDict["butto3"] = [ButtonDict["butto3"][0], (butto3.BoPo[0], butto3.BoPo[1])]
注意到共性,除了文本有变化,其它变化不大,正是使用exec的时机
这段代码也是一样
butto1.SetPo()
butto2.SetPo()
butto3.SetPo()
思路就是把这些变成有规律的指令用exec循环执行,如果你添加或删除一个按钮就不需要改动太多了。修改这两个函数,就是把 ButtonDict所有与按钮有关的代码抽象出来自动处理(format一下)
def CreateButton():
# global ButtonDict
mylist=[]
for exi in ButtonDict.keys():
mylist.append("{}=Jbutton({},'{}')".format(exi,ButtonDict[exi][0],ButtonDict[exi][1]))
for exi in ButtonDict.keys():
mylist.append('ButtonDict["{0}"] = [ButtonDict["{0}"][0],({0}.BoPo[0],{0}.BoPo[1])]'.format(exi))
return mylist
def showButton():
mylist = [] #butto1.SetPo()
for exi in ButtonDict.keys():
mylist.append ("{}.SetPo()".format(exi))
return mylist
修正后的代码,下一节准备添加鼠标移动事件
# coding: utf8
import pygame
#导入pygame库
from pygame.locals import *
#导入一些常用的函数和常量
from sys import exit
import pickle
from PIL import Image
import DVerctor
# coding: utf8
import pygame
#导入pygame库
from pygame.locals import *
#导入一些常用的函数和常量
from sys import exit
import pickle
import DVerctor
ButtonDict={}
class JCon():
def __init__(self,vertex,mouse_image_filename):
self.vertex=vertex #设置按钮顶点 set button vertex (left,top)格式
self.mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
self.count=0 #用于计数
self.BoPo =DVerctor.Vec2d(vertex)+DVerctor.Vec2d(self.mouse_cursor.get_width(),self.mouse_cursor.get_height())
#获得范围left+width,top+height (x,y)+(x1,y1)
def SetPo(self): #设置位置 set position #
screen.blit(self.mouse_cursor,self.vertex)
def Mouse_Click(self):
pass
class Jbutton(JCon):
pass
def TextPygame(): #测试模块是否存在和版本号
print(pygame.ver)
pgname = ['pygame.cdrom', 'pygame.cursors', 'pygame.display', 'pygame.draw',
'pygame.event', 'pygame.font', 'pygame.image', 'pygame.joystick',
'pygame.key', 'pygame.mixer', 'pygame.mouse', 'pygame.movie', 'pygame.music',
'pygame.overlay', 'pygame', 'pygame.rect', 'pygame.sndarray', 'pygame.sprite',
'pygame.surface', 'pygame.surfarray', 'pygame.time']
for i in pgname:
if i is None:
print(i+" is None")
else:
print(i + " at this computer")
def storeTree(filename,*args):
with open(filename,'wb') as fw: #打开需要用'wb'
for i in args:
pickle.dump(i, fw,-1) #为了保护数据protocol=-1,设为0可以看到数据
def grabTree(filename):
Mylist=[] #返回变量的列表
with open(filename,'rb') as fr:
while True: #这里用try最简单,不用定义循环次数
try:
Mylist.append(pickle.load(fr))
except:
break
return Mylist
def CreateButton():
# global ButtonDict
mylist=[]
for exi in ButtonDict.keys():
mylist.append("{}=Jbutton({},'{}')".format(exi,ButtonDict[exi][0],ButtonDict[exi][1]))
for exi in ButtonDict.keys():
mylist.append('ButtonDict["{0}"] = [ButtonDict["{0}"][0],({0}.BoPo[0],{0}.BoPo[1])]'.format(exi))
return mylist
def showButton():
mylist = [] #butto1.SetPo()
for exi in ButtonDict.keys():
mylist.append ("{}.SetPo()".format(exi))
return mylist
if __name__ == "__main__":
background_image_filename = 'sushiplate.jpg'
# 指定图像文件名称
pygame.init()
# 初始化pygame,为使用硬件做准备
screen = pygame.display.set_mode((640, 480), 0, 32)
# 创建了一个窗口
pygame.display.set_caption("Hello, World!") # 设置窗口标题
background = pygame.image.load(background_image_filename).convert()
#在这里添加按钮
ButtonDict["butto1"] = [(12, 13), 'feid1.png'] #全局变量,判定
ButtonDict["butto2"] = [(52, 73), 'feid1.png']
ButtonDict["butto3"] = [(102, 203), 'feid1.png']
# ButtonDict = {"butto1": [(12, 13), 'feid1.png'], "butto2": [(52, 73), 'feid1.png'], "butto3": [(102, 203), 'feid1.png']}
s=CreateButton()
# RunStr(s) 这里不能调用函数
for i in s:
exec(i)
print("ButtonDict=",ButtonDict)
#修改ButtonDict
while True:
# 游戏主循环
for event in pygame.event.get():
if event.type == QUIT:
# 接收到退出事件后退出程序
exit()
screen.blit(background, (0, 0))
# 将背景图画上去
x, y = pygame.mouse.get_pos()
# 获得鼠标位置
# 计算光标的左上角位置
#screen.blit(mouse_cursor, (x, y))
# 把光标画上去
# butto1.SetPo()
# butto2.SetPo()
# butto3.SetPo()
for i in showButton():
exec(i)
#screen.blit(mouse_cursor, butto1.vertex)
pygame.display.update()
# 刷新一下画面