python中的Raspberry Pi帧缓冲区UI

python中的Raspberry Pi帧缓冲区UI,python,raspberry-pi,Python,Raspberry Pi,我似乎把自己绊倒了,要么不理解类,要么缺少一点关键代码 我正在尝试为Raspbian开发一个python应用程序,它将为我提供一个在帧缓冲区中运行的UI。它松散地基于为PiCam所做的工作,PiCam使用了一个类似的UI,我不得不重新构建这个UI,因为项目太不相似了。我挑选了需要工作的片段,并试图重写框架以满足我的需要。我一直在工作,直到我试图通过将我的一个def条目设置为类来清理东西。我不确定我在这里做错了什么,因为我大约在3天前开始这个项目时才开始编写python代码 此代码: ev =

我似乎把自己绊倒了,要么不理解类,要么缺少一点关键代码

我正在尝试为Raspbian开发一个python应用程序,它将为我提供一个在帧缓冲区中运行的UI。它松散地基于为PiCam所做的工作,PiCam使用了一个类似的UI,我不得不重新构建这个UI,因为项目太不相似了。我挑选了需要工作的片段,并试图重写框架以满足我的需要。我一直在工作,直到我试图通过将我的一个def条目设置为类来清理东西。我不确定我在这里做错了什么,因为我大约在3天前开始这个项目时才开始编写python代码

此代码:

  ev = pygame.event.get()
  screen.blit(ethdisp,(0,0))
  screen.blit(wldisp, (0,1*font.get_linesize()) )
此处生成的调用信息:

class IPdisplay:
    def get_ip_address(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
        )[20:24])
        font            = pygame.font.Font(None, 30)
        try:
            eth = get_ip_address('eth0')
        except IOError:
            eth = ('0.0.0.0')
        try:
            wl = get_ip_address('wlan0')
        except IOError: 
            wl = ("0.0.0.0")
        if eth == ("0.0.0.0"):
            ethdisp = font.render(ethip, 1, (255,0,0))
        else:
            ethdisp = font.render(ethip, 1, (0, 255, 0))
        screen.blit( ethdisp, (0,0) )
        ethrect = ethdisp.get_rect()
        if wl == ("0.0.0.0"):
            wldisp = font.render(wlip, 1, (255, 0, 0))
        else:
            wldisp = font.render(wlip, 1, (0, 255, 0))
        screen.blit(wldisp, (0,1*font.get_linesize()) )
        wlrect = wldisp.get_rect()
给我这个错误:

Traceback (most recent call Last):                                                 
  File "piface.py", line 188, in <module>                              
    screen.blit(ethdisp,(0,0))    
NameError: name 'ethdisp' is not defined
回溯(最近一次呼叫最后一次):
文件“piface.py”,第188行,在
屏幕blit(ethdisp,(0,0))
NameError:未定义名称“ethdisp”
我理解这个错误,但我不知道如何修复它。它调用一个定义在类中的变量,该类显然不是全局的,但我不知道如何使它全局化或正确调用它。我已经搜索了几个小时,我不知道为什么我找不到答案,或者我只是不知道要搜索什么。任何帮助都将不胜感激

如果有人感兴趣,下面是完整的代码,如果有人想贡献的话,我在bitbucket上

import os
import pygame
import time
import random
import socket
import fcntl
import struct
import fnmatch
from pygame.locals import *
os.environ["SDL_FBDEV"] = "/dev/fb1"
if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'



class Icon:

    def __init__(self, name):
      self.name = name
      try:
        self.bitmap = pygame.image.load(iconPath + '/' + name + '.png')
      except:
        pass

