尝试创建包时出现“ TypeError:'pygame.Surface'对象不可迭代”

时间:2019-06-06 23:26:23

标签: python macos terminal pygame package

我正在尝试使用py2app打包我的应用程序,但是每次在终端中输入命令时都会遇到此错误:

TypeError: 'pygame.Surface' object is not iterable

这是我输入的用于打包应用程序的命令:

python setup.py py2app

我尝试将pygame导入终端,但这并没有帮助。这是我完整的应用程序代码(要打包的应用程序):

import pygame
import os
import random
from pygame.locals import *

flags = DOUBLEBUF

pygame.init()
pygame.event.set_allowed([QUIT])

current_path = os.path.dirname(__file__) #The directory the main file is in
iconPath = os.path.join(current_path, 'images') #The icon folder path

displayWidth = 1280
displayHeight = 720

prev_x = None
prev_y = None

gameDisplay = pygame.display.set_mode((displayWidth, displayHeight), flags)
gameDisplay.set_alpha(None)
pygame.display.set_caption('PyPaint')

rect = pygame.Rect(50, 120, 1080, 480)
sub = gameDisplay.subsurface(rect)

black = (0, 0, 0)
white = (255, 255, 255)
grey = (200, 200, 200)
darkCyan = (0, 130, 225)
green = (0, 150, 0)
lightGreen = (0, 255, 0)
red = (150, 0, 0)
lightRed = (255, 0, 0)

orange = (255, 140, 0)
yellow = (255, 255, 0)
lime = (0, 255, 0)
cyan = (0, 200, 255)
blue = (0, 0, 255)
purple = (140, 0, 255)
pink = (255, 0, 255)
gray = (100, 100, 100)

colourChosen = black
brushSize = 3
ColIndicatorLocation = (895, 614)
BrushIndicatorLocation = (45, 614)
SizeIndicatorLocation = (490, 614)

smallfont = pygame.font.SysFont("arialblack", 40)
medfont = pygame.font.SysFont("arialblack", 60)
largefont = pygame.font.SysFont("arialblack", 80)

airbrushIcon = pygame.image.load(os.path.join(iconPath, "airbrush.png"))
pencilIcon = pygame.image.load(os.path.join(iconPath, "pencil.png"))
calligraphyIcon = pygame.image.load(os.path.join(iconPath, "calligraphy.png"))
eraserIcon = pygame.image.load(os.path.join(iconPath, "eraser.png"))
rad1 = pygame.image.load(os.path.join(iconPath, "rad1.png"))
rad3 = pygame.image.load(os.path.join(iconPath, "rad3.png"))
rad5 = pygame.image.load(os.path.join(iconPath, "rad5.png"))
rad7 = pygame.image.load(os.path.join(iconPath, "rad7.png"))
rad9 = pygame.image.load(os.path.join(iconPath, "rad9.png"))
rad11 = pygame.image.load(os.path.join(iconPath, "rad11.png"))
rad13 = pygame.image.load(os.path.join(iconPath, "rad13.png"))
ColIndicator = pygame.image.load(os.path.join(iconPath, "colindicator.png"))
BrushIndicator = pygame.image.load(os.path.join(iconPath, "brushindicator.png"))
SizeIndicator = pygame.image.load(os.path.join(iconPath, "sizeindicator.png"))
saveIcon = pygame.image.load(os.path.join(iconPath, "saveicon.png"))

clock = pygame.time.Clock()
FPS = 60

airbrushMode = False
calligraphyMode = False
eraserMode = False
pencilMode = True

