将.py编译为.exe时出现问题

2024-06-16 11:55:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用pyinstaller将.py文件编译为.exe文件,但我总是在终端中收到以下警告:

c:\users\cpuhv\appdata\local\programs\python\python39\lib\site-packages\setuptools\distutils_patch.py:25: UserWarning: Distutils was imported before Setuptools. This u
sage is discouraged and may exhibit undesirable behaviors or errors. Please use Setuptools' objects directly or at least import Setuptools first.
  warnings.warn(

当我尝试运行.exe文件时,会出现一个警告窗口,其中的文本为:“无法执行脚本”

有人知道如何解决这个问题吗


Tags: or文件py终端警告liblocalexe
3条回答
import sys
import os
import comtypes.client
from pdf2docx import Converter
from docx2pdf import convert
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QToolTip, QFileDialog, QLineEdit, QLabel
from PyQt6.QtGui import QIcon, QFont
from pathlib import Path


home_directory = str(Path.home()).replace("/", "\\")


def name(file):
    path = file
    i = 1
    while os.path.exists(path):
        path = file
        path += " " + str(i)
        i += 1
    return path


class MainGui(QWidget):
    def __init__(self):
        super().__init__()

        self.row1 = 50
        self.row2 = 100
        self.row3 = 175
        self.row4 = 260

        self.button_font = QFont('Verdana', 10)
        self.line = QLineEdit(self)
        self.browse = QPushButton("Durchsuchen", self)
        self.selected_files_count = QLabel("0 Elemente ausgewählt", self)
        self.docx_files = []
        self.pdf_files = []
        self.init_me()

    def init_me(self):
        font = QFont('Verdana', 8)
        font.setBold(True)
        QToolTip.setFont(font)

        pdf_to_docx_button = QPushButton('PDF Dateien auswählen', self)
        pdf_to_docx_button.setFont(self.button_font)
        pdf_to_docx_button.setToolTip('öffen Sie einen Datei-Dialog, um Dateien auszuwählen')
        pdf_to_docx_button.move(50, self.row1)
        pdf_to_docx_button.setFixedWidth(200)
        pdf_to_docx_button.setFixedHeight(35)
        pdf_to_docx_button.clicked.connect(self.pdf_to_docx_button_pressed)

        docx_to_pdf_button = QPushButton('DOCX Dateien auswählen', self)
        docx_to_pdf_button.setFont(self.button_font)
        docx_to_pdf_button.setToolTip('öffen Sie einen Datei-Dialog, um Dateien auszuwählen')
        docx_to_pdf_button.move(300, self.row1)
        docx_to_pdf_button.setFixedWidth(200)
        docx_to_pdf_button.setFixedHeight(35)
        docx_to_pdf_button.clicked.connect(self.docx_to_pdf_button_pressed)

        self.line.move(50, self.row3)
        self.line.setFixedWidth(320)
        self.line.setFixedHeight(30)
        self.line.setFont(self.button_font)
        self.line.setText(home_directory)

        self.browse.move(390, self.row3)
        self.browse.setFont(self.button_font)
        self.browse.setFixedWidth(110)
        self.browse.setFixedHeight(30)
        self.browse.setToolTip('öffen Sie einen Datei-Dialog, um den Ausgabe-Ordner auszuwählen')
        self.browse.clicked.connect(self.browse_button_pressed)

        convert_button = QPushButton('Konvertieren', self)
        convert_button.move(190, self.row4)
        convert_button.setFixedWidth(170)
        convert_button.setFixedHeight(50)
        convert_button.setFont(self.button_font)
        convert_button.clicked.connect(self.convert)

        self.selected_files_count.move(200, self.row2)
        self.selected_files_count.setFont(self.button_font)
        self.selected_files_count.setFixedSize(200, 50)

        self.move(50, 50)
        self.setFixedSize(550, 400)
        self.setWindowTitle("Konverter")
        self.setWindowIcon(QIcon(r"icon.png"))
        self.show()

    def pdf_to_docx_button_pressed(self):
        fd = QFileDialog()
        fd.setAcceptMode(QFileDialog.AcceptMode.AcceptOpen)
        path = fd.getOpenFileNames(self, "PDF Dateien öffnen", home_directory, "PDF (*.pdf)")
        fd.close()
        print(len(path[0]))
        if len(path[0]) > 0:
            self.pdf_files.extend(path[0])
            print(True)
            self.update_label()

    def docx_to_pdf_button_pressed(self):
        fd = QFileDialog()
        fd.setAcceptMode(QFileDialog.AcceptMode.AcceptOpen)
        path = fd.getOpenFileNames(self, "Docx Dateien öffnen", home_directory, "Word-Dokument ("
                                                                                                  "*.docx)")
        fd.close()
        if len(path[0]) > 0:
            self.docx_files.extend(path[0])
            self.update_label()

    def convert(self):
        directory = self.line.text()
        if not os.path.exists(directory):
            return
        if not os.path.isdir(directory):
            return
        for file in self.pdf_files:
            docx_file = name(directory + "/" + os.path.basename(file).replace(".pdf", ".docx"))
            convert_pdf_to_docx(file, docx_file)
            update_docx(docx_file)
        for file in self.docx_files:
            convert_docx_to_pdf(file, name(directory + "/" + os.path.basename(file).replace(".docx", ".pdf")))
        self.docx_files = []
        self.pdf_files = []

    def browse_button_pressed(self):
        fd = QFileDialog()
        fd.setAcceptMode(QFileDialog.AcceptMode.AcceptSave)
        path = fd.getExistingDirectory(self, "Ausgabeordner auswählen", home_directory)
        if path is not None and not len(path) <= 0:
            self.line.setText(path)

    def update_label(self):
        count = len(self.pdf_files) + len(self.docx_files)
        if count != 1:
            self.selected_files_count.setText(str(count) + " Elemente ausgewählt")
        else:
            self.selected_files_count.setText("ein Element ausgewählt")


def convert_pdf_to_docx(pdf_file, docx_file):
    cv = Converter(pdf_file)
    cv.convert(docx_file, start=0, end=None)
    cv.close()


def convert_docx_to_pdf(docx_file, pdf_file):
    convert(docx_file, pdf_file)


def update_docx(file):
    docx_format_name = 16
    file_in = os.path.abspath(file)
    file_out = file_in.replace(".docx", "2.docx")
    word_application = comtypes.client.CreateObject('word.Application')
    if word_application is not None:
        doc = word_application.Documents.Open(file_in)
        doc.SaveAs(file_out, FileFormat=docx_format_name)
        doc.Close()
        word_application.Quit()
        os.remove(file_in)
        os.rename(file_out, file_in)


app = QApplication(sys.argv)

w = MainGui()

sys.exit(app.exec())

这是我的密码

命令是:

pyinstaller --noconfirm --onefile --windowed  "C:/Users/cpuhv/Documents/Projekte/Python/Python Test/PDFConverter.py"

所以我昨天也有类似的问题。我有一个变通方法,允许程序运行,但不能作为一个文件运行。不幸的是,这也会使文件夹变大,因为它将包含所有虚拟环境包。我希望其他人能给你一个更好的答案

首先,调试时不要使用--windowed。忽略--窗口化,然后使用命令行运行.exe。这将为您显示错误。在这种情况下:

  Traceback (most recent call last):
  File "main.py", line 6, in <module>
  File "PyInstaller\loader\pyimod03_importers.py", line 531, in exec_module
  File "docx2pdf\__init__.py", line 13, in <module>
  File "importlib\metadata.py", line 551, in version
  File "importlib\metadata.py", line 524, in distribution
  File "importlib\metadata.py", line 187, in from_name
importlib.metadata.PackageNotFoundError: docx2pdf
[6860] Failed to execute script main

我们看到一个导入错误,因为Pyinstaller不考虑二级导入。在这种情况下,我相信docx2pdf有自己的导入列表。看看钩子和导入错误,有很多解决方案——但是我个人无法用我读到的解决方案获得结果

因此,我为您提供的替代“bandaid”解决方案要求您使用.spec文件。 运行Pyinstaller --noconfirm main.py 接下来,您需要编辑在工作目录中生成的main.spec文件。 将site packages文件夹添加到数据中,使其如下所示:

datas=[('C:\\PathToProjectFolder\\venv\\Lib\\site-packages', '.')]

并将.spec文件中的控制台行编辑为:console=False(单击.exe时隐藏控制台)

使用更新的.spec文件,我们可以再次运行Pyinstaller,这次输入:

pyinstaller --noconfirm main.spec

请注意main.spec,而不是main.py

dist文件夹中的.exe现在应该运行。祝你好运,找到一个更好的解决方案,不会使你的文件夹过大

我为你找到了解决办法。一个文件和所有。我留下我以前的答案,尽管它并不理想,但它可能会对某人有所帮助

按照此处的说明操作:https://github.com/AlJohri/docx2pdf/issues/5

pyinstaller is missing hook script to run docx2pdf.

save hook-docx2pdf.py to \Lib\site-packages\PyInstaller\hooks, Copy the text below in:

from PyInstaller.utils.hooks import collect_all

hiddenimports = collect_all('docx2pdf')

之后我不得不退出并重新启动PyCharm,但这修复了与docx2pdf导入问题相关的所有错误

在那之后,我遇到了很多与PyQt相关的错误。我过去在PyQt和Pyinstaller的合作中遇到过麻烦

但是,如果您从PyQt6降级到PyQt5,所有问题都会得到解决。 然后只需将导入列表更改为从PyQt5导入即可

然后运行pyinstaller --onefile -w main.py

Pyinstaller和PyQt6似乎还不完全兼容

如果这是有效的,我将不胜感激,如果你能将此标记为已接受的答案

相关问题 更多 >