在RaspberryPi中用Pygame做信息显示屏

来源:互联网 发布:jquery.easing.min.js 编辑:程序博客网 时间:2024/05/16 19:13
家母患眼疾已久,艰于视物,看电视时头都快钻进机子里了。
为了弘扬物尽其用精神,改善生活质量,本着家人为我我为家人的宗旨,我用树莓派对某些图像信息的尺寸尽量放大,并连接到电视上显示,比如天气预报类信息,以便她一目了然成竹在胸,收吾之晾衣而无受浸雨侵袭。

关注的信息数据可以用相应API获取,或者去页面抓,但界面还是要自己组织,对我来说要花些成本。
所以我直接用CasperJS(基于PhantomJS(一个无界面的Webkit浏览器))对页面需要的部分截图,然后用Pygame直接显示图片便完事儿。

Raspbian已自带Python和Pygame,如果之前做过2D贴图,Pygame是很易用的。一步一步来:


1.Hello World

import time,pygame,sysfrom pygame.locals import *def init():#初始化    pygame.init()    screen_size = (1280,720)    screen = pygame.display.set_mode(screen_size,0,32) #设置窗口    return screen    def update(screen):#显示    p = pygame.image.load(sys.path[0]+"/img/p1.png").convert()#加载图片    screen.blit(p,(0,0))#贴到显示屏(从左上角开始)    pygame.display.update()#这时才更新到窗口def eventCheck():#非必要    for event in pygame.event.get():            if event.type in [QUIT ,KEYDOWN]:#退出及键按下事件时                pygame.quit()#退出                sys.exit()        screen=init()update(screen)#以下非必要,加上是为了方便退出while True:    eventCheck()      time.sleep(1)

2.获取信息后再显示

与上一版相比有修改的地方用 '##' 表示,删除的忽略。下同。
本例增加一个信息类,新开子进程用CasperJS截图。
开头import的subprocess32来自python3下的subprocess,可以限制进程的timeout,不然可能会等到世界末日。
在python2中需安装,只用内建的subprocess也可以,自己写定时检查的代码。

import time,pygame,sysfrom pygame.locals import *import subprocess32 as subprocess ## class Info():##获取信息类    def get(self):        try:            subprocess.check_output(["casperjs",sys.path[0]+"/weather.js"],timeout=60)        except Exception,e:            return False#timeout的话可能要把子进程杀掉        return True                  def init():    pygame.init()    screen_size = (1280,720)    screen = pygame.display.set_mode(screen_size,0,32)    return screendef update(screen):    p = pygame.image.load(sys.path[0]+"/img/p3.png").convert()    screen.blit(p,(0,0))    pygame.display.update()def eventCheck():    for event in pygame.event.get():        if event.type in [QUIT ,KEYDOWN]:            pygame.quit()            sys.exit()screen=init()if Info().get():##获取信息    update(screen)while True:    eventCheck()    time.sleep(1)

3.定时获取信息
用循环的话程序不能往下走,不能响应。改为用新线程运行。

import time,pygame,sys,threading##from pygame.locals import *import subprocess32 as subprocessclass Info():    def __init__(self): ##        self.nextTime=0        def get(self):        try:    #以子进程方式运行命令,返回代码不为0或超时都视为失败            subprocess.check_output(["casperjs",sys.path[0]+"/weather.js"],timeout=60)        except Exception,e:            return False        return True        def runPlan(self,update,screen): ##        while True:            if self.nextTime<time.time():                isOK=self.get()                 if isOK:                    update(screen)                    self.nextTime=time.time()+3*60*60# 成功后下次运行时间设在3小时后                else:                    self.nextTime=time.time()+180# 失败则3分钟后重试            time.sleep(60)        def init():    pygame.init()    screen_size = (1280,720)    screen = pygame.display.set_mode(screen_size,0,32)    return screendef update(screen):    p = pygame.image.load(sys.path[0]+"/img/p1.png").convert()    screen.blit(p,(0,0))    pygame.display.update()def eventCheck():    for event in pygame.event.get():        if event.type in [QUIT ,KEYDOWN]:            pygame.quit()            sys.exit()    time.sleep(1)screen=init()th=threading.Thread(target=Info().runPlan,args=(update,screen))##把获取信息后的更新图片的回调方法和参数传给定时获取方法th.setDaemon(True)th.start()while True:    eventCheck()

 4.轮流显示多张图片
加个图片类来管理,显示部分也单独分出来,加个计数器类用于触发图片切换。

