Nuitka打包制作exe桌面软件

文摘   2024-10-01 14:56   上海  

Nuitka打包

numpypandasPyQt5

简介

基于Nuitak的PyQt5打包,优势在于将 Python 代码编译成 C/C++ 代码,代码混淆降低被篡改和盗用的风险

环境配置

打开mingw下载页面地址https://sourceforge.net/projects/mingw-w64/,下载后的到压缩包,解压放到C盘,并添加环境变量到

下载
移动到C盘
编辑环境变量

打开cmd,测试是否能够识别到gcc

测试gcc

下载numpy精简版,打开网址https://pypi.funzilla.net/,搜索numpy+Vanilla,选择python3.8的amd64位版本

激活conda环境,安装必要库pip install nuitka==2.0 pandas==1.5 E:\Downloads\numpy-1.22.4+vanilla-cp38-cp38-win_amd64.whl

打包示例

本项目在python3.8下通过测试,所用的库为pandas,PyQt5,openpyxl,示例代码如下

import sys
import pandas as pd
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QVBoxLayout, QHBoxLayout,
                             QFileDialog, QLabel, QLineEdit, QTextEdit, QWidget, QTableView)
from PyQt5.QtCore import QAbstractTableModel, Qt
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QHeaderView

class PandasModel(QAbstractTableModel):
    """A model to interface between a pandas DataFrame and a Qt TableView."""

    def __init__(self, df=pd.DataFrame(), parent=None):
        QAbstractTableModel.__init__(self, parent=parent)
        self._df = df

    def rowCount(self, parent=None):
        return self._df.shape[0]

    def columnCount(self, parent=None):
        return self._df.shape[1]

    def data(self, index, role=Qt.DisplayRole):
        if index.isValid():
            if role == Qt.DisplayRole:
                return str(self._df.iat[index.row(), index.column()])
            elif role == Qt.BackgroundRole:
                return QColor(Qt.white)
        return None

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                return str(self._df.columns[section])
            if orientation == Qt.Vertical:
                return str(self._df.index[section])


class ExcelSearchApp(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('Excel 搜索工具')
        self.resize(1200, 900)

        # 创建主窗口的小部件
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        # 创建垂直布局
        layout = QVBoxLayout(self.central_widget)
        # 搜索栏
        self.search_layout = QHBoxLayout()
        self.search_label = QLabel('输入关键词:')
        self.search_input = QLineEdit()
        self.search_button = QPushButton('搜索')
        self.search_button.clicked.connect(self.search_keyword)
        self.search_layout.addWidget(self.search_label)
        self.search_layout.addWidget(self.search_input)
        self.search_layout.addWidget(self.search_button)
        layout.addLayout(self.search_layout)

        # 语言切换按钮
        self.language_button = QPushButton('切换到英文模式')
        self.language_button.clicked.connect(self.toggle_language)
        layout.addWidget(self.language_button)

        # 搜索结果表格
        self.table_view = QTableView()
        layout.addWidget(self.table_view)
        self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # 显示操作记录
        self.results_area = QTextEdit()
        self.results_area.setReadOnly(True)
        layout.addWidget(self.results_area)

        # 初始化 Excel 文件路径和搜索模式
        self.excel_file_path = None
        self.language_mode = 'Chinese'  # 初始为中文模式


    def search_keyword(self):
    
        keyword = self.search_input.text().strip()
        if not keyword:
            self.results_area.append("请输入关键词。")
            return

        df = pd.DataFrame({
            "中文": [
                '这是第1句中文',
                '这是第2句中文',
                '这是第3句中文',
                ],
            "英文":[
                'this is 1 sentence',
                'this is 2 sentence',
                'this is 3 sentence',
            ]})
        # 根据语言模式决定搜索的列(中文第一列,英文第二列)
        column_to_search = 0 if self.language_mode == 'Chinese' else 1

        # 遍历指定列,寻找包含关键词的单元格
        result_df=df[df.iloc[:,column_to_search].str.contains(keyword)]

        # 显示结果
        if result_df.shape[0]>0:
            self.results_area.append(f"找到 {result_df.shape[0]} 个匹配结果。")
            result_df.columns=["中文""英文"]
            self.update_table(result_df)
        else:
            self.results_area.append(f"未在文件中找到包含关键词 '{keyword}' 的内容。")

    def update_table(self, df):
        # 更新 QTableView 中的数据
        model = PandasModel(df)
        self.table_view.setModel(model)

    def toggle_language(self):
        # 切换语言模式
        if self.language_mode == 'Chinese':
            self.language_mode = 'English'
            self.language_button.setText('切换到中文模式')
            self.results_area.append("已切换到英文模式,搜索第二列。")
        else:
            self.language_mode = 'Chinese'
            self.language_button.setText('切换到英文模式')
            self.results_area.append("已切换到中文模式,搜索第一列。")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = ExcelSearchApp()
    window.show()
    sys.exit(app.exec_())

打包命令

nuitka --mingw64 --standalone --show-progress --show-memory --nofollow-import-to=sympy,numpy,pandas,numpy --enable-plugin=pyqt5 --include-module=openpyxl --jobs=4 --output-dir=o index.py

打包完成,只有PyQt5在index.dist文件夹中

打包完成后将所需要的库(已上传仓库,点击阅读原文即可获取)复制到o文件夹下的index.dist文件夹下,即可完成运行

复制库

正常运行


Python工坊
Python技术分享
 最新文章