Attachment 'py2exe_gui_V0.04.pyw'
Download 1 # -*- coding: utf-8 -*-
2
3 # Programmer: 0.707
4 # $Id: py2exe_gui.pyw
5
6 __VER__ = u'0.04'
7
8 import sys
9 import os
10 import wx
11 import wx.grid as gridlib
12
13 from py2exe.build_exe import py2exe
14 from distutils.core import Distribution
15
16 exe_typs = ['console', 'windows','service','com_server']
17
18 def MakeExe(dir,par_d,opt_d):
19 os.chdir(dir)
20 sys_old_path = sys.path[:]
21 sys.path.insert(0,dir)
22
23 dist = Distribution(par_d)
24 cmd = py2exe(dist)
25
26 cmd.__dict__.update(opt_d)
27
28 cmd.ensure_finalized()
29
30
31 cmd.run()
32 sys.path = sys_old_path
33
34 build_dir = os.path.join(dir,'build')
35 from distutils import dir_util
36 dir_util.remove_tree(build_dir)
37
38 class PyFileGrid(gridlib.Grid):
39 def __init__(self, parent):
40 gridlib.Grid.__init__(self, parent, -1,style=wx.STATIC_BORDER)
41 self.CreateGrid(1, 2)
42 self.SetColLabelValue(0,u"文件名")
43 self.SetColLabelValue(1,u"程序类型")
44 self.SetColSize(0,200)
45 self.SetColSize(1,100)
46 self.SetRowLabelSize(30)
47 self.DeleteRows()
48
49 def CreateEditor(self):
50 return gridlib.GridCellChoiceEditor(exe_typs, False)
51
52 def SetValues(self,files):
53 row_c = self.GetNumberRows()
54 if row_c:
55 self.DeleteRows(0,row_c)
56 file_c = len(files)
57 self.AppendRows(file_c)
58 for row,file in enumerate(files):
59 self.SetCellEditor(row, 1, self.CreateEditor())
60 self.SetCellValue(row,0,file)
61 ext = os.path.splitext(file)[1].lower()
62 if ext =='.pyw':
63 self.SetCellValue(row,1,'windows')
64 elif ext =='.py':
65 self.SetCellValue(row,1,'console')
66
67 def GetValueDict(self):
68 row_c = self.GetNumberRows()
69 v_d = {}
70 for row in range(row_c):
71 typ = self.GetCellValue(row,1)
72 if typ in exe_typs:
73 if typ not in v_d:
74 v_d[typ] = []
75 v_d[typ].append(self.GetCellValue(row,0))
76 return v_d
77
78
79
80
81 class DataFileGrid(gridlib.Grid):
82 def __init__(self, parent):
83 gridlib.Grid.__init__(self, parent, -1,style=wx.STATIC_BORDER)
84 self.CreateGrid(1, 2)
85 self.SetColLabelValue(0,u"源文件")
86 self.SetColLabelValue(1,u"安装目录")
87 self.SetColSize(0,300)
88 self.SetColSize(1,60)
89 self.SetRowLabelSize(20)
90 self.DeleteRows()
91 self.SetSelectionMode(1)
92
93 def SetValues(self,paths):
94 row_c = self.GetNumberRows()
95 file_c = len(paths)
96 self.AppendRows(file_c)
97
98 for i,p in enumerate(paths):
99 self.SetCellValue(row_c+i,0,p)
100 self.SetCellValue(row_c+i,1,'data')
101
102 def DelSelectedRows(self):
103 tls = self.GetSelectionBlockTopLeft()
104 brs = self.GetSelectionBlockBottomRight()
105
106 needdel_rows = []
107 for t,b in [(x[0],y[0]) for x,y in zip(tls,brs)]:
108 needdel_rows += range(t,b+1)
109
110 old_row_c = self.GetNumberRows()
111 new_row_c = old_row_c-len(needdel_rows)
112
113 remain_rows = []
114 for row in range(old_row_c):
115 if row not in needdel_rows:
116 remain_rows.append((self.GetCellValue(row,0),self.GetCellValue(row,1)))
117
118 self.DeleteRows(0,old_row_c)
119 self.AppendRows(new_row_c)
120
121 for i,fd in enumerate(remain_rows):
122 self.SetCellValue(i,0,fd[0])
123 self.SetCellValue(i,1,fd[1])
124
125 def GetValueDict(self):
126 row_c = self.GetNumberRows()
127 v_d = {}
128 for row in range(row_c):
129 path = self.GetCellValue(row,1).encode('utf-8')
130 file = self.GetCellValue(row,0).encode('utf-8')
131 if path not in v_d:
132 v_d[path] = []
133 if len(file):
134 v_d[path].append(file)
135 return v_d
136
137 class MyFrame(wx.Frame):
138 def __init__(self,title):
139 wx.Frame.__init__(self,None,-1,title,style=wx.SYSTEM_MENU|wx.CAPTION|wx.CLOSE_BOX ,size=wx.Size(400,400))
140
141 # Prepare the menu bar
142 menuBar = wx.MenuBar()
143
144 # 1st menu from left
145 menu = wx.Menu()
146
147 #menu.Append(101, u"打开", u"打开一个已有工程")
148 #menu.Append(102, u"保存", u"把当前工程信息存盘")
149 #menu.Append(103, u"另存为...", u"把当前工程信息换名存盘")
150 menu.AppendSeparator()
151 menu.Append(104, u"退出", u"退出本程序")
152 # Add menu to the menu bar
153 menuBar.Append(menu, u"工程")
154 menu = wx.Menu()
155
156 menu.Append(201, u"生成可执行文件", u"")
157 menuBar.Append(menu, u"py2exe")
158
159
160 self.SetMenuBar(menuBar)
161
162 self.Bind(wx.EVT_MENU, self.Exit, id=104)
163 self.Bind(wx.EVT_MENU, self.OnMakeExe,id=201 )
164
165 #notebook
166 self.nb = nb = wx.Notebook(self,-1,style=wx.NB_BOTTOM )
167
168 #页面1,基本信息,选择要生成的控制台程序和窗口程程序脚本
169 self.panel_1 = panel_1 = wx.Panel(nb, -1,style=wx.STATIC_BORDER)
170 self.nb.AddPage(panel_1,u"程序文件",select = True)
171
172
173 self.help_label = wx.StaticText(panel_1, -1, u" 点右边按扭选择要打包的python文件(可多选),再点菜单'py2exe'->'生成可执行文件'既可.",size=(240,50))
174 self.add_py_btn = wx.Button(panel_1,-1, u"选择python文件",size=(100,40))
175
176 self.dir_label = wx.StaticText(panel_1, -1, u"目录:")
177 self.dir_text = wx.TextCtrl(panel_1, -1, u"",style=wx.TE_READONLY )
178
179 self.py_grid = PyFileGrid(self.panel_1)
180
181 self.Bind(wx.EVT_BUTTON, self.AddPyFile,self.add_py_btn)
182
183 #页面3,数据文件
184 self.panel_3 = panel_3 = wx.Panel(nb, -1,style=wx.STATIC_BORDER)
185 self.nb.AddPage(panel_3,u"数据文件")
186
187 self.add_data_btn = wx.Button(panel_3,-1, u"添加",size=(40,24))
188 self.del_data_btn = wx.Button(panel_3,-1, u"删除",size=(40,24))
189
190 self.data_grid = DataFileGrid(self.panel_3)
191
192 self.Bind(wx.EVT_BUTTON, self.AddDataFile,self.add_data_btn)
193 self.Bind(wx.EVT_BUTTON, self.DelDataFile,self.del_data_btn)
194
195 #页面2,选项
196 self.panel_2 = panel_2 = wx.Panel(nb, -1,style=wx.STATIC_BORDER )
197 self.nb.AddPage(panel_2,u"py2exe选项")
198
199 self.optimize_label = wx.StaticText(panel_2, -1, u"optimization level(优化选项):")
200 self.optimize_box = wx.ComboBox(panel_2,-1,value='0',choices = ['0','1','2'],style = wx.CB_READONLY )
201
202 self.distdir_label = wx.StaticText(panel_2, -1, u"dist-dir(存放生成文件的目录):")
203 self.distdir_box = wx.TextCtrl(panel_2,-1,u'dist',size=(200,22))
204
205 self.excludes_label = wx.StaticText(panel_2, -1, u'excludes(排除的模块,以","分隔):')
206 self.excludes_box = wx.TextCtrl(panel_2,-1,u'',size=(183,22))
207
208 self.dllexcludes_label = wx.StaticText(panel_2, -1, u'dll-excludes(排除dll文件,以","分隔):')
209 self.dllexcludes_box = wx.TextCtrl(panel_2,-1,u'',size=(168,22))
210
211
212 self.ignores_label = wx.StaticText(panel_2, -1, u'ignores(忽略的模块,以","分隔):')
213 self.ignores_box = wx.TextCtrl(panel_2,-1,u'',size=(190,22))
214
215 self.includes_label = wx.StaticText(panel_2, -1, u'includes(包含的模块,以","分隔):')
216 self.includes_box = wx.TextCtrl(panel_2,-1,u'',size=(185,22))
217
218 self.packages_label = wx.StaticText(panel_2, -1, u'packages(包含的模块包,以","分隔):')
219 self.packages_box = wx.TextCtrl(panel_2,-1,u'',size=(168,22))
220
221 self.bundle_label = wx.StaticText(panel_2, -1, u'bundle-files(打包dll级别):')
222 self.bundle_box = wx.ComboBox(panel_2,-1,value='3',choices = ['1','2','3'],style = wx.CB_READONLY )
223
224
225 self.compressed = wx.CheckBox(panel_2,-1,u"compressed(生成压缩文件zipfile)")
226 self.xref = wx.CheckBox(panel_2,-1,u"xref(生成模块交叉引用)")
227 self.ascii = wx.CheckBox(panel_2,-1,u"ascii(不自动包含encoding和codecs)")
228
229
230
231 #页面3,py2exe输出
232 self.output = wx.TextCtrl(nb, -1,style=wx.TE_MULTILINE)
233 self.nb.AddPage(self.output,u"py2exe输出")
234
235
236 self.__do_layout()
237
238 self.Bind(wx.EVT_CLOSE,self.OnCloseWindow,self)
239
240 self.lasts = ''
241
242 def __do_layout(self):
243
244 sizer = wx.BoxSizer(wx.VERTICAL)
245
246 sizer_0 = wx.BoxSizer(wx.HORIZONTAL)
247 sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
248 sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
249 sizer_11 = wx.BoxSizer(wx.VERTICAL)
250 sizer_12 = wx.BoxSizer(wx.VERTICAL)
251
252
253 sizer_0.Add(self.dir_label,0, wx.LEFT|wx.RIGHT, 5)
254 sizer_0.Add(self.dir_text, 1,wx.RIGHT|wx.EXPAND, 10)
255
256
257
258 sizer_1.Add(self.py_grid,1, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 10)
259
260
261 sizer_2.Add(self.help_label, 0, wx.LEFT|wx.RIGHT,10)
262 sizer_2.Add(self.add_py_btn, 1, wx.LEFT|wx.RIGHT,10)
263
264 sizer.Add(sizer_2, 0,wx.TOP|wx.BOTTOM,20)
265 sizer.Add(sizer_0, 0,wx.TOP|wx.EXPAND,10)
266 sizer.Add(sizer_1, 1,wx.TOP|wx.EXPAND,10)
267
268
269 self.panel_1.SetAutoLayout(1)
270 self.panel_1.SetSizer(sizer)
271
272
273
274 sizer1 = wx.BoxSizer(wx.VERTICAL)
275
276
277 sizer1_1 = wx.BoxSizer(wx.HORIZONTAL)
278 sizer1_2 = wx.BoxSizer(wx.HORIZONTAL)
279 sizer1_3 = wx.BoxSizer(wx.HORIZONTAL)
280 sizer1_31 = wx.BoxSizer(wx.HORIZONTAL)
281 sizer1_4 = wx.BoxSizer(wx.HORIZONTAL)
282 sizer1_5 = wx.BoxSizer(wx.HORIZONTAL)
283 sizer1_6 = wx.BoxSizer(wx.HORIZONTAL)
284 sizer1_7 = wx.BoxSizer(wx.HORIZONTAL)
285 sizer1_8 = wx.BoxSizer(wx.HORIZONTAL)
286
287 sizer1_1.Add(self.optimize_label,0, wx.LEFT|wx.RIGHT, 5)
288 sizer1_1.Add(self.optimize_box,1, wx.LEFT|wx.RIGHT, 5)
289
290 sizer1_2.Add(self.distdir_label,0, wx.LEFT|wx.RIGHT, 5)
291 sizer1_2.Add(self.distdir_box,1, wx.LEFT|wx.RIGHT, 5)
292
293 sizer1_3.Add(self.excludes_label,0, wx.LEFT|wx.RIGHT, 5)
294 sizer1_3.Add(self.excludes_box,1, wx.LEFT|wx.RIGHT, 5)
295
296 sizer1_31.Add(self.dllexcludes_label,0, wx.LEFT|wx.RIGHT, 5)
297 sizer1_31.Add(self.dllexcludes_box,1, wx.LEFT|wx.RIGHT, 5)
298
299 sizer1_4.Add(self.ignores_label,0, wx.LEFT|wx.RIGHT, 5)
300 sizer1_4.Add(self.ignores_box,1, wx.LEFT|wx.RIGHT, 5)
301
302 sizer1_5.Add(self.includes_label,0, wx.LEFT|wx.RIGHT, 5)
303 sizer1_5.Add(self.includes_box,1, wx.LEFT|wx.RIGHT, 5)
304
305 sizer1_6.Add(self.packages_label,0, wx.LEFT|wx.RIGHT, 5)
306 sizer1_6.Add(self.packages_box,1, wx.LEFT|wx.RIGHT, 5)
307
308 sizer1_7.Add(self.bundle_label,0, wx.LEFT|wx.RIGHT, 5)
309 sizer1_7.Add(self.bundle_box,1, wx.LEFT|wx.RIGHT, 5)
310
311 sizer1_8.Add(self.compressed,0, wx.LEFT|wx.RIGHT, 5)
312 sizer1_8.Add(self.xref,0, wx.LEFT|wx.RIGHT, 5)
313
314
315
316 sizer1.Add(sizer1_1, 0,wx.TOP|wx.BOTTOM,5)
317 sizer1.Add(sizer1_2, 0,wx.TOP|wx.BOTTOM,5)
318 sizer1.Add(sizer1_3, 0,wx.TOP|wx.BOTTOM,5)
319 sizer1.Add(sizer1_31, 0,wx.TOP|wx.BOTTOM,5)
320 sizer1.Add(sizer1_4, 0,wx.TOP|wx.BOTTOM,5)
321 sizer1.Add(sizer1_5, 0,wx.TOP|wx.BOTTOM,5)
322 sizer1.Add(sizer1_6, 0,wx.TOP|wx.BOTTOM,5)
323 sizer1.Add(sizer1_7, 0,wx.TOP|wx.BOTTOM,5)
324 sizer1.Add(sizer1_8, 0,wx.TOP|wx.BOTTOM,5)
325 sizer1.Add(self.ascii,0, wx.LEFT|wx.RIGHT, 5)
326 self.panel_2.SetAutoLayout(1)
327 self.panel_2.SetSizer(sizer1)
328
329
330 sizer2 = wx.BoxSizer(wx.VERTICAL)
331 sizer2_1 = wx.BoxSizer(wx.HORIZONTAL)
332
333 sizer2_1.Add(self.add_data_btn, 1, wx.LEFT|wx.RIGHT,50)
334 sizer2_1.Add(self.del_data_btn,1, wx.LEFT|wx.RIGHT,50)
335
336 sizer2.Add(sizer2_1, 0, wx.TOP|wx.BOTTOM,10)
337 sizer2.Add(self.data_grid,1,wx.EXPAND,0)
338
339 self.panel_3.SetAutoLayout(1)
340 self.panel_3.SetSizer(sizer2)
341
342
343
344 def AddDataFile(self,evt):
345 dlg = wx.FileDialog(
346 self, message=u"选择文件", defaultDir="",wildcard=u"数据文件(*.*)|*.*",
347 style=wx.OPEN | wx.CHANGE_DIR|wx.MULTIPLE
348 )
349
350 if dlg.ShowModal() == wx.ID_OK:
351 self.data_grid.SetValues(dlg.GetPaths())
352 dlg.Destroy()
353
354 def DelDataFile(self,evt):
355 self.data_grid.DelSelectedRows()
356
357
358 def AddPyFile(self,evt):
359 dlg = wx.FileDialog(
360 self, message=u"选择文件", defaultDir="",wildcard=u"Python文件(*.py,*.pyw)|*.py;*.pyw",
361 style=wx.OPEN | wx.CHANGE_DIR|wx.MULTIPLE
362 )
363
364 if dlg.ShowModal() == wx.ID_OK:
365 self.dir_text.SetValue(dlg.GetDirectory())
366 self.py_grid.SetValues(dlg.GetFilenames())
367
368 dlg.Destroy()
369
370
371 def OnMakeExe(self,evt):
372 self.output.Clear()
373 self.nb.SetSelection(3)
374 self.lasts = ''
375
376 dir = self.dir_text.GetValue()
377 par_d = self.GetPar()
378 opt_d = self.GetOpt()
379
380 MakeExe(dir,par_d,opt_d)
381
382
383 def GetPar(self):
384 par_d = {}
385 par_d["zipfile"] = "library.zip"
386 par_d["ctypes_com_server"]= []
387 par_d["com_server"] = []
388 par_d["service"] = []
389 par_d["console"] =[]
390 par_d["isapi"] = []
391 par_d["windows"] = []
392 par_d["console"] = []
393
394 par_d.update(self.py_grid.GetValueDict())
395 par_d["data_files"] = self.data_grid.GetValueDict().items()
396
397 return par_d
398
399 def GetOpt(self):
400 opt_d = {}
401
402 opt_d['optimize'] = self.optimize_box.GetValue().encode('utf-8')
403 opt_d['bundle_files'] = self.bundle_box.GetValue().encode('utf-8')
404
405 dist_dir = self.distdir_box.GetValue().encode('utf-8')
406 if dist_dir != '':
407 opt_d['dist_dir'] = dist_dir
408
409 excludes = self.excludes_box.GetValue().encode('utf-8')
410 if excludes != "":
411 opt_d['excludes'] = excludes
412
413 dllexcludes = self.dllexcludes_box.GetValue().encode('utf-8')
414 if dllexcludes != "":
415 opt_d['dll_excludes'] = dllexcludes
416
417 ignores = self.ignores_box.GetValue().encode('utf-8')
418 if ignores!= "":
419 opt_d['ignores'] = ignores
420
421 includes = self.includes_box.GetValue().encode('utf-8')
422 if includes != "":
423 opt_d['includes'] = includes
424
425 packages = self.packages_box.GetValue().encode('utf-8')
426 if packages != "":
427 opt_d['packages'] = packages
428
429
430 opt_d['compressed'] = int(self.compressed.GetValue())
431 opt_d['xref'] = int(self.xref.GetValue())
432 opt_d['ascii'] = int(self.ascii.GetValue())
433
434 return opt_d
435
436
437 def Exit(self,evt):
438 self.Close(True)
439
440 def OnCloseWindow(self, event):
441 self.Destroy()
442
443 def write(self,s):
444 pre = s[:8]
445 if pre=="byte-com" or pre=="skipping":
446 return
447 if s == self.lasts:
448 return
449
450 self.lasts = s
451 self.output.AppendText(s)
452
453 # end of class MyFrame
454
455 class MyApp(wx.App):
456 def OnInit(self):
457 frame_1 = MyFrame(u'PY2EXE GUI V'+__VER__)
458 frame_1.Show(True)
459 sys.stdout = frame_1
460 #sys.stderr = frame_1
461 self.SetTopWindow(frame_1)
462 return True
463
464 if __name__ == "__main__":
465 app = MyApp(0)
466 app.MainLoop()
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.