様々なピットをスキップしてpythonプログラムをpyinstallerでexeにパッケージ化するにはどうすればいいですか?
7611 ワード
前に文章を書いたことがありますが、seleniumで文ファンのページの箴言を登る方法と、これらの文を画像に書く方法を議論して、画像をデスクトップの背景に設定して、タイミングを決めて更新して、興味があれば見てください.
この文章では、以上のpythonプログラムをpyinstallerでexeにパッケージ化し、他人に共有しやすくし、嫉妬や憎しみをうらやましがらせる方法について議論します.
まずpythonプログラムをexeに変換し、よく使われるのはpyinstaller、py 2 exe、nuitkaです.最後のnuitkaはpythonコードをc++コードに変換してからexeファイルをコンパイルして生成し、実行効率が大幅に向上します.py 2 exeはプラットフォーム間で悪く、単一のexeファイルにパッケージできないと言われています.だからネット上の世論に基づいてpyinstallerを重点的に研究して、本文の重点と難点はパッケージタイミング実行モジュールapschedulerの時に多くの問題に出会って、同時にどのように使った画像、フォント、テキストなどのデータファイルをexeにパッケージします.
ソースプログラムは前のリンクを見てください.パッケージ化の過程で各モジュールのインポートの問題に遭遇しました.ここにはテクニックがあります.生成後のexeファイルが直接ダブルクリックして実行されると、エラーが発生した後、フラッシュして、エラー情報を見極めることができません.ソースコードにinput()を入れる人がいますが、実際にエラーが発生したときはinputを実行していないので、フラッシュしました.私は最初とても愚かで、windowsのスクリーンショットでその驚きの一瞥を残そうとしたが、何度も試しても成功しなかった.結局、これは目が速くて、自動スクリーンショットのスクリプトを書きたいほどだった.幸いなことに、後で知恵を絞って、もとはexeもcmdの中で直接ファイル名をたたいて運行することができて、このように間違いがあっても、雁が音を残して、跡があります.
さて、モジュールエラーの問題について、最初はapschedulerのhookファイルが少なくなったと思っていたので、ネット上でapschedulerのhookファイル(ページが長いので、自習して探しています)を見つけました.pyinstaller-F--additional-hooks-dir add_でhook set_wall_paper.pyはパッケージ化されていますが、生成されたexeファイルは依然としてエラーを報告しています.No trigger by the name「interval」was foundは、ネット上でsetuptoolsをアップグレードすると言っていますが、アップグレード後は役に立たないです.そこで探し続けると、すぐにIntervalTriggerというモジュールを導入し、プログラムヘッダに参加する必要があるという説があります.
実行後にエラーが発生しました:No module named'apscheduler.triggers.interval'は、グーグルを続け、stactoverflow上の解決方法を発見した.
解決策に従ってやっと変更され、手動で作成する必要があります.
以上、やっと様々なグーグルでapschedulerモジュールの問題を解決しました.次に、フォント、ピクチャ、jsonデータをexeファイルにパッケージしたいと思っています.公式サイトの紹介に従って、コマンドラインにパラメータを追加したり、specファイルを修正したりすればいいです.specファイルを生成するには
ここでdatas=[....]の内容は追加のデータファイルで、tupleの前項はソースファイルのパスで、後項はファイルがexe bundleの中の相対的なパスで、うん、今は簡単で、問題はプログラムの中でどのようにbundleの中のファイルを使って、どのようにソースプログラムを変更しないで、それではプログラムが読むたびにやはりソースファイルで、exeファイルとそのフォルダを一緒に置かなければならないことです.これは私の目的ではありません.私はexeがどこへ行っても一人で実行できるようにしたいと思っています.他の人に頼らないで、私と同じです.
どうしよう?公式サイトからヒントが出てきて、何度も繰り返し見てやっと分かりました.Googleがありますが、基本的には公式サイトの言葉ですが、この例はいいですね.公式サイトには、ファイルがfrozenとfrozenでないときにいくつかのパラメータがそれぞれどのようなパスであるかを示す例があります.自分でテイクアウトしてみたら、納得.exeが実行するときにtempフォルダが作成され、パッケージされたデータの親ディレクトリがこのtempフォルダであり、公式サイトの例によって親ディレクトリのpathが得られ、os.path.joinは同じでいいので、外部からexeにパッケージされたデータファイルはすべてjoinしなければならないことに注意してください.最終的なコードは以下の通りで、興味のある学生は前のものと比較することができます.
最後にパッケージされたexeファイル33 M程度は、20 M以上のフォント、ピクチャファイルが含まれているので、総じて納得できます.もちろんtkinterでインタフェースを作ることもできますが、間隔を設定したり、背景画像やフォントを増やしたりして、暇があれば話しましょう.
この文章では、以上のpythonプログラムをpyinstallerでexeにパッケージ化し、他人に共有しやすくし、嫉妬や憎しみをうらやましがらせる方法について議論します.
まずpythonプログラムをexeに変換し、よく使われるのはpyinstaller、py 2 exe、nuitkaです.最後のnuitkaはpythonコードをc++コードに変換してからexeファイルをコンパイルして生成し、実行効率が大幅に向上します.py 2 exeはプラットフォーム間で悪く、単一のexeファイルにパッケージできないと言われています.だからネット上の世論に基づいてpyinstallerを重点的に研究して、本文の重点と難点はパッケージタイミング実行モジュールapschedulerの時に多くの問題に出会って、同時にどのように使った画像、フォント、テキストなどのデータファイルをexeにパッケージします.
ソースプログラムは前のリンクを見てください.パッケージ化の過程で各モジュールのインポートの問題に遭遇しました.ここにはテクニックがあります.生成後のexeファイルが直接ダブルクリックして実行されると、エラーが発生した後、フラッシュして、エラー情報を見極めることができません.ソースコードにinput()を入れる人がいますが、実際にエラーが発生したときはinputを実行していないので、フラッシュしました.私は最初とても愚かで、windowsのスクリーンショットでその驚きの一瞥を残そうとしたが、何度も試しても成功しなかった.結局、これは目が速くて、自動スクリーンショットのスクリプトを書きたいほどだった.幸いなことに、後で知恵を絞って、もとはexeもcmdの中で直接ファイル名をたたいて運行することができて、このように間違いがあっても、雁が音を残して、跡があります.
さて、モジュールエラーの問題について、最初はapschedulerのhookファイルが少なくなったと思っていたので、ネット上でapschedulerのhookファイル(ページが長いので、自習して探しています)を見つけました.pyinstaller-F--additional-hooks-dir add_でhook set_wall_paper.pyはパッケージ化されていますが、生成されたexeファイルは依然としてエラーを報告しています.No trigger by the name「interval」was foundは、ネット上でsetuptoolsをアップグレードすると言っていますが、アップグレード後は役に立たないです.そこで探し続けると、すぐにIntervalTriggerというモジュールを導入し、プログラムヘッダに参加する必要があるという説があります.
from apscheduler.triggers import interval
実行後にエラーが発生しました:No module named'apscheduler.triggers.interval'は、グーグルを続け、stactoverflow上の解決方法を発見した.
解決策に従ってやっと変更され、手動で作成する必要があります.
trigger_interval = IntervalTrigger(seconds=60)
scheduler.add_job(set_wallpaper, args=(pic_files, poet_files, fonts_dir),
trigger=trigger_interval)
以上、やっと様々なグーグルでapschedulerモジュールの問題を解決しました.次に、フォント、ピクチャ、jsonデータをexeファイルにパッケージしたいと思っています.公式サイトの紹介に従って、コマンドラインにパラメータを追加したり、specファイルを修正したりすればいいです.specファイルを生成するには
pyi-makespec , pyinstaller 。 exe pyinstaller -F set_wall_paper.spec 。
でspecファイルを修正するのがより直感的で、簡単で、メモ帳で開きます.以下は修正後のspecファイルです.# -*- mode: python -*-
block_cipher = None
a = Analysis(['set_poet_wallpaper.py'],
pathex=['D:\\ \\PoetWallPaper'],
binaries=[],
datas=[('bgpics/*.jpg', 'bgpics'),
('mottos.json', '.'),
('fonts/*.ttf', 'fonts')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='set_poet_wallpaper',
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True )
ここでdatas=[....]の内容は追加のデータファイルで、tupleの前項はソースファイルのパスで、後項はファイルがexe bundleの中の相対的なパスで、うん、今は簡単で、問題はプログラムの中でどのようにbundleの中のファイルを使って、どのようにソースプログラムを変更しないで、それではプログラムが読むたびにやはりソースファイルで、exeファイルとそのフォルダを一緒に置かなければならないことです.これは私の目的ではありません.私はexeがどこへ行っても一人で実行できるようにしたいと思っています.他の人に頼らないで、私と同じです.
どうしよう?公式サイトからヒントが出てきて、何度も繰り返し見てやっと分かりました.Googleがありますが、基本的には公式サイトの言葉ですが、この例はいいですね.公式サイトには、ファイルがfrozenとfrozenでないときにいくつかのパラメータがそれぞれどのようなパスであるかを示す例があります.自分でテイクアウトしてみたら、納得.exeが実行するときにtempフォルダが作成され、パッケージされたデータの親ディレクトリがこのtempフォルダであり、公式サイトの例によって親ディレクトリのpathが得られ、os.path.joinは同じでいいので、外部からexeにパッケージされたデータファイルはすべてjoinしなければならないことに注意してください.最終的なコードは以下の通りで、興味のある学生は前のものと比較することができます.
# -*- coding: utf-8 -*-
"""
Created on Wed Aug 15 11:30:56 2018
@author: xiaozhen
"""
import os, json, sys
from PIL import Image, ImageFont, ImageDraw
import win32api
import win32con
import win32gui
import random
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.interval import IntervalTrigger
def reformat(string):
string_lst = string.splitlines()
format_string = []
for line in string_lst:
for i in range(len(line)//25+1):
format_string.append(line[i*25:25*(i+1)])
return '
'.join(format_string)
def set_wallpaper_from_bmp(bmp_path):
#
reg_key = win32api.RegOpenKeyEx(
win32con.HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, win32con.KEY_SET_VALUE)
# :2 ,0 ,6 ,10 ,0
win32api.RegSetValueEx(reg_key, "WallpaperStyle", 0, win32con.REG_SZ, "2")
# :1 , 0
win32api.RegSetValueEx(reg_key, "TileWallpaper", 0, win32con.REG_SZ, "0")
#
win32gui.SystemParametersInfo(
win32con.SPI_SETDESKWALLPAPER, bmp_path, win32con.SPIF_SENDWININICHANGE)
def random_poems(poet_files):
poet_file = random.choice(poet_files)
with open(poet_file, 'r', encoding='utf-8') as json_file:
poems = json.load(json_file)
# preferred_poets = (' ', ' ', ' ')
# for i in range(1000):
# poem = random.choice(poems)
# if poem['author'] in preferred_poets:
# break
poem = random.choice(poems)
poem_content = poem['paragraphs'][0]
poem['paragraphs'] = [reformat(poem_content)]
poem_string = '
'.join([poem['title'], poem['author']] + poem['paragraphs'])
return poem_string
def set_wallpaper(img_files, poem_files, fonts_dir):
# bmp ,
img_path = random.choice(img_files)
img_dir = os.path.dirname(img_path)
bmpImage = Image.open(img_path)
bmpImage = bmpImage.resize((1920, 1080), Image.ANTIALIAS)
draw = ImageDraw.Draw(bmpImage)
font = random.choice([os.path.join(fonts_dir, file)
for file in os.listdir(fonts_dir)])
print(font)
fnt = ImageFont.truetype(font, 40)
poem_str = random_poems(poem_files)
print(poem_str)
width, height = bmpImage.size
draw.multiline_text((width/4, height/5), poem_str, fill='#000000',
font=fnt, anchor='center', spacing=10, align="center")
new_bmp_path = os.path.join(img_dir, 'wallpaper.bmp')
bmpImage.save(new_bmp_path, "BMP")
set_wallpaper_from_bmp(os.path.abspath(new_bmp_path))
if __name__ == '__main__':
if getattr(sys, 'frozen', False):
# we are running in a bundle
bundle_dir = sys._MEIPASS
else:
# we are running in a normal Python environment
bundle_dir = os.path.dirname(os.path.abspath(__file__))
pic_path = os.path.join(bundle_dir, 'bgpics')
pic_files = [os.path.join(pic_path, file) for file in os.listdir(pic_path)
if 'wallpaper' not in file]
poet_files = [os.path.join(bundle_dir, 'mottos.json')]
fonts_dir = os.path.join(bundle_dir, 'fonts')
set_wallpaper(pic_files, poet_files, fonts_dir)
scheduler = BlockingScheduler()
trigger_interval = IntervalTrigger(seconds=60)
scheduler.add_job(set_wallpaper, args=(pic_files, poet_files, fonts_dir),
trigger=trigger_interval) #
# scheduler.add_job(set_wallpaper, args=(pic_files, poet_files,),
# trigger='interval', seconds=60) #
scheduler.start()
最後にパッケージされたexeファイル33 M程度は、20 M以上のフォント、ピクチャファイルが含まれているので、総じて納得できます.もちろんtkinterでインタフェースを作ることもできますが、間隔を設定したり、背景画像やフォントを増やしたりして、暇があれば話しましょう.