ด้วยคำตอบที่ยอดเยี่ยมจากMaxและโพสต์นี้เกี่ยวกับการเพิ่มไฟล์ข้อมูลพิเศษเช่นรูปภาพหรือเสียงและการวิจัย / การทดสอบของฉันเองฉันพบว่าสิ่งที่ฉันเชื่อว่าเป็นวิธีที่ง่ายที่สุดในการเพิ่มไฟล์ดังกล่าว
หากคุณต้องการดูตัวอย่างจริงที่เก็บของฉันอยู่ที่ GitHub
หมายเหตุ: ใช้สำหรับการคอมไพล์โดยใช้คำสั่ง--onefile
or -F
กับ pyinstaller
สภาพแวดล้อมของฉันมีดังนี้
การแก้ปัญหาใน 2 ขั้นตอน
ในการแก้ปัญหานี้เราจำเป็นต้องบอก Pyinstaller โดยเฉพาะว่าเรามีไฟล์พิเศษที่ต้อง "รวม" กับแอปพลิเคชัน
เราจำเป็นต้องใช้เส้นทาง 'สัมพัทธ์'ด้วยดังนั้นแอปพลิเคชันจึงสามารถทำงานได้อย่างถูกต้องเมื่อทำงานเป็น Python Script หรือ Frozen EXE
ด้วยเหตุนี้เราจึงต้องการฟังก์ชันที่ช่วยให้เรามีพา ธ สัมพัทธ์ การใช้ฟังก์ชั่นที่Max โพสต์เราสามารถแก้ปัญหาเส้นทางสัมพัทธ์ได้อย่างง่ายดาย
def img_resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
เราจะใช้ฟังก์ชันข้างต้นเช่นนี้เพื่อให้ไอคอนแอปพลิเคชันปรากฏขึ้นเมื่อแอปทำงานเป็นสคริปต์หรือ Frozen EXE
icon_path = img_resource_path("app/img/app_icon.ico")
root.wm_iconbitmap(icon_path)
ขั้นตอนต่อไปคือเราต้องสั่งให้ Pyinstaller ทราบว่าจะหาไฟล์พิเศษได้ที่ไหนเมื่อทำการคอมไพล์เพื่อที่ว่าเมื่อแอปพลิเคชันถูกเรียกใช้งานจะถูกสร้างขึ้นในไดเร็กทอรี temp
เราสามารถแก้ปัญหานี้ได้สองวิธีดังที่แสดงในเอกสารแต่โดยส่วนตัวแล้วฉันชอบจัดการไฟล์. spec ของตัวเองดังนั้นเราจะทำอย่างไร
ขั้นแรกคุณต้องมีไฟล์. spec อยู่แล้ว ในกรณีของฉันฉันก็สามารถที่จะสร้างสิ่งที่ฉันต้องการโดยการทำงานpyinstaller
กับ args พิเศษคุณสามารถค้นหา args พิเศษที่นี่ ด้วยเหตุนี้ไฟล์ข้อมูลจำเพาะของฉันอาจดูแตกต่างจากของคุณเล็กน้อย แต่ฉันโพสต์ทั้งหมดเพื่ออ้างอิงหลังจากที่ฉันอธิบายบิตที่สำคัญ
added_filesเป็นรายการที่มี Tuple เป็นหลักในกรณีของฉันฉันแค่ต้องการเพิ่มภาพ SINGLE แต่คุณสามารถเพิ่ม ico, png หรือ jpgได้หลายรายการโดยใช้('app/img/*.ico', 'app/img')
คุณสามารถสร้าง tuple อื่นได้เช่นกันเพื่อadded_files = [ (), (), ()]
ให้มีการนำเข้าหลายรายการ
ส่วนแรกของทูเพิลจะกำหนดไฟล์หรือประเภทของไฟล์ที่คุณต้องการเพิ่มรวมถึงตำแหน่งที่จะค้นหา คิดว่านี่คือ CTRL + C
ส่วนที่สองของ tuple บอกให้ Pyinstaller สร้างพา ธ 'app / img /' และวางไฟล์ในไดเร็กทอรีนั้นสัมพันธ์กับไดเร็กทอรี temp ใด ๆ ที่สร้างขึ้นเมื่อคุณเรียกใช้. exe คิดว่านี่คือ CTRL + V
ภายใต้a = Analysis([main...
ฉันตั้งไว้datas=added_files
แต่เดิมเคยเป็นdatas=[]
แต่เราต้องการให้รายการการนำเข้าเป็นอย่างดีนำเข้าดังนั้นเราจึงส่งผ่านการนำเข้าที่กำหนดเองของเรา
คุณไม่จำเป็นต้องทำเช่นนี้ถ้าคุณต้องการไอคอนที่เฉพาะเจาะจงสำหรับ EXE ที่ด้านล่างของแฟ้มข้อมูลจำเพาะฉันบอก Pyinstaller การตั้งค่าไอคอนโปรแกรมของฉันสำหรับ exe icon='app\\img\\app_icon.ico'
ที่มีตัวเลือก
added_files = [
('app/img/app_icon.ico','app/img/')
]
a = Analysis(['main.py'],
pathex=['D:\\Github Repos\\Processes-Killer\\Process Killer'],
binaries=[],
datas=added_files,
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='Process Killer',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True , uac_admin=True, icon='app\\img\\app_icon.ico')
กำลังคอมไพล์ไปที่ EXE
ฉันขี้เกียจมาก ฉันไม่ชอบพิมพ์อะไรมากกว่าที่ฉันต้องทำ ฉันได้สร้างไฟล์. bat ที่ฉันสามารถคลิกได้ คุณไม่ต้องทำเช่นนี้รหัสนี้จะทำงานในเชลล์พรอมต์คำสั่งโดยไม่ต้องใช้มัน
เนื่องจากไฟล์. spec มีการตั้งค่าและการคอมไพล์ทั้งหมดของเรา (aka option) เราจึงต้องให้ไฟล์. spec นั้นแก่ Pyinstaller
pyinstaller.exe "Process Killer.spec"
a.datas += ...
) ช่วยฉันได้จริงๆ เอกสาร pyinstaller พูดถึงการใช้งานCOLLECT
แต่ล้มเหลวในการใส่ไฟล์ลงในไบนารีเมื่อใช้--onefile