我无法将我的py文件打包成exe文件
I can't package my py file to an exe file
我是编程新手,我决定使用 python 作为我的第一门编程语言!所以我通过 Pygame 创建了一个没有附加文件的游戏,它只有一个 python 文件。
这只是一个问答游戏,我通过代码自己创建了一个GUI。游戏 运行 在使用 cmd 运行 游戏时很好,但是当我使用 pyinstaller 将其转换为可执行文件并尝试 运行ning 它时,它只会闪烁一个空的黑色窗口屏幕,然后关闭。我什至尝试使用 cx freeze。我尝试了很多解决方案,但其中 none 行得通。任何帮助,将不胜感激。我对编程很陌生,所以如果你能回答我的问题,你能用初学者的话解释一下吗哈哈哈。这是我的游戏代码:
import random
from random import randint
WIDTH = 1280
HEIGHT = 720
def draw():
screen.fill("green yellow")
screen.draw.filled_rect(main_box, "sky blue")
screen.draw.filled_rect(timer_box, "sky blue")
screen.draw.text("Score: " + str(score), color="black", topleft=(10, 10))
for box in answer_boxes:
screen.draw.filled_rect(box, "orange")
screen.draw.textbox(str(time_left), timer_box, color=('black'))
screen.draw.textbox(question[0], main_box, color=('black'))
index = 1
for box in answer_boxes:
screen.draw.textbox(question[index], box, color=('black'))
index = index + 1
def game_over():
global question, time_left, scoredecreaserps
scoredecreaserps = 0
message = 'Game Over. You got %s questions correct' %str(numques)
question = [message, '-', '-', '-', '-', 5]
time_left = 0
def correct_answer():
global question, score, numques, time_left
numques = numques + 1
score = score + 1000
if questions:
question = questions.pop()
time_left = 10
else:
print('End of questions')
game_over()
def on_mouse_down(pos):
index = 1
for box in answer_boxes:
if box.collidepoint(pos):
print('Clicked on answer' + str(index))
if index == question[5]:
print('You got it correct!')
correct_answer()
else:
game_over()
index = index + 1
def update_time_left():
global time_left
if time_left:
time_left = time_left - 1
else:
game_over()
def score_lower():
global score
if score:
score = score - scoredecreaserps
main_box = Rect(50, 40, 820, 240)
timer_box = Rect(990, 40, 240, 240)
answer_box1 = Rect(50, 358, 495, 165)
answer_box2 = Rect(735, 358, 495, 165)
answer_box3 = Rect(50, 538, 495, 165)
answer_box4 = Rect(735, 538, 495, 165)
answer_boxes = [answer_box1, answer_box2, answer_box3, answer_box4]
scoredecreaserps = 80
numques = 0
score = 0
time_left = 10
q1 = ["Who was the third president of the Philippines?",
'Rodrigo Duterte', 'Ramon Magsaysay', 'Jose P. Laurel',
'Fidel V. Ramos', 3]
q2 = ['When was the Philippines granted independece from the US?'
, '1977', '1946', '1935', '1907', 2]
q3 = ['When was the Philippines colonized by Spain', '1898', '1523', '1654',
'1521', 4]
questions = [q1, q2, q3]
random.shuffle(questions)
question = questions.pop(0)
clock.schedule_interval(update_time_left, 1.0)
clock.schedule_interval(score_lower, 1.0)
我在这种情况下使用auto-py-to-exe
https://pypi.org/project/auto-py-to-exe/
我的系统:Python 2.7 on Windows 8.1
人们告诉我 exe 也很好用
用 Linux + 葡萄酒
如果您是编程新手,则不应专注于创建二进制文件。了解如何在 shell 中 运行 您的应用程序,并通过学习 Object-Oriented 编程、函数式编程、每种代码方法的优缺点来培养您的开发人员技能。
您会发现,您的大部分项目都不需要 运行 它的 exe。如果你想点击一个文件并 运行,你可以 运行 python 文件直接用一些 Windows 配置*,或者为它创建一个 shell 脚本设置 and/or 运行。这种方法是使用 python.
的一种更自然的方式
* 我已经很久不用 Windows,但我相信你可以用 UI 中的 python.exe 打开一个 python 文件。
我已经成功解决了您的任务,请执行后续步骤:
- 需要安装一次的模块:
python -m pip install pyinstaller pgzero requests
- 通过 运行 下一个命令行检索包含所有需要资源的存档
game.zip
:
python -c "import requests, base64; f = open('game.zip', 'wb'); f.write(base64.b64decode(requests.get('https://pastebin.com/raw/GnJ72zgP').content)); f.close()"
里面 game.zip
文件已经有了所有需要的东西,只需要 运行 package.cmd
,打包后需要一些时间,你会在 dist/script.exe
.
game.zip
有下一个文件:
package.cmd
包含一行 pyinstaller --noconfirm --onefile --console --noupx --add-data "./pgzero/;./pgzero/" --add-data "./fonts/;./fonts/" --runtime-tmpdir "c:/temp/" script.py
script.py
包含我将在下面提供的完整脚本代码。
fonts/arial.ttf
包含取自 C:\Windows\Fonts\arial.ttf
的文件。
pgzero/data/
等于文件夹 D:\bin2\Python37\Lib\site-packages\pgzero\data\
(在此路径中更改 Python 分发的位置)。
完全更正和改进的脚本代码在下面。您可能需要更改第一行 - 变量 logname
等于写入日志的路径,如果程序崩溃,所有异常都写在那里,变量 fontname
等于位于 ./fonts/arial.ttf
在game.zip
中,您可以将此字体替换为您喜欢的字体。
脚本可以通过 python script.py
命令或使用 pyinstaller
.
打包成 script.exe
来 运行
接下来的改进:
- 添加了
try
/except
全局块以捕获所有程序的 exceptions/errors,内部 except
块错误被保存到日志文件,路径来自 logname
变量。
- 在脚本的第一行添加了
faulthandler
以捕获所有严重错误,例如 Segmentation Fault
。
- 在第一行中添加
os.chdir(...)
以将工作目录更改为 运行 从中打包脚本的目录。因为默认情况下打包脚本的工作目录不等于脚本所在的目录。
- 在第一行添加了
import pgzrun
,在最后几行添加了 pgzrun.go()
,这允许脚本仅通过 python script.py
而不是命令行 pgzrun script.py
运行nable ] 这对于 pygame
脚本 运行ning 很常见。为了使用 pyinstaller 轻松打包,此改进是必要的。
- 为
screen.draw.text...(...)
函数的所有调用添加了 fontname = fontname
参数,因为如果未提供字体文件名,打包的脚本会崩溃。
try:
logname = 'c:/temp/pgzrun.log'
fontname = 'arial.ttf'
import faulthandler
faulthandler.enable()
import os, sys
script_dir = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
os.chdir(script_dir)
import pgzrun
import random
from random import randint
WIDTH = 1280
HEIGHT = 720
def draw():
screen.fill("green yellow")
screen.draw.filled_rect(main_box, "sky blue")
screen.draw.filled_rect(timer_box, "sky blue")
screen.draw.text("Score: " + str(score), color="black", topleft=(10, 10), fontname=fontname)
for box in answer_boxes:
screen.draw.filled_rect(box, "orange")
screen.draw.textbox(str(time_left), timer_box, color=('black'), fontname=fontname)
screen.draw.textbox(question[0], main_box, color=('black'), fontname=fontname)
index = 1
for box in answer_boxes:
screen.draw.textbox(question[index], box, color=('black'), fontname=fontname)
index = index + 1
def game_over():
global question, time_left, scoredecreaserps
scoredecreaserps = 0
message = 'Game Over. You got %s questions correct' %str(numques)
question = [message, '-', '-', '-', '-', 5]
time_left = 0
def correct_answer():
global question, score, numques, time_left
numques = numques + 1
score = score + 1000
if questions:
question = questions.pop()
time_left = 10
else:
print('End of questions')
game_over()
def on_mouse_down(pos):
index = 1
for box in answer_boxes:
if box.collidepoint(pos):
print('Clicked on answer' + str(index))
if index == question[5]:
print('You got it correct!')
correct_answer()
else:
game_over()
index = index + 1
def update_time_left():
global time_left
if time_left:
time_left = time_left - 1
else:
game_over()
def score_lower():
global score
if score:
score = score - scoredecreaserps
main_box = Rect(50, 40, 820, 240)
timer_box = Rect(990, 40, 240, 240)
answer_box1 = Rect(50, 358, 495, 165)
answer_box2 = Rect(735, 358, 495, 165)
answer_box3 = Rect(50, 538, 495, 165)
answer_box4 = Rect(735, 538, 495, 165)
answer_boxes = [answer_box1, answer_box2, answer_box3, answer_box4]
scoredecreaserps = 80
numques = 0
score = 0
time_left = 10
q1 = ["Who was the third president of the Philippines?",
'Rodrigo Duterte', 'Ramon Magsaysay', 'Jose P. Laurel',
'Fidel V. Ramos', 3]
q2 = ['When was the Philippines granted independece from the US?'
, '1977', '1946', '1935', '1907', 2]
q3 = ['When was the Philippines colonized by Spain', '1898', '1523', '1654',
'1521', 4]
questions = [q1, q2, q3]
random.shuffle(questions)
question = questions.pop(0)
clock.schedule_interval(update_time_left, 1.0)
clock.schedule_interval(score_lower, 1.0)
pgzrun.go()
except:
import traceback
with open(logname, 'a', encoding = 'utf-8') as f:
f.write(''.join(traceback.format_exc()) + '\n')
我是编程新手,我决定使用 python 作为我的第一门编程语言!所以我通过 Pygame 创建了一个没有附加文件的游戏,它只有一个 python 文件。
这只是一个问答游戏,我通过代码自己创建了一个GUI。游戏 运行 在使用 cmd 运行 游戏时很好,但是当我使用 pyinstaller 将其转换为可执行文件并尝试 运行ning 它时,它只会闪烁一个空的黑色窗口屏幕,然后关闭。我什至尝试使用 cx freeze。我尝试了很多解决方案,但其中 none 行得通。任何帮助,将不胜感激。我对编程很陌生,所以如果你能回答我的问题,你能用初学者的话解释一下吗哈哈哈。这是我的游戏代码:
import random
from random import randint
WIDTH = 1280
HEIGHT = 720
def draw():
screen.fill("green yellow")
screen.draw.filled_rect(main_box, "sky blue")
screen.draw.filled_rect(timer_box, "sky blue")
screen.draw.text("Score: " + str(score), color="black", topleft=(10, 10))
for box in answer_boxes:
screen.draw.filled_rect(box, "orange")
screen.draw.textbox(str(time_left), timer_box, color=('black'))
screen.draw.textbox(question[0], main_box, color=('black'))
index = 1
for box in answer_boxes:
screen.draw.textbox(question[index], box, color=('black'))
index = index + 1
def game_over():
global question, time_left, scoredecreaserps
scoredecreaserps = 0
message = 'Game Over. You got %s questions correct' %str(numques)
question = [message, '-', '-', '-', '-', 5]
time_left = 0
def correct_answer():
global question, score, numques, time_left
numques = numques + 1
score = score + 1000
if questions:
question = questions.pop()
time_left = 10
else:
print('End of questions')
game_over()
def on_mouse_down(pos):
index = 1
for box in answer_boxes:
if box.collidepoint(pos):
print('Clicked on answer' + str(index))
if index == question[5]:
print('You got it correct!')
correct_answer()
else:
game_over()
index = index + 1
def update_time_left():
global time_left
if time_left:
time_left = time_left - 1
else:
game_over()
def score_lower():
global score
if score:
score = score - scoredecreaserps
main_box = Rect(50, 40, 820, 240)
timer_box = Rect(990, 40, 240, 240)
answer_box1 = Rect(50, 358, 495, 165)
answer_box2 = Rect(735, 358, 495, 165)
answer_box3 = Rect(50, 538, 495, 165)
answer_box4 = Rect(735, 538, 495, 165)
answer_boxes = [answer_box1, answer_box2, answer_box3, answer_box4]
scoredecreaserps = 80
numques = 0
score = 0
time_left = 10
q1 = ["Who was the third president of the Philippines?",
'Rodrigo Duterte', 'Ramon Magsaysay', 'Jose P. Laurel',
'Fidel V. Ramos', 3]
q2 = ['When was the Philippines granted independece from the US?'
, '1977', '1946', '1935', '1907', 2]
q3 = ['When was the Philippines colonized by Spain', '1898', '1523', '1654',
'1521', 4]
questions = [q1, q2, q3]
random.shuffle(questions)
question = questions.pop(0)
clock.schedule_interval(update_time_left, 1.0)
clock.schedule_interval(score_lower, 1.0)
我在这种情况下使用auto-py-to-exe https://pypi.org/project/auto-py-to-exe/
我的系统:Python 2.7 on Windows 8.1 人们告诉我 exe 也很好用 用 Linux + 葡萄酒
如果您是编程新手,则不应专注于创建二进制文件。了解如何在 shell 中 运行 您的应用程序,并通过学习 Object-Oriented 编程、函数式编程、每种代码方法的优缺点来培养您的开发人员技能。
您会发现,您的大部分项目都不需要 运行 它的 exe。如果你想点击一个文件并 运行,你可以 运行 python 文件直接用一些 Windows 配置*,或者为它创建一个 shell 脚本设置 and/or 运行。这种方法是使用 python.
的一种更自然的方式* 我已经很久不用 Windows,但我相信你可以用 UI 中的 python.exe 打开一个 python 文件。
我已经成功解决了您的任务,请执行后续步骤:
- 需要安装一次的模块:
python -m pip install pyinstaller pgzero requests
- 通过 运行 下一个命令行检索包含所有需要资源的存档
game.zip
:
python -c "import requests, base64; f = open('game.zip', 'wb'); f.write(base64.b64decode(requests.get('https://pastebin.com/raw/GnJ72zgP').content)); f.close()"
里面
game.zip
文件已经有了所有需要的东西,只需要 运行package.cmd
,打包后需要一些时间,你会在dist/script.exe
.game.zip
有下一个文件:package.cmd
包含一行pyinstaller --noconfirm --onefile --console --noupx --add-data "./pgzero/;./pgzero/" --add-data "./fonts/;./fonts/" --runtime-tmpdir "c:/temp/" script.py
script.py
包含我将在下面提供的完整脚本代码。fonts/arial.ttf
包含取自C:\Windows\Fonts\arial.ttf
的文件。pgzero/data/
等于文件夹D:\bin2\Python37\Lib\site-packages\pgzero\data\
(在此路径中更改 Python 分发的位置)。
完全更正和改进的脚本代码在下面。您可能需要更改第一行 - 变量 logname
等于写入日志的路径,如果程序崩溃,所有异常都写在那里,变量 fontname
等于位于 ./fonts/arial.ttf
在game.zip
中,您可以将此字体替换为您喜欢的字体。
脚本可以通过 python script.py
命令或使用 pyinstaller
.
script.exe
来 运行
接下来的改进:
- 添加了
try
/except
全局块以捕获所有程序的 exceptions/errors,内部except
块错误被保存到日志文件,路径来自logname
变量。 - 在脚本的第一行添加了
faulthandler
以捕获所有严重错误,例如Segmentation Fault
。 - 在第一行中添加
os.chdir(...)
以将工作目录更改为 运行 从中打包脚本的目录。因为默认情况下打包脚本的工作目录不等于脚本所在的目录。 - 在第一行添加了
import pgzrun
,在最后几行添加了pgzrun.go()
,这允许脚本仅通过python script.py
而不是命令行pgzrun script.py
运行nable ] 这对于pygame
脚本 运行ning 很常见。为了使用 pyinstaller 轻松打包,此改进是必要的。 - 为
screen.draw.text...(...)
函数的所有调用添加了fontname = fontname
参数,因为如果未提供字体文件名,打包的脚本会崩溃。
try:
logname = 'c:/temp/pgzrun.log'
fontname = 'arial.ttf'
import faulthandler
faulthandler.enable()
import os, sys
script_dir = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
os.chdir(script_dir)
import pgzrun
import random
from random import randint
WIDTH = 1280
HEIGHT = 720
def draw():
screen.fill("green yellow")
screen.draw.filled_rect(main_box, "sky blue")
screen.draw.filled_rect(timer_box, "sky blue")
screen.draw.text("Score: " + str(score), color="black", topleft=(10, 10), fontname=fontname)
for box in answer_boxes:
screen.draw.filled_rect(box, "orange")
screen.draw.textbox(str(time_left), timer_box, color=('black'), fontname=fontname)
screen.draw.textbox(question[0], main_box, color=('black'), fontname=fontname)
index = 1
for box in answer_boxes:
screen.draw.textbox(question[index], box, color=('black'), fontname=fontname)
index = index + 1
def game_over():
global question, time_left, scoredecreaserps
scoredecreaserps = 0
message = 'Game Over. You got %s questions correct' %str(numques)
question = [message, '-', '-', '-', '-', 5]
time_left = 0
def correct_answer():
global question, score, numques, time_left
numques = numques + 1
score = score + 1000
if questions:
question = questions.pop()
time_left = 10
else:
print('End of questions')
game_over()
def on_mouse_down(pos):
index = 1
for box in answer_boxes:
if box.collidepoint(pos):
print('Clicked on answer' + str(index))
if index == question[5]:
print('You got it correct!')
correct_answer()
else:
game_over()
index = index + 1
def update_time_left():
global time_left
if time_left:
time_left = time_left - 1
else:
game_over()
def score_lower():
global score
if score:
score = score - scoredecreaserps
main_box = Rect(50, 40, 820, 240)
timer_box = Rect(990, 40, 240, 240)
answer_box1 = Rect(50, 358, 495, 165)
answer_box2 = Rect(735, 358, 495, 165)
answer_box3 = Rect(50, 538, 495, 165)
answer_box4 = Rect(735, 538, 495, 165)
answer_boxes = [answer_box1, answer_box2, answer_box3, answer_box4]
scoredecreaserps = 80
numques = 0
score = 0
time_left = 10
q1 = ["Who was the third president of the Philippines?",
'Rodrigo Duterte', 'Ramon Magsaysay', 'Jose P. Laurel',
'Fidel V. Ramos', 3]
q2 = ['When was the Philippines granted independece from the US?'
, '1977', '1946', '1935', '1907', 2]
q3 = ['When was the Philippines colonized by Spain', '1898', '1523', '1654',
'1521', 4]
questions = [q1, q2, q3]
random.shuffle(questions)
question = questions.pop(0)
clock.schedule_interval(update_time_left, 1.0)
clock.schedule_interval(score_lower, 1.0)
pgzrun.go()
except:
import traceback
with open(logname, 'a', encoding = 'utf-8') as f:
f.write(''.join(traceback.format_exc()) + '\n')