Skip to content

Commit 7ed0e5d

Browse files
committed
update
1 parent 296bf1e commit 7ed0e5d

File tree

3 files changed

+270
-13
lines changed

3 files changed

+270
-13
lines changed

src/build.spec

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
BLOCK_CIPHER = None
44
APP_NAME = 'Pythub'
55
APP_APP = 'Pythub.app'
6-
APP_VERSION = '0.0.1'
6+
APP_VERSION = '0.0.2'
77
SCRIPTS = ['pythub.py']
88
BINARIES = []
99
DATAS = []
@@ -13,7 +13,7 @@ EXCLUDES = [] # 不需要打包的模块
1313
RUNTIME_HOOKS = []
1414
BUNDLE_IDENTIFIER = 'com.crogram.pythub' # 一般情况下Bundle ID的格式为:com.公司名称.项目名称
1515
UPX = True # 如果有UPX安装(执行Configure.py时检测),会压缩执行文件(Windows系统中的DLL也会)
16-
PATHEX = ['aa.py', 'bb.py', 'cc.py', '/Users/douzhenjiang/Projects/pythub/src']
16+
PATHEX = ['/Users/douzhenjiang/Projects/pythub/src']
1717

1818
a = Analysis(
1919
SCRIPTS,

src/pythub.py

+42-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,45 @@
1-
# _*_ coding:utf-8 _*_
2-
import tkinter
1+
# -*- coding: utf-8 -*-
32

4-
import aa
5-
import bb
6-
import cc
7-
import utils
3+
from os import system
4+
from threading import Thread
5+
from tkinter import Tk
86

9-
window = tkinter.Tk()
10-
window.title('Pythub')
11-
window.resizable(width=False, height=False)
12-
utils.set_window_center(window, 800, 600)
7+
from utils import set_window_center
8+
from view import View
139

14-
window.mainloop() # 将窗口显示出来
10+
11+
class App(View):
12+
def __init__(self, master=None):
13+
super(App, self).__init__()
14+
master.title('Pythub')
15+
master.resizable(False, False)
16+
17+
def fn_build(self):
18+
'''生成可执行文件'''
19+
if not self.status_build:
20+
thread_build = Thread(target=self.thread)
21+
thread_build.setDaemon(True)
22+
thread_build.start()
23+
else:
24+
self.label_status['text'] = '正在打包,请稍后再操作!'
25+
26+
def thread(self):
27+
'''线程执行生成动作'''
28+
if len(self.entry_value_list[0].get()) == 0:
29+
self.label_status['text'] = '请选择源文件'
30+
return
31+
try:
32+
self.status_build = True
33+
cmd = self.fn_build_cmd()
34+
self.label_status['text'] = '正在打包,请稍等。。。'
35+
system(cmd)
36+
self.status_build = False
37+
self.label_status['text'] = '打包成功!'
38+
except Exception as e:
39+
self.label_status['text'] = e.message
40+
self.status_build = False
41+
42+
if __name__ == '__main__':
43+
root = Tk()
44+
App(root)
45+
root.mainloop()

src/view.py

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import os.path
4+
from tkinter import (Button, Checkbutton, Entry, IntVar, Label, LabelFrame, StringVar, filedialog)
5+
6+
from utils import set_window_center
7+
8+
9+
class View(object):
10+
def __init__(self, master=None):
11+
self.root = master
12+
self.status_build = False
13+
self.init_frame()
14+
15+
def init_frame(self):
16+
'''基本框架'''
17+
self.frm_project = LabelFrame(self.root, text='项目')
18+
self.frm_config = LabelFrame(self.root, text='配置')
19+
self.frm_operate = LabelFrame(self.root, text='操作')
20+
self.frm_status = LabelFrame(self.root, text='状态')
21+
22+
self.frm_project.pack(expand='yes', side='top',
23+
fill='both', padx=15, pady=10)
24+
self.frm_config.pack(fill='x', padx=15, pady=10)
25+
self.frm_operate.pack(fill='x', padx=15, pady=10)
26+
self.frm_status.pack(side='bottom', fill='x', padx=15, pady=10)
27+
28+
self.init_project()
29+
self.init_config()
30+
self.init_operate()
31+
self.init_status()
32+
33+
def init_project(self):
34+
'''项目配置'''
35+
labels = ['入口文件:', '工作目录:', '目标路径:', '图标路径:']
36+
37+
self.entry_value_list = list()
38+
for index, label_text in enumerate(labels):
39+
temp_strvar = StringVar()
40+
temp_label = Label(self.frm_project, text=label_text)
41+
temp_entry = Entry(
42+
self.frm_project, textvariable=temp_strvar, width=50)
43+
self.entry_value_list.append(temp_strvar)
44+
temp_label.grid(row=index % 4, column=0,
45+
padx=5, pady=5, sticky='w')
46+
temp_entry.grid(row=index % 4, column=1,
47+
padx=5, pady=5, sticky='we')
48+
49+
self.btn_main_path = Button(
50+
self.frm_project, text='选择文件', command=self.fn_select_main
51+
)
52+
self.btn_work_path = Button(
53+
self.frm_project, text='选择路径', command=self.fn_work_path
54+
)
55+
self.btn_dist_path = Button(
56+
self.frm_project, text='选择路径', command=self.fn_dist_path
57+
)
58+
self.btn_ico_path = Button(
59+
self.frm_project, text='选择图标', command=self.fn_icon_path
60+
)
61+
self.btn_main_path.grid(row=0, column=2, padx=5, pady=5, sticky='we')
62+
self.btn_work_path.grid(row=1, column=2, padx=5, pady=5, sticky='w')
63+
self.btn_dist_path.grid(row=2, column=2, padx=5, pady=5, sticky='e')
64+
self.btn_ico_path.grid(row=3, column=2, padx=5, pady=5, sticky='e')
65+
66+
def init_config(self):
67+
'''配置选项'''
68+
# 定义变量
69+
self.cfg_onefile = IntVar()
70+
self.cfg_onedir = IntVar()
71+
self.cfg_noconsole = IntVar()
72+
self.cfg_clean = IntVar()
73+
self.cfg_rename = IntVar()
74+
self.cfg_exe_name = StringVar()
75+
# 子配置框架
76+
self.frm_config_base = LabelFrame(
77+
self.frm_config, text='基本', borderwidth=0)
78+
self.frm_config_base.pack(fill='x', padx=10, pady=5, ipady=5)
79+
self.frm_config_exe = LabelFrame(
80+
self.frm_config, text='生成执行文件类型', borderwidth=0)
81+
self.frm_config_exe.pack(fill='x', padx=10, pady=5, ipady=5)
82+
self.frm_config_other = LabelFrame(
83+
self.frm_config, text='其它', borderwidth=0)
84+
self.frm_config_other.pack(fill='x', padx=10, pady=5, ipady=5)
85+
# 定义按钮
86+
self.btn_noconsole = Checkbutton(
87+
self.frm_config_base, text='关闭控制台', variable=self.cfg_noconsole)
88+
self.btn_clean = Checkbutton(
89+
self.frm_config_base, text='构建前清理', variable=self.cfg_clean)
90+
self.btn_isonefile = Checkbutton(
91+
self.frm_config_exe, text='单个执行文件', variable=self.cfg_onefile)
92+
self.btn_isonedir = Checkbutton(
93+
self.frm_config_exe, text='文件夹包', variable=self.cfg_onedir)
94+
self.btn_rename = Checkbutton(
95+
self.frm_config_other, text='修改执行文件名', variable=self.cfg_rename)
96+
self.entry_rename = Entry(
97+
self.frm_config_other, textvariable=self.cfg_exe_name)
98+
# 放置按钮
99+
self.btn_isonefile.pack(side='left', fill='x')
100+
self.btn_isonedir.pack(side='left', fill='x')
101+
self.btn_noconsole.pack(side='left', fill='x')
102+
self.btn_clean.pack(side='left', fill='x')
103+
self.btn_rename.pack(side='left', fill='x')
104+
self.entry_rename.pack(fill='x')
105+
# 初始化默认值
106+
self.cfg_onefile.set(1)
107+
self.cfg_onedir.set(0)
108+
self.cfg_noconsole.set(1)
109+
self.cfg_clean.set(1)
110+
111+
def init_operate(self):
112+
'''操作命令'''
113+
# 定义按钮
114+
self.btn_build = Button(
115+
self.frm_operate, text='构建生成', command=self.fn_build)
116+
self.btn_clear = Button(
117+
self.frm_operate, text='清理', command=self.fn_clear)
118+
self.btn_reset = Button(
119+
self.frm_operate, text='重置', command=self.fn_reset)
120+
# 放置按钮
121+
self.btn_build.pack(fill='x', side='left')
122+
self.btn_clear.pack(fill='x', side='left')
123+
self.btn_reset.pack(fill='x', side='left')
124+
125+
def init_status(self):
126+
'''状态栏'''
127+
self.label_status = Label(self.frm_status, text='待命')
128+
self.label_status.grid(row=1, column=0, padx=5, pady=5, sticky='we')
129+
130+
def fn_build(self):
131+
'''生成可执行文件'''
132+
pass
133+
134+
def fn_clear(self):
135+
'''清理生成文件'''
136+
pass
137+
138+
def fn_reset(self):
139+
'''重置表单内容'''
140+
for i in range(4):
141+
self.entry_value_list[i].set('')
142+
143+
self.cfg_onefile.set(1)
144+
self.cfg_noconsole.set(1)
145+
self.cfg_clean.set(1)
146+
self.cfg_rename.set(0)
147+
self.cfg_exe_name.set('')
148+
149+
def fn_select_main(self):
150+
'''选择源文件'''
151+
types = (
152+
('py files', '*.py'),
153+
('pyc files', '*.pyc'),
154+
('All files', '*.*')
155+
)
156+
path = filedialog.askopenfilename(filetypes=types)
157+
if not path:
158+
return
159+
_path = os.path.dirname(path)
160+
# 主文件
161+
self.entry_value_list[0].set(path)
162+
# 工作目录
163+
self.entry_value_list[1].set(os.path.join(_path, 'build/'))
164+
# dist目录
165+
self.entry_value_list[2].set(os.path.join(_path, 'dist/'))
166+
167+
def fn_work_path(self):
168+
'''选择工作目录'''
169+
path = filedialog.askdirectory()
170+
if not path:
171+
return
172+
self.entry_value_list[1].set(path)
173+
174+
def fn_dist_path(self):
175+
'''选择生成文件目录'''
176+
path = filedialog.askdirectory()
177+
if not path:
178+
return
179+
self.entry_value_list[2].set(path)
180+
181+
def fn_icon_path(self):
182+
'''选择图标文件'''
183+
types = (
184+
('ico files', '*.ico'),
185+
('icns files', '*.icns'),
186+
('All files', '*.*')
187+
)
188+
path = filedialog.askopenfilename(filetypes=types)
189+
if not path:
190+
return
191+
self.entry_value_list[3].set(path)
192+
193+
def fn_build_cmd(self):
194+
'''组装命令'''
195+
cmds = list()
196+
cmds.append('pyinstaller')
197+
198+
if self.cfg_onefile.get() == 1:
199+
cmds.append('--onefile')
200+
elif self.cfg_onedir.get() == 1:
201+
cmds.append('--onedir')
202+
203+
if self.cfg_clean.get() == 1:
204+
cmds.append('--clean')
205+
cmds.append('--noconfirm')
206+
207+
if self.cfg_noconsole.get() == 1:
208+
cmds.append('--noconsole')
209+
210+
if len(self.entry_value_list[1].get()) > 0:
211+
cmds.append('--workpath=' + self.entry_value_list[1].get())
212+
213+
if len(self.entry_value_list[2].get()) > 0:
214+
cmds.append('--distpath=' + self.entry_value_list[2].get())
215+
216+
if len(self.entry_value_list[3].get()) > 0:
217+
cmds.append('--icon=' + self.entry_value_list[3].get())
218+
219+
if self.cfg_rename.get() == 1:
220+
if len(self.cfg_exe_name.get()) > 0:
221+
cmds.append('--name=' + self.cfg_exe_name.get())
222+
223+
if len(self.entry_value_list[0].get()) > 0:
224+
cmds.append(self.entry_value_list[0].get())
225+
226+
return ' '.join(cmds)

0 commit comments

Comments
 (0)