Python 使用Pyinstaller创建可执行Pygame后出错

Python 使用Pyinstaller创建可执行Pygame后出错,python,segmentation-fault,pygame,pyinstaller,Python,Segmentation Fault,Pygame,Pyinstaller,所以我的pygame脚本在python中工作得非常好,所以我决定尝试捆绑该程序以分发它,使用。我按照指示编译并运行Pyinstaller: sudo pip install pyinstaller pyinstaller Loop.py 它工作得很好。然后,我运行生成的可执行文件以查看其运行情况: cd /dist/Loop/ ./Loop 结果是: Fatal Python error: (pygame parachute) Segmentation Fault Aborted (core

所以我的pygame脚本在python中工作得非常好,所以我决定尝试捆绑该程序以分发它,使用。我按照指示编译并运行Pyinstaller:

sudo pip install pyinstaller
pyinstaller Loop.py
它工作得很好。然后,我运行生成的可执行文件以查看其运行情况:

cd /dist/Loop/
./Loop
结果是:

Fatal Python error: (pygame parachute) Segmentation Fault
Aborted (core dumped)
似乎没有执行Loop.py的任何一行,因为导入包后的第一行是打开一个新窗口(这没有发生)。通过谷歌搜索,似乎唯一推荐的解决方案是调试代码以找到分段发生的位置。然而,这是没有意义的,因为代码本身工作得非常好,它只有在使用pyinstaller之后才能这样做。我甚至在与循环可执行文件相同的目录中输入了python shell,并验证了导入pygame没有问题

无论如何,我只是在寻找捆绑python项目的方法。当然,如果您知道更好的捆绑python项目进行发布的方法(在Ubuntu 16上使用python 2.7),我很乐意查看:)

编辑

我创建了一个尽可能简化的代码版本,以便专注于主要问题(当然也是为了证明问题是可复制的)。这是主程序(
Loop.py
):

这是
Car.py

from Car import*

vehicle = Car()


def display_all(main_surface, display_list):
    main_surface.fill((0, 100, 100))
    for element in display_list:
        element.display(main_surface)


def update_all(update_list):
    for element in update_list:
        element.update()


running = True
while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.KEYDOWN:
            None

    key = pygame.key.get_pressed()

    to_update = [vehicle]
    to_display = [vehicle]

    update_all(to_update)
    display_all(main_s, to_display)
    pygame.display.flip()
from Startup import*


class Car:
    def __init__(self):
        self.body = pygame.image.load("Images//Body//Grey.png")
        self.wheels = pygame.image.load("Images//Wheels//Black.png")
        self.rect = self.body.get_rect()
        self.rect.x = width/2
        self.rect.y = height/2
        self.rect.center = self.rect.x, self.rect.y
        self.angle = 0
        self.move_x = 0
        self.move_y = 0

    def display(self, main_surface):
        temp_image = pygame.transform.rotate(self.body, self.angle)
        main_surface.blit(temp_image, (self.rect.x, self.rect.y))
        temp_image = pygame.transform.rotate(self.wheels, self.angle)
        main_surface.blit(temp_image, (self.rect.x, self.rect.y))

    def update(self):
        self.move_x = 0
        self.move_y = 0
import pygame
import math
pygame.font.init()

clock = pygame.time.Clock()
font = pygame.font.SysFont("", 20)

pygame.init()
width = 1000
height = 600
main_s = pygame.display.set_mode((width, height))
下面是
Startup.py

from Car import*

vehicle = Car()


def display_all(main_surface, display_list):
    main_surface.fill((0, 100, 100))
    for element in display_list:
        element.display(main_surface)


def update_all(update_list):
    for element in update_list:
        element.update()


running = True
while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.KEYDOWN:
            None

    key = pygame.key.get_pressed()

    to_update = [vehicle]
    to_display = [vehicle]

    update_all(to_update)
    display_all(main_s, to_display)
    pygame.display.flip()
from Startup import*


class Car:
    def __init__(self):
        self.body = pygame.image.load("Images//Body//Grey.png")
        self.wheels = pygame.image.load("Images//Wheels//Black.png")
        self.rect = self.body.get_rect()
        self.rect.x = width/2
        self.rect.y = height/2
        self.rect.center = self.rect.x, self.rect.y
        self.angle = 0
        self.move_x = 0
        self.move_y = 0

    def display(self, main_surface):
        temp_image = pygame.transform.rotate(self.body, self.angle)
        main_surface.blit(temp_image, (self.rect.x, self.rect.y))
        temp_image = pygame.transform.rotate(self.wheels, self.angle)
        main_surface.blit(temp_image, (self.rect.x, self.rect.y))

    def update(self):
        self.move_x = 0
        self.move_y = 0
import pygame
import math
pygame.font.init()

clock = pygame.time.Clock()
font = pygame.font.SysFont("", 20)

pygame.init()
width = 1000
height = 600
main_s = pygame.display.set_mode((width, height))
编辑(再次)

我只是按照评论中的建议尝试了
py2app
,但似乎不起作用。正如我可以发现的,其目的是在MacOS上运行。如上所述,我使用的是Ubuntu16,这就是我编写代码的架构。当我完成上面链接的教程时,我没有出现任何复杂情况,并继续执行该文件:

./dist/Loop.app/Contents/MacOS/Loop
我很快就发现了错误:

bash: cannot execute binary file: Exec format error
这似乎表明它不适合我的电脑

你知道有没有适合Ubuntu的版本吗?或者是否有其他解决方案

谢谢,
内森

谢谢你提供了一个合适的例子,它帮助我识别了罪犯:

font = pygame.font.SysFont("", 20)
如果禁用该行,则应该能够生成并运行可执行文件。这很容易测试,因为示例中没有使用
font