def paintScreen():
    global airbrushMode
    global calligraphyMode
    global eraserMode
    global pencilMode
    global colourChosen
    global brushSize
    paint = True
    gameDisplay.fill(darkCyan)
    click = pygame.mouse.get_pressed()
    pygame.draw.rect(gameDisplay, white, (50, 120, displayWidth - 100, displayHeight - 240)) #coords = from (50, 120), to (1180, 600)
    while paint:
        cur = pygame.mouse.get_pos()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        pygame.draw.rect(gameDisplay, darkCyan, (0, 0, 50, displayHeight))#to clean up the left border of the canvas (0, 0) to (50, 720)
        pygame.draw.rect(gameDisplay, darkCyan, (1230, 0, 50, displayHeight))#to clean up the right border of the canvas (1230, 0) to (50, 720)
        pygame.draw.rect(gameDisplay, darkCyan, (0, 600, 1280, 120))#to clean up the bottom of the canvas (0, 600) to (1280, 720)
        pygame.draw.rect(gameDisplay, darkCyan, (0, 0, 1280, 120))#to clean up the top of the canvas (0, 0) to (1280, 120)
        button('X', 50, 20, 70, 70, red, lightRed, action = 'quit')
        button('', 1200, 619, 30, 50, red, red, action = 'crimson')
        button('', 1170, 619, 30, 50, lightRed, lightRed, action = 'red')
        button('', 1140, 619, 30, 50, orange, orange, action = 'orange')
        button('', 1110, 619, 30, 50, yellow, yellow, action = 'yellow')
        button('', 1080, 619, 30, 50, lime, lime, action = 'lime')
        button('', 1050, 619, 30, 50, green, green, action = 'green')
        button('', 1020, 619, 30, 50, cyan, cyan, action = 'cyan')
        button('', 990, 619, 30, 50, blue, blue, action = 'blue')
        button('', 960, 619, 30, 50, purple, purple, action = 'purple')
        button('', 930, 619, 30, 50, pink, pink, action = 'pink')
        button('', 900, 619, 30, 50, black, black, action = 'black')
        button('', 870, 619, 30, 50, gray, gray, action = 'gray')
        icon(saveIcon, white, 1160, 20, 70, 70, white, grey, 'save')
        icon(pencilIcon, white, 50, displayHeight - 101, 51, 51, white, grey, 'pencil')
        icon(airbrushIcon, white, 150, displayHeight - 101, 51, 51, white, grey, 'airbrush')
        icon(calligraphyIcon, white, 250, displayHeight - 101, 51, 51, white, grey, 'calligraphy')
        icon(eraserIcon, white, 350, displayHeight - 101, 51, 51, white, grey, 'eraser')
        icon(rad1, white, 435, displayHeight - 101, 51, 51, white, grey, 'rad1')
        icon(rad3, white, 495, displayHeight - 101, 51, 51, white, grey, 'rad3')
        icon(rad5, white, 555, displayHeight - 101, 51, 51, white, grey, 'rad5')
        icon(rad7, white, 615, displayHeight - 101, 51, 51, white, grey, 'rad7')
        icon(rad9, white, 675, displayHeight - 101, 51, 51, white, grey, 'rad9')
        icon(rad11, white, 735, displayHeight - 101, 51, 51, white, grey, 'rad11')
        icon(rad13, white, 795, displayHeight - 101, 51, 51, white, grey, 'rad13')
        message_to_screen('Welcome to PyPaint', black, -310, 'large')
        gameDisplay.blit(BrushIndicator, BrushIndicatorLocation)
        gameDisplay.blit(SizeIndicator, SizeIndicatorLocation)
        gameDisplay.blit(ColIndicator, ColIndicatorLocation)
        if airbrushMode == True:
            airbrush(colourChosen, brushSize)
        elif calligraphyMode == True:
            calligraphy(colourChosen, brushSize)
        elif eraserMode == True:
            pencil(white, brushSize * 2)
        elif pencilMode == True:
            pencil(colourChosen, brushSize)
        pygame.display.update()
        clock.tick(FPS)

def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, action = None):
    global airbrushMode
    global calligraphyMode
    global eraserMode
    global pencilMode
    global brushSize
    global BrushIndicatorLocation
    global SizeIndicatorLocation
    cur = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x + width > cur[0] > x and y + height > cur[1] > y:#if the cursor is over the button
        pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
        gameDisplay.blit(icon, (x, y))
        if click[0] == 1 and action != None: #if clicked
            if action == 'quit':
                pygame.quit()
                quit()
            elif action == 'pencil':
                pencilMode = True
                airbrushMode = False
                calligraphyMode = False
                eraserMode = False
                BrushIndicatorLocation = (45, 614)
            elif action == 'airbrush':
                airbrushMode = True
                calligraphyMode = False
                pencilMode = False
                eraserMode = False
                BrushIndicatorLocation = (145, 614)
            elif action == 'calligraphy':
                calligraphyMode = True
                airbrushMode = False
                pencilMode = False
                eraserMode = False
                BrushIndicatorLocation = (245, 614)
            elif action == 'eraser':
                eraserMode = True
                airbrushMode = False
                pencilMode = False
                calligraphyMode = False
                BrushIndicatorLocation = (345, 614)
            elif action == 'rad1':
                brushSize = 1
                SizeIndicatorLocation = (430, 614)
            elif action == 'rad3':
                brushSize = 3
                SizeIndicatorLocation = (490, 614)
            elif action == 'rad5':
                brushSize = 5
                SizeIndicatorLocation = (550, 614)
            elif action == 'rad7':
                brushSize = 7
                SizeIndicatorLocation = (610, 614)
            elif action == 'rad9':
                brushSize = 9
                SizeIndicatorLocation = (670, 614)
            elif action == 'rad11':
                brushSize = 11
                SizeIndicatorLocation = (730, 614)
            elif action == 'rad13':
                brushSize = 13
                SizeIndicatorLocation = (790, 614)
            elif action == 'save':
                pygame.image.save(sub, "screenshot.jpg")
    else:
        pygame.draw.rect(gameDisplay, inactiveColour, (x, y, width, height))
        gameDisplay.blit(icon, (x, y))