class Button:

    def __init__(self, rect, **kwargs):
        self.rect     = rect # Bounds
        self.color    = None # Background fill color, if any
        self.iconBg   = None # Background Icon (atop color fill)
        self.iconFg   = None # Foreground Icon (atop background)
        self.bg       = None # Background Icon name
        self.fg       = None # Foreground Icon name
        self.callback = None # Callback function
        self.value    = None # Value passed to callback
        for key, value in kwargs.iteritems():
            if   key == 'color': self.color    = value
            elif key == 'bg'   : self.bg       = value
            elif key == 'fg'   : self.fg       = value
            elif key == 'cb'   : self.callback = value
            elif key == 'value': self.value    = value

    def selected(self, pos):
        x1 = self.rect[0]
        y1 = self.rect[1]
        x2 = x1 + self.rect[2] - 1
        y2 = y1 + self.rect[3] - 1
        if ((pos[0] >= x1) and (pos[0] <= x2) and
            (pos[1] >= y1) and (pos[1] <= y2)):
            if self.callback:
                if self.value is None: self.callback()
                else:                  self.callback(self.value)
            return True
        return False

    def draw(self, screen):
        if self.color:
            screen.fill(self.color, self.rect)
        if self.iconBg:
            screen.blit(self.iconBg.bitmap,
              (self.rect[0]+(self.rect[2]-self.iconBg.bitmap.get_width())/2,
               self.rect[1]+(self.rect[3]-self.iconBg.bitmap.get_height())/2))
        if self.iconFg:
            screen.blit(self.iconFg.bitmap,
              (self.rect[0]+(self.rect[2]-self.iconFg.bitmap.get_width())/2,
               self.rect[1]+(self.rect[3]-self.iconFg.bitmap.get_height())/2))

    def setBg(self, name):
        if name is None:
            self.iconBg = None
        else:
            for i in icons:
                if name == i.name:
                    self.iconBg = i
                break

# Global stuff -------------------------------------------------------------

screenMode      =  3      # Current screen mode; default = viewfinder
iconPath        = 'icons' # Subdirectory containing UI bitmaps (PNG format)

icons = [] # This list gets populated at startup

buttons = [
    # Screen mode 0 is photo playback
  [Button((  0,188,320, 52), bg='done'),# , cb=doneCallback),
   Button((  0,  0, 80, 52), bg='prev'),# , cb=imageCallback, value=-1),
   Button((240,  0, 80, 52), bg='next'),# , cb=imageCallback, value= 1),
   Button(( 88, 70,157,102)), # 'Working' label (when enabled)
   Button((148,129, 22, 22)), # Spinner (when enabled)
   Button((121,  0, 78, 52), bg='trash',)],# cb=imageCallback, value= 0)],

  # Screen mode 1 is delete confirmation
  [Button((  0,35,320, 33), bg='delete'),
   Button(( 32,86,120,100), bg='yn', fg='yes'),
    #cb=deleteCallback, value=True),
   Button((168,86,120,100), bg='yn', fg='no')],
    #cb=deleteCallback, value=False)],

  # Screen mode 2 is 'No Images'
  [Button((0,  0,320,240)), #cb=doneCallback), # Full screen = button
   Button((0,188,320, 52), bg='done'),       # Fake 'Done' button
   Button((0, 53,320, 80), bg='empty')],     # 'Empty' message
# Screen mode 3 is viewfinder / snapshot
  [Button((  0,188,156, 52), bg='gear',),# cb=viewCallback, value=0),
   Button((164,188,156, 52), bg='play',),# cb=viewCallback, value=1),
   Button((  0,  0,320,240)           ,),# cb=viewCallback, value=2),
   Button(( 88, 51,157,102)),  # 'Working' label (when enabled)
   Button((148, 110,22, 22))], # Spinner (when enabled)
]
ifname=0

