在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()
# 刷新一下画面
继续阅读与本文标签相同的文章
-
开一家线上外卖门店选址要注意哪些因素?
2026-05-19栏目: 教程
-
信院人的APP,你get到了吗?
2026-05-19栏目: 教程
-
对话FILA姚伟雄:安踏赋予独立性,未来坚持做直营
2026-05-19栏目: 教程
-
小程序如何引流?企业推广其实很简单
2026-05-19栏目: 教程
-
2019云栖大会 | 云原生时代 带你聚焦新数据库的硬核科技
2026-05-19栏目: 教程