import time,pygame,sys,threadingfrom pygame.locals import *import subprocess32 as subprocessclass Info():    def __init__(self):        self.nextTime=0        def get(self):        try:<span style="white-space:pre"></span>    subprocess.check_output(["casperjs",sys.path[0]+"/weather.js"],timeout=60)        except Exception,e:            return False#need manual stop        return True        def runPlan(self,updateImg):        while True:            if self.nextTime<time.time():                isOK=self.get()                if isOK:                    updateImg()                    self.nextTime=time.time()+3*60*60                else:                    self.nextTime=time.time()+180#retry            time.sleep(60)######################################################################class Imgs(): ##图片类    def __init__(self):        self.curPos=-1 #当前位置,即哪张图片        self.list=[] #图片列表        self.isGetImg=False #是否已获取图片    def getCur(self):#得到这次要显示的图片        self.curPos+=1        if self.curPos>=len(self.list):            self.curPos=0        return self.list[self.curPos]      def update(self):#图片更新到列表        list=[]        p = pygame.image.load(sys.path[0]+"/img/p1.png").convert()        list.append(p)        p = pygame.image.load(sys.path[0]+"/img/p2.png").convert()        list.append(p)        #......        self.list=list        self.isGetImg=True#####################################################################class Counter(): ## 计数器,设定计数到多少时触发,以返回True为标志    def __init__(self,trigCount):        self.count=0        self.trigCount=trigCount            def reachTrig(self):        self.count+=1        if self.count>=self.trigCount:            self.count=0            return True        return False####################################################################        def init():    pygame.init()    screenSize = (1280,720)    screen = pygame.display.set_mode(screenSize,0,32)    return screendef eventCheck():    for event in pygame.event.get():        if event.type in [QUIT ,KEYDOWN]:            pygame.quit()            sys.exit()            def playboard(screen,imgs):##显示部分放这里    cnt=Counter(10)#计数到10时    while True:           if cnt.reachTrig():#达到触发条件            p=imgs.getCur()            screen.fill((0,0,0))            screen.blit(p,(0,0))            pygame.display.update()        eventCheck()        time.sleep(1)    ###################main##########################screen=init()imgs=Imgs()th=threading.Thread(target=Info().runPlan,args=(imgs.update,))##th.setDaemon(True)th.start()while True:    if imgs.isGetImg:        playboard(screen,imgs)    time.sleep(1)

5.加上效果类 实现淡入淡出等各种效果。

import time,pygame,sys,threadingfrom pygame.locals import *import subprocess32 as subprocessclass Info():    def __init__(self):        self.nextTime=0        def get(self):        try:            subprocess.check_output(["casperjs",sys.path[0]+"/weather.js"],timeout=60)        except Exception,e:            return False#need manual stop        return True        def runPlan(self,updateImg):        while True:            if self.nextTime<time.time():                isOK=self.get()                if isOK:                    updateImg()                    self.nextTime=time.time()+3*60*60                else:                    self.nextTime=time.time()+180#retry            time.sleep(60)######################################################################class Imgs():    def __init__(self):        self.curPos=-1        self.list=[]        self.isGetImg=False    def getLastCur(self):        lastImg=self.list[self.curPos]        self.curPos+=1        if self.curPos>=len(self.list):            self.curPos=0        curImg=self.list[self.curPos]          return  lastImg,curImg    def update(self):        list=[]        p = pygame.image.load(sys.path[0]+"/img/p1.png").convert()        list.append(p)        p = pygame.image.load(sys.path[0]+"/img/p2.png").convert()        list.append(p)        #......        self.list=list        self.isGetImg=True#####################################################################class Counter():    def __init__(self,trigCount):        self.count=0        self.trigCount=trigCount            def reachTrig(self):        self.count+=1        if self.count>=self.trigCount:            self.count=0            return True        return False####################################################################class Effect():##效果类    def fade(self,screen,p,rg):        for alpha in rg:            p.set_alpha(alpha) #改变透明度                    screen.fill((0,0,0))            screen.blit(p,(0,0))            pygame.display.update()            time.sleep(0.01)                def fadeIn(self,screen,p):#淡入        rg=range(0,257,32) #透明度范围由0过渡到256,步长为32        self.fade(screen,p,rg)            def fadeOut(self,screen,p):#淡出        rg=range(255,0,-32)        self.fade(screen,p,rg)###################################################################        def init():    pygame.init()    screenSize = (1280,720)    screen = pygame.display.set_mode(screenSize,FULLSCREEN,32) ##FULLSCREEN全屏独霸    return screendef eventCheck():    for event in pygame.event.get():        if event.type in [QUIT ,KEYDOWN]:            pygame.quit()            sys.exit()            def playboard(screen,imgs):    cnt=Counter(4)    ef=Effect()    while True:           if cnt.reachTrig():            li,ci=imgs.getLastCur()            ef.fadeOut(screen,li)  ##上一张淡出            ef.fadeIn(screen,ci) ##这张淡入        eventCheck()        time.sleep(1)     ###################main##########################screen=init()imgs=Imgs()th=threading.Thread(target=Info().runPlan,args=(imgs.update,))th.setDaemon(True)th.start()while True:    if imgs.isGetImg:        playboard(screen,imgs)    time.sleep(1)


可以用这东西显示各种信息,如新闻、股市、物价、备忘或者作为电子相册。



0 0
原创粉丝点击