class IPdisplay:
    def get_ip_address(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
        )[20:24])
        font            = pygame.font.Font(None, 30)
        try:
            eth = get_ip_address('eth0')
        except IOError:
            eth = ('0.0.0.0')
        try:
            wl = get_ip_address('wlan0')
        except IOError: 
            wl = ("0.0.0.0")
        if eth == ("0.0.0.0"):
            ethdisp = font.render(ethip, 1, (255,0,0))
        else:
            ethdisp = font.render(ethip, 1, (0, 255, 0))
        screen.blit( ethdisp, (0,0) )
        ethrect = ethdisp.get_rect()
        if wl == ("0.0.0.0"):
            wldisp = font.render(wlip, 1, (255, 0, 0))
        else:
            wldisp = font.render(wlip, 1, (0, 255, 0))
        screen.blit(wldisp, (0,1*font.get_linesize()) )
        wlrect = wldisp.get_rect()

        #pygame.init()
        #size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
        #screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
        #pygame.mouse.set_visible(0)

        #black = (0, 0, 0)
        #screen.fill(black)
        #screen.blit(ethdisp,(0,0))
        #screen.blit(wldisp, (0,1*font.get_linesize()) )
        #pygame.display.flip()



os.putenv('SDL_VIDEODRIVER', 'fbcon')
os.putenv('SDL_FBDEV'      , '/dev/fb1')
os.putenv('SDL_MOUSEDRV'   , 'TSLIB')
os.putenv('SDL_MOUSEDEV'   , '/dev/input/touchscreen')

pygame.init()
#scope = IPdisplay()
#scope.getips()
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)

# Load all icons at startup.
for file in os.listdir(iconPath):
  if fnmatch.fnmatch(file, '*.png'):
    icons.append(Icon(file.split('.')[0]))

# Assign Icons to Buttons, now that they're loaded
for s in buttons:        # For each screenful of buttons...
  for b in s:            #  For each button on screen...
    for i in icons:      #   For each icon...
      if b.bg == i.name: #    Compare names; match?
        b.iconBg = i     #     Assign Icon to Button
        b.bg     = None  #     Name no longer used; allow garbage collection
      if b.fg == i.name:
        b.iconFg = i
        b.fg     = None





while (True): # your main loop
  # get all events
  ev = pygame.event.get()
  screen.blit(ethdisp,(0,0))
  screen.blit(wldisp, (0,1*font.get_linesize()) )

  # proceed events
  for event in ev:

    # handle MOUSEBUTTONUP
    if event.type == pygame.MOUSEBUTTONUP:
        pos = pygame.mouse.get_pos()
        key = pygame.mouse.get_pressed()
#        print pos
#        print key
        scope = IPdisplay()
        scope.__init__()
    if event.type == pygame.KEYUP:
            if event.key == K_ESCAPE:
                print "Escape Pressed"
                pygame.quit()
            else:
                print (event.key)
                print "you go nowhere, looping"

    for i,b in enumerate(buttons[screenMode]):
        b.draw(screen)
    pygame.display.update()
导入操作系统
导入pygame
导入时间
随机输入
导入套接字
进口fcntl
导入结构
导入fnmatch
从pygame.locals导入*
os.environ[“SDL_FBDEV”]=“/dev/fb1”
如果不是pygame.font:打印“警告,字体已禁用”
如果不是pygame.mixer:打印“警告,声音已禁用”
类图标:
定义初始化(self,name):
self.name=名称
尝试:
self.bitmap=pygame.image.load(iconPath+'/'+name+'.png')
除:
通过
类别按钮:
定义初始值(自、矩形、**kwargs):
self.rect=rect#界
self.color=无#背景填充颜色(如果有)
self.iconBg=None#背景图标(顶部颜色填充)
self.iconFg=None#前景图标(背景顶部)
self.bg=None#背景图标名称
self.fg=无#前景图标名称
self.callback=None#回调函数
self.value=None#传递给回调函数的值
对于键,使用kwargs.iteritems()表示的值:
如果键='color':self.color=值
elif key=='bg':self.bg=value
elif key=='fg':self.fg=value
elif key='cb':self.callback=value
elif键=='value':self.value=value
已选择def(自身,位置):
x1=self.rect[0]
y1=自整角[1]
x2=x1+self.rect[2]-1
y2=y1+self.rect[3]-1

如果((pos[0]>=x1)和(pos[0]=y1)和(pos[1]我想我已经解决了这部分问题。我并没有将变量声明为全局变量。所以我需要这样做:

ethdisp = None
然后在我首先使用的课堂上,我必须使用:

global ethdisp
那我就可以正常使用了