├── README.md └── packer.py /README.md: -------------------------------------------------------------------------------- 1 | 2 | Python packer for Windows - простой упаковщик скриптов Python в .EXE файлы. 3 | 4 | Имеет графический интерфейс, создан на основе PyInstaller 5 | 6 | Для работы программы потребуется установить модуль [Pyinstaller](https://pypi.org/project/PyInstaller/), PyWin32 и Pypiwin32. 7 | Если вы устанавливаете PyInstaller с помощью pip или conda, но PyWin32 еще не установлен, то pypiwin32 устанавливается автоматически. 8 | PyInstaller также требует пакет [pefile](https://pypi.org/project/pefile/). 9 | Возможно понадобится дополнительно установить сопутствующие библиотеки, которые используются в проекте - интерпретатор сообщит вам об этом. 10 | 11 | **Где сохраняются готовые проекты?** 12 | 13 | Сборка производится в папку dist в рабочем каталоге IDLE - она будет создана, если ее нет. 14 | Открыть ее довольно просто - нажатием кнопки open 15 | 16 | **Как собрать проект?** 17 | 18 | Укажите путь к скрипту, который хотите собрать в exe файл. 19 | Расширение файла должно быть **.py или .pyw** 20 | При необходимости отметьте нужные чекбоксы справа - в консоли отобразится статус настройки. 21 | В окне программы появится кнопка "Запустить сборку!" - при ее нажатии запустится процесс сборки скрипта. 22 | 23 | **Настройки работы программы:** 24 | 25 | *Отключить запуск терминала.* 26 | 27 | Эта настройка отключает отображение консоли при запуске вашего приложения после сборки. 28 | 29 | *Сборка в один файл.* 30 | 31 | Эта настройка позволит собрать вашу программу в один exe файл.* 32 | 33 | *Сборка в одну папку.* 34 | 35 | Эта настройка позволит собрать вашу программу в каталог, внутри которого будут служебные файлы и сам .exe файл вашей программы. 36 | Такой вариант будет быстрее запускаться. 37 | 38 | *Задать иконку файлу.* 39 | 40 | Выберите ico иконку для вашего проекта и установите чекбокс на этом пункте - иконка будет добавлена к проекту. 41 | 42 | *Очистить временные файлы.* 43 | 44 | Удаление временных файлов, которые создаются в процессе сборки проекта. 45 | 46 | *Требовать права Администратора.* 47 | 48 | Ваша программа будет запускаться с правами Администратора 49 | 50 | *Как добавить собственные меню из функционала Pyinstaller?* 51 | 52 | Просто добавляйте желаемые пункты в список list_check - я в программе разместил класс, который самостоятельно генерирует отображение, размещение на форме и команды обращения к пункту. 53 | Не забудьте добавить команду на исполнение в функцию file_compilled - только не последним файлом, что бы не ломать логику построения. 54 | 55 | 56 | [Официальный форум поддержки](https://safezone.cc/threads/python-exe-compiller-programma-dlja-kompiljacii-skriptov-python-v-exe-fajly.34032/#post-278301) 57 | 58 | 59 | 60 | ![image](https://user-images.githubusercontent.com/41836986/110980257-3d33ba80-8398-11eb-80be-9fe68a17dde0.png) 61 | -------------------------------------------------------------------------------- /packer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Python packer for Windows. 4 | 5 | @author: Кирилл safezone.cc 6 | """ 7 | import tkinter as tk 8 | from tkinter import filedialog as fd 9 | import os as os 10 | import PyInstaller.__main__ 11 | 12 | root = tk.Tk() 13 | checkbuttons_id = int() 14 | object_id = int() 15 | 16 | 17 | class Buttons(): 18 | """Класс отвечает за создание и работу кнопок, переключателей и прочих \ 19 | управляющих элементов.""" 20 | 21 | def __init__(self, root='root'): 22 | # Корневой фрейм 23 | self.root = root 24 | # Флаг checkbutton 25 | self.flag_check = tk.BooleanVar() 26 | self.flag_check.set(0) 27 | # Координаты расположения checkbutton 28 | self.axle_x = int(350) 29 | self.axle_y = int(25) 30 | 31 | def checkbuttons(self, *kwargz): 32 | """На вход принимаем параметры checkbutton. \ 33 | Упаковываем и задаем рабочие параметры.""" 34 | global checkbuttons_id, object_id 35 | 36 | self.object, self.text = kwargz 37 | if self.object.endswith('text'): 38 | object_id += 1 39 | self.object = tk.Entry() 40 | self.object.insert(0, self.text) 41 | self.object.place(x=20, y=(380 - object_id*self.axle_y), 42 | width=400, height=25) 43 | 44 | self.object_bt = tk.Button() 45 | self.object_bt.place(x=425, y=(380 - object_id*self.axle_y)) 46 | 47 | elif self.object.endswith('label'): 48 | object_id += 1 49 | self.object = tk.Label(text=self.text) 50 | self.object.place(x=20, y=(380 - object_id*self.axle_y)) 51 | else: 52 | checkbuttons_id += 1 53 | self.object = tk.Checkbutton(text=self.text, 54 | variable=self.flag_check, 55 | onvalue=1, offvalue=0, 56 | command=self.check_select) 57 | self.object.place(x=self.axle_x, y=(self.axle_y * checkbuttons_id)) 58 | 59 | def check_select(self): 60 | """Event select scheckbox.""" 61 | if self.flag_check.get(): 62 | print(self.text) 63 | if check_onefile.flag_check.get(): 64 | check_onefolder.flag_check.set(0) 65 | else: 66 | print('Отменено: ' + self.text) 67 | if check_icon.flag_check.get(): 68 | if not icon_patch_text.object.get().lower().endswith('.ico'): 69 | if icon_patch_text.object.get() != '': 70 | icon_patch_text.object.delete(0, 'end') 71 | icon_patch_text.object.insert( 72 | 0, 'Выберите файл с расширением \'.ico\'') 73 | print('Выберите файл с расширением \'.ico\'') 74 | check_icon.flag_check.set(0) 75 | 76 | def objects_id(self, *kwargz): 77 | """ 78 | На вход принимаем параметры object - прочие элементы на форме. 79 | 80 | Упаковываем и задаем рабочие параметры 81 | """ 82 | global object_id 83 | object_id += 1 84 | self.object, self.text = kwargz 85 | self.object = tk.Entry(text=self.text) 86 | self.object.place(x=self.axle_x, y=300-20*object_id) 87 | 88 | 89 | ############################################################################# 90 | # Функция сборки пректа 91 | def file_compilled(): 92 | """Параметры Pyinstaller в порядке их выполнения.""" 93 | py_compiled_list = ['--name=%s' % input_name_file.get()] 94 | if check_clean.flag_check.get(): 95 | py_compiled_list.insert(0, '--clean') 96 | if check_onefile.flag_check.get(): 97 | py_compiled_list.append('-F') 98 | if check_onefolder.flag_check.get(): 99 | py_compiled_list.append('-D') 100 | if check_noconsole.flag_check.get(): 101 | py_compiled_list.append('-w') 102 | if check_icon.flag_check.get(): 103 | py_compiled_list.append('-i=%s' % icon_patch_text.object.get()) 104 | if check_admin.flag_check.get(): 105 | py_compiled_list.append('--uac-admin') 106 | py_compiled_list.append(os.path.abspath(input_patch_file.get())) 107 | PyInstaller.__main__.run(py_compiled_list) 108 | ############################################################################# 109 | 110 | 111 | # Checkbutton - экземпляры класса 112 | # Требовать права Администратора 113 | check_admin = Buttons(root) 114 | # Отключить запуск консоли 115 | check_noconsole = Buttons(root) 116 | # Сборка в один файл 117 | check_onefile = Buttons(root) 118 | # Сборка в одну папку 119 | check_onefolder = Buttons(root) 120 | # очистить временные файлы 121 | check_clean = Buttons(root) 122 | # задать иконку к сборке файла 123 | check_icon = Buttons(root) 124 | # label с адресом иконки проекта 125 | icon_patch_label = Buttons(root) 126 | # текстовое поле с адресом места иконки 127 | icon_patch_text = Buttons(root) 128 | # текстовое поле с адресом места сборки 129 | pack_patch_file_text = Buttons(root) 130 | # label с адресом места сборки 131 | pack_patch_file_label = Buttons(root) 132 | list_check = [ 133 | check_noconsole.checkbuttons('check_noconsole', 134 | 'Отключить запуск терминала'), 135 | check_onefile.checkbuttons('check_onefile', 'Сборка в один файл'), 136 | check_onefolder.checkbuttons('check_onefolder', 'Сборка в одну папку'), 137 | check_clean.checkbuttons('check_clean', 'Очистить временные файлы'), 138 | check_icon.checkbuttons('check_icon', 'Задать иконку к файлу'), 139 | icon_patch_text.checkbuttons('icon_patch_text', '.....'), 140 | icon_patch_label.checkbuttons('icon_text_label', 141 | 'Задать иконку для проекта:'), 142 | pack_patch_file_text.checkbuttons('pack_patch_file_text', 143 | os.getcwd() + "\\dist\\"), 144 | pack_patch_file_label.checkbuttons('pack_patch_file_label', 145 | 'Проект будет сохранен по адресу:'), 146 | check_admin.checkbuttons('check_admin', 'Требовать права Админитратора'), ] 147 | 148 | 149 | def bt_open_func(): 150 | """ 151 | Кнопка открыть рабочий каталог. 152 | 153 | Функция проверяет наличие пути, указанного в поле ввода 154 | Если адрес недоступен - создает каталог в полном соответствии 155 | с введенными данными в текстовом поле 156 | """ 157 | if os.path.isdir(pack_patch_file_text.object.get()): 158 | os.system('explorer %s' % os.path.abspath( 159 | pack_patch_file_text.object.get())) 160 | else: 161 | os.mkdir(pack_patch_file_text.object.get()) 162 | os.system('explorer %s' % os.path.abspath( 163 | pack_patch_file_text.object.get())) 164 | 165 | 166 | def file_setting(): 167 | """ 168 | Диалоговое окно выбора скрипта Python для сборки. 169 | 170 | Проверяет, действительно ли выбран файл с расширением .py 171 | ---> Если да, удаляем содержимое текстового поля (input_patch_file), 172 | если не пустое. Затем записываем туда путь до файла 173 | В поле с именем файла (input_name_file) - 174 | автомтически пишем имя выбранного файла 175 | Далее активируем кнопку компилляции (bt_run) 176 | ---> Если выбран файл не с расширением .py, то выводим соответствующее 177 | сообщение, а так же деактивируем кнопки, если активны 178 | """ 179 | file_name = fd.askopenfilename(title='Выберите файл для сборки', 180 | filetypes=[('Python File', '.py'), 181 | ('Python File', '.pyw')]) 182 | if file_name: 183 | input_patch_file.delete(0, 'end') 184 | input_patch_file.insert(0, file_name) 185 | if not input_name_file.get(): 186 | input_name_file.insert(0, os.path.splitext( 187 | os.path.basename(file_name))[0]) 188 | bt_run.place(x=20, y=125, height=25) 189 | return file_name 190 | 191 | 192 | def icon_patch_open(): 193 | """Функция - иконка проекта. Проверка и обработка.""" 194 | icon_name = fd.askopenfilename(title='Выберите файл иконки', 195 | filetypes=[('images', '*.ico')]) 196 | if icon_name.lower().endswith('.ico'): 197 | icon_patch_text.object.delete(0, 'end') 198 | icon_patch_text.object.insert(0, icon_name) 199 | return icon_name 200 | 201 | 202 | if __name__ == '__main__': 203 | 204 | # ###################################################################### # 205 | # Поле ввода - имя файла и путь к нему 206 | input_patch_file = tk.Entry() 207 | input_patch_file.place(x=20, y=25, width=240, height=25) 208 | 209 | name_patch_file = tk.Label(text='Укажите путь к вашему файлу') 210 | name_patch_file.place(x=20, y=3, width=180) 211 | 212 | # Кнопка диалога выбора файла, который будем компиллировать 213 | bt_patch = tk.Button(text='...', command=file_setting) 214 | bt_patch.place(x=260, y=25, height=25) 215 | 216 | # Поле ввода - имя для проекта 217 | input_name_file = tk.Entry() 218 | input_name_file.place(x=20, y=75, width=240, height=25) 219 | 220 | # Кнопка "Запустить сборку" 221 | bt_run = tk.Button(text='Запустить сборку!', command=file_compilled) 222 | 223 | # Lbel name file 224 | name_your_file = tk.Label(text='Как вы назовете ваш проект?') 225 | name_your_file.place(x=20, y=50, width=180) 226 | 227 | # ###################################################################### # 228 | 229 | # Указываем параметры отдельных объектов, если нужно. 230 | # Деактивируем текстовое поле указания рабочего каталога 231 | pack_patch_file_text.object.configure(state='disable') 232 | # Кнопка открытия рабочего каталога 233 | pack_patch_file_text.object_bt.configure(text='open', command=bt_open_func) 234 | # Кнопка пути к иконке... 235 | icon_patch_text.object_bt.configure(text='open', command=icon_patch_open) 236 | root.title("Упаковщик скриптов Python в .exe") 237 | root.geometry('600x400') 238 | root.resizable(0, 0) 239 | root.mainloop() 240 | root.mainloop() 241 | --------------------------------------------------------------------------------