def button(text, x, y, width, height, inactiveColour, activeColour, action = None):
    global colourChosen
    global ColIndicatorLocation
    cur = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x + width > cur[0] > x and y + height > cur[1] > y:
        pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
        if click[0] == 1 and action != None:
            if action == 'quit':
                pygame.quit()
                quit()
            elif action == 'crimson':
                colourChosen = red
                ColIndicatorLocation = (1195, 614)
            elif action == 'red':
                colourChosen = lightRed
                ColIndicatorLocation = (1165, 614)
            elif action == 'orange':
                colourChosen = orange
                ColIndicatorLocation = (1135, 614)
            elif action == 'yellow':
                colourChosen = yellow
                ColIndicatorLocation = (1105, 614)
            elif action == 'lime':
                colourChosen = lime
                ColIndicatorLocation = (1075, 614)
            elif action == 'green':
                colourChosen = green
                ColIndicatorLocation = (1045, 614)
            elif action == 'cyan':
                colourChosen = cyan
                ColIndicatorLocation = (1015, 614)
            elif action == 'blue':
                colourChosen = blue
                ColIndicatorLocation = (985, 614)
            elif action == 'purple':
                colourChosen = purple
                ColIndicatorLocation = (955, 614)
            elif action == 'pink':
                colourChosen = pink
                ColIndicatorLocation = (925, 614)
            elif action == 'black':
                colourChosen = black
                ColIndicatorLocation = (895, 614)
            elif action == 'gray':
                colourChosen = gray
                ColIndicatorLocation = (865, 614)
    else:
        pygame.draw.rect(gameDisplay, inactiveColour, (x, y, width, height))
    text_to_button(text, black, x, y, width, height)

def text_to_button(msg, colour, buttonx, buttony, buttonwidth, buttonheight, size = 'small'):
    textSurf, textRect = text_objects (msg, colour, size)
    textRect.center = ((buttonx + (buttonwidth/2)), buttony + (buttonheight/2))
    gameDisplay.blit(textSurf, textRect)

def message_to_screen(msg, colour, y_displace = 0, size = 'small'):
    textSurf, textRect = text_objects (msg, colour, size)
    textRect.center = (displayWidth / 2), (displayHeight / 2) + y_displace
    gameDisplay.blit(textSurf, textRect)

def airbrush(colourChosen, brushSize = 3):
    global prev_x
    global prev_y
    x, y = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x >= 50 and x <= displayWidth - 50 and y >= 120 and y <= displayHeight - 120:
        if click[0] == 1:
            x, y = pygame.mouse.get_pos()
            if x >= 0 and x <= displayWidth and y >= 0 and y <= displayHeight:
                pygame.draw.circle(gameDisplay, colourChosen, (x + random.randrange(-brushSize * 2, brushSize * 2), y + random.randrange(-brushSize * 2, brushSize * 2)), random.randrange(brushSize))
            # if there is previous point then draw missing points 
            if prev_x is not None:
                diff_x = x - prev_x
                diff_y = y - prev_y
                steps = max(abs(diff_x), abs(diff_y))
                # skip if distance is zero (error: dividing by zero)
                if steps > 0:
                    dx = diff_x / steps
                    dy = diff_y / steps
                    for _ in range(steps):
                        prev_x += dx
                        prev_y += dy
                        pygame.draw.circle(gameDisplay, colourChosen, (round(prev_x - 5) + random.randrange(-brushSize * 2, brushSize * 2), round(prev_y - 5) + random.randrange(-brushSize * 2, brushSize * 2)), random.randrange(brushSize))
            prev_x = x # remeber previous point
            prev_y = y # remeber previous point
        else:
            prev_x = None # there is no previous point
            prev_y = None # there is no previous point

def calligraphy(colourChosen, brushSize = 3):
    global prev_x
    global prev_y
    x, y = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x >= 50 and x <= displayWidth - 50 and y >= 120 and y <= displayHeight - 120:
        if click[0] == 1:
            x, y = pygame.mouse.get_pos()
            #if there is previous point then draw missing points 
            if prev_x is None:
                pygame.draw.rect(gameDisplay, colourChosen, ((x, y, brushSize, brushSize * 3)))
            elif prev_x is not None:
                diff_x = x - prev_x
                diff_y = y - prev_y
                steps = max(abs(diff_x), abs(diff_y))
                # skip if distance is zero (error: dividing by zero)
                if steps > 0:
                    dx = diff_x / steps
                    dy = diff_y / steps
                    for _ in range(steps):
                        prev_x += dx
                        prev_y += dy
                        pygame.draw.rect(gameDisplay, colourChosen, ((round(prev_x - 5), round(prev_y - 5), brushSize, brushSize * 3)))
            prev_x = x # remeber previous point
            prev_y = y # remeber previous point
        else:
            prev_x = None # there is no previous point
            prev_y = None # there is no previous point

