由pyinstaller和Inno编译的桌面应用程序设置仅在编译应用程序的PC上上传pdf文档

问题描述 投票:0回答:1

我使用 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)

            ```
pdf pyinstaller inno-setup image-conversion sqlite3-python
1个回答
0
投票

这很难回答,我们需要 MRE:https://stackoverflow.com/help/minimal-reproducible-example

一些猜测:

  • 您的 Inno 安装脚本缺少一些文件,因此当安装程序在不同的计算机上运行时,Python 应用程序可以工作,但 PDF 导出失败
  • 这个丢失的文件可能是一些本地库(例如用于 PDF 导出的 .dll 文件)
  • 或者某些依赖项完全丢失 - 就像您需要运行一些第 3 方依赖项设置来安装 PDF 导出
  • 目标计算机上未安装 Python 或 Python 缺少某些功能(PDF 导出)

请粘贴 Inno Setup 脚本,以便我们可以看到安装程序实际在做什么。

© www.soinside.com 2019 - 2024. All rights reserved.