如果您将名称更改为可能可用的名称,如
Arial
,或包含列表作为名称,则搜索不存在的字体时可能会出现问题。或者您可以从可用的字体中指定一种字体,例如
pygame.font.get_fonts()[0]

下面是一个经过修改的示例,可以将汽车移动到您单击鼠标的任何位置:

import pygame
import math

pygame.init()
pygame.font.init()
all_fonts = pygame.font.get_fonts()
print(all_fonts)
font = pygame.font.SysFont(all_fonts[0], 20) # just use the first font.
#font = pygame.font.SysFont("Arial, couriernewm", 20)
clock = pygame.time.Clock()

width = 1000
height = 600
main_s = pygame.display.set_mode((width, height))

class Car(pygame.sprite.Sprite):
    """Sprite with self drawn images"""
    def __init__(self, speed=5):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((40,30)).convert_alpha()  # sprites need an 'image'
        self.image.fill((0,0,0,0)) # make transparent
        pygame.draw.rect(self.image, (111,111,111), (0,5, 40, 15)) # draw the body
        for center in [(5,5), (35,5), (5,20), (35, 20)]:  # draw four wheels
            pygame.draw.circle(self.image, (0,0,0), center, 5)
        self.rect = self.image.get_rect()
        self.rect.x = width/2
        self.rect.y = height/2
        self.rect.center = self.rect.x, self.rect.y
        self.angle = 0
        self.move_x = 0
        self.move_y = 0
        self.speed = speed
        self.destination = self.rect.center

    def update(self, pos=None):
        if pos:
            #set new destination
            self.destination = pos
        else:
        # move towards destination at speed
            xd = self.destination[0] - self.rect.center[0]
            if xd < 0:
                xd = max(xd, -self.speed)
            else:
                xd = min(xd, self.speed)
            yd = self.destination[1] - self.rect.center[1]
            if yd < 0:
               yd = max(yd, -self.speed)
            else:
                yd = min(yd, self.speed)
            self.rect.center = (self.rect.center[0] + xd, self.rect.center[1] + yd)


# create a sprite group to store cars
slow_car = Car()
vehicles = pygame.sprite.Group(slow_car)

running = True
#main loop
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            pass
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # move to position
            vehicles.update(event.pos)
    # update sprites
    vehicles.update()

    # clear surface
    main_s.fill((0, 100, 100))

    #draw sprites
    vehicles.draw(main_s)

    # update display
    pygame.display.update()
    clock.tick(10)
pygame.quit()
导入pygame
输入数学
pygame.init()
pygame.font.init()
all\u fonts=pygame.font.get\u fonts()
打印(所有字体)
font=pygame.font.SysFont(所有字体[0],20)#只需使用第一种字体。
#font=pygame.font.SysFont(“Arial,couriernewm”,20)
clock=pygame.time.clock()
宽度=1000
高度=600
main_s=pygame.display.set_模式((宽度、高度))
类车(pygame.sprite.sprite):
“具有自绘制图像的精灵”
def u u初始(自身,速度=5):
pygame.sprite.sprite.\uuuuu init\uuuuuuu(自我)
self.image=pygame.Surface((40,30)).convert_alpha()#精灵需要一个“图像”
self.image.fill((0,0,0,0))#使透明
pygame.draw.rect(self.image,(111111111),(0,5,40,15))#绘制身体
对于[(5,5),(35,5),(5,20),(35,20)]中的中心:#绘制四个车轮
pygame.draw.circle(self.image,(0,0,0),center,5)
self.rect=self.image.get_rect()
self.rect.x=宽度/2
自校正y=高度/2
self.rect.center=self.rect.x,self.rect.y
自转角=0
self.move_x=0
self.move_y=0
自身速度=速度
self.destination=self.rect.center
def更新(自身,位置=无):
如果pos:
#设置新的目的地
self.destination=pos
其他:
#以最快的速度向目的地移动
xd=self.destination[0]-self.rect.center[0]
如果xd<0:
xd=最大(xd,-自速度)
其他:
xd=最小值(xd,自速度)
yd=自目的地[1]-自纠正中心[1]
如果yd<0:
yd=最大值(yd,-自身速度)
其他:
yd=最小值(yd,自速度)
self.rect.center=(self.rect.center[0]+xd,self.rect.center[1]+yd)
#创建一个精灵组来存储汽车
慢车
车辆=pygame.sprite.Group(慢车)
运行=真
#主回路
运行时:
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
运行=错误
elif event.type==pygame.KEYDOWN:
通过
elif event.type==pygame.MOUSEBUTTONDOWN:
#移动到位置
车辆更新(事件位置)
#更新精灵
车辆更新(
#净表面
主要填料(0、100、100))
#画精灵
车辆.牵引(主)
#更新显示
pygame.display.update()
时钟滴答(10)
pygame.quit()

注:不幸的是,这不是运行在Mac上,所以我不能保证它会工作。启动可执行文件时,我确实看到应用程序失败。

您使用的是最新版本的PyInstaller吗?您最好包含一段代码来重现问题,然后我们可以尝试提供帮助。我在问题中准确地说明了我是如何安装PyInstaller的,所以是的,我有最新版本,运行
PyInstaller-v
返回添加的3.3.1Code示例。现在你可以像我一样运行了。可能是相关的:而且,看起来他们并没有找到一个很好的解决方案。。。Pyinstaller中的错误报告也没有出现。。。一位记者提到py2app为他工作,所以不妨试试看它是否为你工作?好吧,但py2app似乎只为MacOS工作?我刚刚在我的Ubuntu 16上试用了它(正如我在最初的问题中所说的),我得到了
bash:cannotexecute