1131023
-打包檔案
pyinstaller --onefile --windowed --add-data "image.png;." your_script.py
--onefile:這個選項會將所有檔案打包成一個可執行檔案。
--windowed:這個選項會禁止顯示命令提示字元窗口(適用於 GUI 應用)。
-修正打包後路徑問題
在 tk.PhotoImage(file="image.png") 中,直接使用相對路徑會在打包後的執行中遇到問題,因為 PyInstaller 將檔案放置在臨時資料夾中。因此,我們需要使用一個函數來正確獲取資源檔案的路徑。
添加 resource_path 函數:這個函數會根據是否打包來決定檔案的實際路徑。
使用 resource_path 來加載圖片:將圖片路徑傳入 tk.PhotoImage。
以下是修正後的程式碼:
import os
import sys
import tkinter as tk
from tkinter import messagebox, ttk, PhotoImage
import win32print
def resource_path(relative_path):
"""獲取資源的絕對路徑,不論是在開發環境還是被打包後"""
try:
# PyInstaller 建立一個臨時資料夾,並將路徑存於 _MEIPASS
base_path = sys._MEIPASS
except AttributeError:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def get_printers():
"""獲取已安裝的印表機列表"""
printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)
return [printer[2] for printer in printers]
def set_default_printer(printer_name):
"""設置預設印表機"""
try:
win32print.SetDefaultPrinter(printer_name)
update_default_printer_label() # 更新標籤顯示
messagebox.showinfo("成功", f"{printer_name} 已設為預設印表機")
except Exception as e:
messagebox.showerror("錯誤", f"無法設置預設印表機: {str(e)}")
def update_default_printer_label():
"""更新顯示當前預設印表機的標籤"""
default_printer = win32print.GetDefaultPrinter()
default_printer_label.config(text=f"當前預設印表機: {default_printer}")
def on_set_default():
"""當按鈕被點擊時的處理函數"""
selected_printer = printer_combobox.get()
if selected_printer and selected_printer != "選擇印表機":
set_default_printer(selected_printer)
else:
messagebox.showwarning("警告", "請先選擇印表機")
# 建立主窗口
root = tk.Tk()
root.title("班級及科任印表機管理工具 by WCS 2024.10.07")
root.geometry("650x300") # 設定窗口大小為 650x300
# 獲取印表機列表
printers = get_printers()
# 創建下拉選單
printer_combobox = ttk.Combobox(root, values=printers)
printer_combobox.set("選擇印表機")
# 設定字體屬性
printer_combobox['justify'] = 'center' # 文字置中
printer_combobox.configure(font=('Arial', 18)) # 字型和大小
# 改變 Combobox 的樣式
style = ttk.Style()
style.configure("TCombobox", foreground="red") # 字體顏色設為紅色
printer_combobox.pack(pady=30, fill=tk.X) # 設置為填滿窗口寬度
# 創建顯示當前預設印表機的標籤
default_printer_label = tk.Label(root, text="", font=("Arial", 18), fg="blue")
default_printer_label.pack(pady=5)
update_default_printer_label() # 初始化顯示當前預設印表機
# 創建按鈕
set_default_button = tk.Button(root, text="設為預設印表機", command=on_set_default, font=("Arial", 18), fg="orange")
set_default_button.pack(pady=10)
# 新增備註標籤
note_label = tk.Label(root, text="by 資訊組 FSPS-新北市中和區復興國小", font=("Arial", 10), fg="black")
note_label.place(relx=0.99, rely=0.99, anchor='se') # 右下角對齊
# 載入並顯示圖片
img_path = resource_path("image.png") # 使用 resource_path 獲取正確路徑
original_image = tk.PhotoImage(file=img_path) # 替換為你的圖片檔名
image = original_image.subsample(4, 4) # 調整大小,這裡將圖片縮小為原來的 1/4
image_label = tk.Label(root, image=image)
image_label.place(relx=0.01, rely=0.99, anchor='sw') # 左下角對齊
# 啟動主循環
root.mainloop()
-打包成一個檔,會路徑問題!
import tkinter as tk
from tkinter import messagebox, ttk
import win32print
def get_printers():
"""獲取已安裝的印表機列表"""
printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)
return [printer[2] for printer in printers]
def set_default_printer(printer_name):
"""設置預設印表機"""
try:
win32print.SetDefaultPrinter(printer_name)
update_default_printer_label() # 更新標籤顯示
messagebox.showinfo("成功", f"{printer_name} 已設為預設印表機")
except Exception as e:
messagebox.showerror("錯誤", f"無法設置預設印表機: {str(e)}")
def update_default_printer_label():
"""更新顯示當前預設印表機的標籤"""
default_printer = win32print.GetDefaultPrinter()
default_printer_label.config(text=f"當前預設印表機: {default_printer}")
def on_set_default():
"""當按鈕被點擊時的處理函數"""
selected_printer = printer_combobox.get()
if selected_printer and selected_printer != "選擇印表機":
set_default_printer(selected_printer)
else:
messagebox.showwarning("警告", "請先選擇印表機")
# 建立主窗口
root = tk.Tk()
root.title("班級及科任印表機管理工具 by WCS 2024.10.07")
root.geometry("650x300") # 設定窗口大小為 650x300
# 獲取印表機列表
printers = get_printers()
# 創建下拉選單
printer_combobox = ttk.Combobox(root, values=printers)
printer_combobox.set("選擇印表機")
# 設定字體屬性
printer_combobox['justify'] = 'center' # 文字置中
printer_combobox.configure(font=('Arial', 18)) # 字型和大小
# 改變 Combobox 的樣式
style = ttk.Style()
style.configure("TCombobox", foreground="red") # 字體顏色設為紅色
printer_combobox.pack(pady=30, fill=tk.X) # 設置為填滿窗口寬度
# 創建顯示當前預設印表機的標籤
default_printer_label = tk.Label(root, text="", font=("Arial", 18), fg="blue")
default_printer_label.pack(pady=5)
update_default_printer_label() # 初始化顯示當前預設印表機
# 創建按鈕
set_default_button = tk.Button(root, text="設為預設印表機", command=on_set_default, font=("Arial", 18), fg="orange")
set_default_button.pack(pady=10)
# 新增備註標籤
note_label = tk.Label(root, text="by 資訊組 FSPS-新北市中和區復興國小", font=("Arial", 10), fg="black")
note_label.place(relx=0.99, rely=0.99, anchor='se') # 右下角對齊
# 載入並顯示圖片
original_image = tk.PhotoImage(file="image.png") # 替換為你的圖片檔名
image = original_image.subsample(4, 4) # 調整大小,這裡將圖片縮小為原來的 1/4
image_label = tk.Label(root, image=image)
image_label.place(relx=0.01, rely=0.99, anchor='sw') # 左下角對齊
# 啟動主循環
root.mainloop()