我使用 pyinstaller 和 Inno 编译了一个桌面应用程序,但在上传 pdf 文档时始终存在问题。当该应用程序安装在其他Windows PC上时,除了上传要存储在sqlite数据库中的pdf文档的功能之外,所有功能都可以正常运行。但是当应用程序安装在编译它的PC上时,所有功能都可以工作。我还使用 --hidden-imports 作为 pyinstaller --hidden-import PyPDF2 --hidden-import pdfplumber --hidden-import Pillow The_Hr.py 但这从未解决问题。
我多次尝试编辑下面的代码摘录,但似乎没有任何效果,请问有什么帮助吗?
from tkinter import ttk
from PIL import ImageTk
import base64
import io
from tkinter import *
import tkinter.messagebox
import datetime
from datetime import date, datetime, timedelta
from dateutil.relativedelta import relativedelta
import time
import os
import sqlite3
from time import strftime, localtime
import re # for date validation
from pdf2image import convert_from_path
from PyPDF2 import PdfReader
from tkinter import Tk, filedialog, simpledialog
from concurrent.futures import ThreadPoolExecutor
from PIL import Image
from db_init import initialize_database
import logging
logging.captureWarnings(True)
# Initialize the database connection pool
db_pool = initialize_database()
# Configure logging
logging.basicConfig(filename='app.log', level=logging.DEBUG)
def employee_documents(access_level):
for widget in right_Frame.winfo_children():
widget.destroy()
for widget in bottom_Frame.winfo_children():
widget.destroy()
# Remove the lagging and leading spaces of access_level
access_level = access_level.strip()
# Variables
period = StringVar()
process_date = StringVar()
emp_id = StringVar()
emp_name = StringVar()
doc_name = StringVar()
doc_number = StringVar()
category = StringVar()
document_search = StringVar()
def display_calendar_list():
try:
# Clear the existing calendar list
e_date['values'] = ()
# Get the selected period and extract the year and month
selected_period = period.get()
selected_month, selected_year = selected_period.split('-')
selected_month = datetime.strptime(selected_month, '%b').month
selected_year = int(selected_year)
# Get the list of dates for the selected month and year
calendar_dates = create_calendar_list(selected_year, selected_month)
# Display the dates in the ComboBox
formatted_dates = [date_obj.strftime('%Y-%m-%d') for date_obj in calendar_dates]
e_date['values'] = tuple(formatted_dates)
except tkinter.TclError as e:
error_message = f'Error inserting data: {str(e)}'
tkinter.messagebox.showerror('Error', error_message)
raise ValueError(error_message)
def on_period_change(event):
display_calendar_list()
current_document_data = None
current_document_category = None
current_zoom = 0.2
current_pages = None
# Define the canvas as a global variable
canvas = None
# get period from payroll table
with db_pool.connection() as conn:
cursor = conn.cursor()
result1 = cursor.execute("SELECT period_month FROM payroll_period WHERE LOWER(status) ='open'
").fetchall()
result2 = cursor.execute("SELECT employee_id FROM employees WHERE LOWER(status) !='inactive'
").fetchall()
period_list = [row[0] for row in result1]
if not period_list:
period_list = ['Empty List']
id_list = [row[0] for row in result2]
if not id_list:
id_list = ['Empty List']
def update_fields(event):
selected_value = e_emp_id.get()
with db_pool.connection() as conn:
cursor = conn.cursor()
result3 = cursor.execute(
"SELECT employee_name, identity_no, shif_NO, nssf_NO, kra_PIN FROM employee_details"
" WHERE employee_id =? ", (selected_value,)).fetchone()
name_result = result3[0] # Accessing the first item in the tuple
stat_result = [result3[1], result3[2], result3[3], result3[4]]
# Update the 'e_emp_name' field
e_emp_name.delete(0, END)
e_emp_name.insert(0, name_result)
# Create a dictionary for documents
statutory_dictionary = {
'ID': [stat_result[0]],
'NHIF': [stat_result[1]],
'NSSF': [stat_result[2]],
'KRA PIN': [stat_result[3]],
'CV': ['CV'],
'Academics': ['Academics']
}
# update doc_name
e_doc_name['values'] = list(statutory_dictionary.keys())
# update doc_number
doc_name_select = e_doc_name.get()
if doc_name_select:
e_doc_number.delete(0, END)
e_doc_number.insert(0, statutory_dictionary[doc_name_select])
# Function to convert PDF document to images
def convert_document_to_image(document_path):
try:
if document_path.lower().endswith('.pdf'):
# Check if the file exists
if not os.path.isfile(document_path):
raise FileNotFoundError("File does not exist.")
# Convert PDF pages to images
images = convert_from_path(document_path, dpi=150) # Adjust DPI as needed
# Convert images to byte arrays
img_byte_arrays = []
for image in images:
byte_array = io.BytesIO()
image.save(byte_array, format='JPEG')
img_byte_arrays.append(byte_array.getvalue())
return img_byte_arrays
else:
raise ValueError("Only PDF documents are supported.")
except Exception as e:
# Log the error
logging.error(f"Error converting document {document_path}: {e}")
tkinter.messagebox.showerror("Error", str(e))
return None
# Number of threads to use for parallel conversion
NUM_THREADS = 4
# Initialize the counts and size variables
current_category_counts = {"Statutory": 0, "Academics": 0, "CV": 0}
total_size = 0
# Define the maximum number of documents per category
max_documents_per_category = {"Statutory": 5, "Academics": 3, "CV": 1}
current_zoom = 0.2
# Get the current working directory (where your Python script is located)
current_directory = os.getcwd()
# Set the relative path for the desktop directory
desktop_directory = os.path.join(current_directory, "Desktop")
# Function to open file dialog for selecting a file
def browse_file():
document_path_entry.insert(0, filedialog.askopenfilename(initialdir=desktop_directory))
# Adjusted insert function
def insert_document(event=None):
document_path = document_path_entry.get()
with ThreadPoolExecutor(max_workers=NUM_THREADS) as executor:
document_data = list(executor.map(convert_document_to_image, [document_path]))
if document_data is None or len(document_data) == 0:
logging.error("Conversion failed or document data is empty.")
return
selected_category = category.get()
max_size_per_category = 25 # MB
max_size_per_page = 5 # MB
total_data_size = sum(len(data) for data in document_data)
if (current_category_counts.get(selected_category, 0) <
max_documents_per_category[selected_category] and
total_data_size <= max_size_per_category * 1024 * 1024):
try:
with db_pool.connection() as conn:
cursor = conn.cursor()
combined_data = b''.join(document_data[0])
cursor.execute("INSERT INTO employee_documents "
"(period, process_date, emp_id, emp_name, "
"doc_name, doc_number, "
"category, document_data) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
(period.get(), process_date.get(), emp_id.get(), emp_name.get(),
doc_name.get(), doc_number.get(), selected_category,
combined_data))
current_category_counts[selected_category] += 1
conn.commit()
clear_entries()
display_data()
display_document(document_data, category, current_zoom)
except Exception as e:
logging.exception("Error occurred during document insertion:")
tkinter.messagebox.showerror("Error", "Failed to insert document into the database.")
else:
tkinter.messagebox.showerror(f"Maximum document size exceeded for category:
{selected_category}")
# browse label
browse_label = Label(right_Frame, text="Browse Path:", font=('cambria', 11), bg='Grey', anchor=W)
browse_label.grid(row=2, column=4, sticky=W, pady=2, padx=2)
# browse button
browse_button = Button(right_Frame, text="Browse", font=('cambria', 10, 'bold'), bg='dimgray',
relief=FLAT, width=19, command=browse_file)
browse_button.grid(row=2, column=5)
# insert button
insert_button = Button(right_Frame, text="Insert Doc", font=('cambria', 11, 'bold'), bg='dimgray',
relief=FLAT, width=17, command=insert_document)
insert_button.grid(row=4, column=5)
```
这很难回答,我们需要 MRE:https://stackoverflow.com/help/minimal-reproducible-example
一些猜测:
请粘贴 Inno Setup 脚本,以便我们可以看到安装程序实际在做什么。