def pencil(colourChosen, brushSize = 3):
    global prev_x
    global prev_y
    click = pygame.mouse.get_pressed()
    cur = pygame.mouse.get_pos()
    if cur[0] >= 50 and cur[0] <= displayWidth - 50 and cur[1] >= 120 and cur[1] <= displayHeight - 120:
        if click[0] == 1:
            x, y = pygame.mouse.get_pos()
            if prev_x is not None:
                diff_x = x - prev_x
                diff_y = y - prev_y
                steps = max(abs(diff_x), abs(diff_y))
                # skip if distance is zero (error: dividing by zero)
                if steps > 0:
                    dx = diff_x / steps
                    dy = diff_y / steps
                    for _ in range(steps):
                        prev_x += dx
                        prev_y += dy
                        pygame.draw.circle(gameDisplay, colourChosen, ((round(prev_x - 5), round(prev_y - 5))), brushSize)
            prev_x = x # remeber previous point
            prev_y = y # remeber previous point
        else:
            prev_x = None # there is no previous point
            prev_y = None # there is no previous point

def text_objects(text, colour, size):
    if size == 'small':
        textSurface = smallfont.render (text, True, colour)
    elif size == 'medium':
        textSurface = medfont.render (text, True, colour)
    elif size == 'large':
        textSurface = largefont.render (text, True, colour)
    return textSurface, textSurface.get_rect() 

paintScreen()

这是我的setup.py文件:

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""
import os
import pygame
from setuptools import setup

current_path = os.path.dirname(__file__)
iconPath = os.path.join(current_path, 'images')

APP = ['PyPaint.py']
DATA_FILES = [pygame.image.load(os.path.join(iconPath, "airbrush.png")),
              pygame.image.load(os.path.join(iconPath, "brushindicator.png")),
              pygame.image.load(os.path.join(iconPath, "calligraphy.png")),
              pygame.image.load(os.path.join(iconPath, "colindicator.png")),
              pygame.image.load(os.path.join(iconPath, "eraser.png")),
              pygame.image.load(os.path.join(iconPath, "pencil.png")),
              pygame.image.load(os.path.join(iconPath, "rad1.png")),
              pygame.image.load(os.path.join(iconPath, "rad3.png")),
              pygame.image.load(os.path.join(iconPath, "rad5.png")),
              pygame.image.load(os.path.join(iconPath, "rad7.png")),
              pygame.image.load(os.path.join(iconPath, "rad9.png")),
              pygame.image.load(os.path.join(iconPath, "rad11.png")),
              pygame.image.load(os.path.join(iconPath, "rad13.png")),
              pygame.image.load(os.path.join(iconPath, "saveicon.png")),
              pygame.image.load(os.path.join(iconPath, "sizeindicator.png"))]
OPTIONS = {}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

这是完整的追溯:

Traceback (most recent call last):
  File "setup.py", line 36, in <module>
    setup_requires=['py2app'],
  File "/usr/local/lib/python2.7/site-packages/setuptools/__init__.py", line 140, in setup
    return distutils.core.setup(**attrs)
  File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/core.py", line 151, in setup
    dist.run_commands()
  File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py", line 972, in run_command
    cmd_obj.run()
  File "/usr/local/lib/python2.7/site-packages/py2app-0.19-py2.7.egg/py2app/build_app.py", line 838, in run
    self._run()
  File "/usr/local/lib/python2.7/site-packages/py2app-0.19-py2.7.egg/py2app/build_app.py", line 1053, in _run
    self.run_normal()
  File "/usr/local/lib/python2.7/site-packages/py2app-0.19-py2.7.egg/py2app/build_app.py", line 1165, in run_normal
    self.create_binaries(py_files, pkgdirs, extensions, loader_files)
  File "/usr/local/lib/python2.7/site-packages/py2app-0.19-py2.7.egg/py2app/build_app.py", line 1451, in create_binaries
    extra_scripts)
  File "/usr/local/lib/python2.7/site-packages/py2app-0.19-py2.7.egg/py2app/build_app.py", line 2262, in build_executable
    for src, dest in self.iter_data_files():
  File "/usr/local/lib/python2.7/site-packages/py2app-0.19-py2.7.egg/py2app/build_app.py", line 899, in iter_data_files
    for (path, files) in (normalize_data_file(fn) for fn in allres):
TypeError: 'pygame.Surface' object is not iterable

我不确定问题是否出在试图打包pygame应用程序,还是我在py2app的命令或安装中做错了。

0 个答案:

没有答案