SoFunction
Updated on 2024-10-30

Example tutorial for developing Python's GUI program using wxPython and py2exe in Windows

Python is support for visual programming, i.e. writing gui programs, and you can use it to write your favorite desktop programs. Using wxPython to make the interface is very easy, just can't drag and drop controls like C#, you need to write your own code layout. After the completion of the preparation, due to the direct py file can no longer run on the computer without the installation of python, can there be a packaged into any computer can run the tool, looking for the Internet found the py2exe just to complete this function. wxPython and py2exe are open source free software.

Environment Configuration
wxPython: sourceforge project page/projects/py2exe/files/py2exe/0.6.9/
Just double-click the download and install, the installer will automatically install under the corresponding python\Scripts.
py2exe: official download homepage/
Again, double-click to install, and note that the download should correspond to the version of Python being used.
The following examples illustrate the simple use of wxPython and py2exe, respectively.

basic example
Filename::

# -*- coding: cp936 -*-
'''The MainWindow class accomplishes the simplest editing functionality, adding a main menu and two submenus (about and exit)'''
import wx
 
class MainWindow():
 '''Define a window class'''
 def __init__(self, parent, title):
  .__init__(self, parent, title=title, size=(300, 300))
   = (self, style=wx.TE_MULTILINE)
 
  ()
  (True)
 
 def setupMenuBar(self):
  ()
 
  menubar = ()
  menufile = ()
 
  mnuabout = (wx.ID_ABOUT, '&About', 'about this shit')
  mnuexit = (wx.ID_EXIT, 'E&xit', 'end program')
 
  (menufile, '&File')
 
  #Event Binding
  (wx.EVT_MENU, , mnuabout)
  (wx.EVT_MENU, , mnuexit)
   
  (menubar)
 
 def onAbout(self, evt):
   '''Event response for clicking about'''
   dlg = (self, 'This app is a simple text editor', 'About my app', )
   ()
   ()
 
 def onExit(self, evt):
   '''Click to exit'''
   (True)
app = (False)
frame = MainWindow(None, 'Small Editor')
() # Loop listening for events

After editing the change file, use py2exe to compile the Python scripts into Windows executables so that you don't need a Python interpreter. To use py2exe, you must first write a compilation script, and then run the compilation script through Python to compile other scripts into executables. The following is an example of a script that will be compiled into an executable file, with the filename:

import distutils
import py2exe
(windows=[''])

There is only one statement in except for importing the required modules:

(windows=[''])

The square brackets are the name of the script to be compiled, and the windows in front of it means that it will be compiled into a GUI program. If you want to compile a command line interface executable, just change windows to console, and if you need to compile the script as a Windows service, you can use the service option.
Once it's all edited, put and in the same path, cmd into that path and type:

 py2exe

If the following error is reported at runtime:
error: : No such file or directory
It's because it's not found, search for this file in the windows directory and copy it to the python installation directory under DLLs.
When packaging a PyQt project, the following error may be reported
ImportError: No module named sip
You just need to add --includes sip to the package, like this:
 py2exe --includes sip

At the end of the run, two directories, dist and build, are created in the path. The dist directory contains the compiled files. If you want to run the compiled program on another machine that does not have Python installed, just copy the dist directory to the other machine. Double-click it to run the program, as shown in the following figure.

 (300×300)

Build a GUI tool to calculate file md5 using wxPython
The widget ends up looking like the following, dragging a file onto it will automatically calculate its md5 and size

 (443×334)

Here is the full code

#coding:gbk
import wx
import optparse
import time,hashlib
import threading
import os

def checkMD5(pefile):
  try:
    f = open(pefile,'rb')
    data = ()
    m = hashlib.md5()
    (data)
    ()
    return ()
  except:
    return 'error'
  
def getFileSize(filename):
  try:
    size = int((filename))
    return size
  except:
    return 'error'
   
#Thread Functions
class FuncThread():
  def __init__(self, func, *params, **paramMap):
    .__init__(self)
     = func
     = params
     = paramMap
     = None
     = False

  def run(self):
     = (*, **)
     = True

  def getResult(self):
    return 

  def isFinished(self):
    return 

def doInThread(func, *params, **paramMap):
  t_setDaemon = None
  if 't_setDaemon' in paramMap:
    t_setDaemon = paramMap['t_setDaemon']
    del paramMap['t_setDaemon']
  ft = FuncThread(func, *params, **paramMap)
  if t_setDaemon != None:
    (t_setDaemon)
  ()
  return ft

class FileDropTarget():
  def __init__(self, filetext,md5tx,filesizetx):
    .__init__(self)
     = filetext
    self.md5tx = md5tx
     = filesizetx
   
  def OnDropFiles(self, x, y, fileNames):
    filename = fileNames[0].encode('gbk')
    print filename
    print type(filename)
    (filename)
    md5 = doInThread(checkMD5,filename)
    filesize = doInThread(getFileSize,filename)
    while True:
      if not ():
        (0.5)
      else:
        self.(())
        break
        
    while True:
      if not ():
        (0.5)
      else:
        (str(()))
        break

class Frame(): #Frame to initialize
  def __init__(self,title):
    .__init__(self,None,title=title,size = (400,300))
    boxSizer = ()
    
     = (self)
    
    # (,1,|) # Distance around, EXPAND expanded to all
    
    filepath = (,-1,"FileDir(Please drag the file into this dialog box)")
    filetext = (,-1,"",size=(350,20))
    
    md5st = (,-1,"MD5")
    md5tx = (,-1,size=(250,20))
    
    filesizest = (,-1,'FileSize')
    filesizetx = (,-1,size=(250,20))
    
    # hashst = (,-1,'Hash')
    # hashtx = (,-1,size=(250,20))
    
    (filepath,0,||,border=10)
    (filetext,0,|,border=10)
    ((-1,20))
    (md5st,0,|,border=10)
    (md5tx,0,|,border=10)
    ((-1,10))
    (filesizest,0,|,border=10)
    (filesizetx,0,|,border=10)
    # ((-1,10))
    # (hashst,0,|,border=10)
    # (hashtx,0,|,border=10)
    
    dropTarget = FileDropTarget(filetext,md5tx,filesizetx)
    ( dropTarget )
    
    (boxSizer)    
 
class App(): ## Inheritance
  def OnInit(self): ## Read initialization when not yet tuned up
     = Frame('MD5&size information')    
    ()
    (True)    
    return True

def killSelf(evt = None):
  ('taskkill /F /T /PID %d >NUL 2>NUL' % ())

if __name__ == '__main__':
  parser = ()
  parser.add_option('-x', '--no-update', dest = 'test', action = 'store_true', help = 'start without update')
  parser.add_option('-t', '--no-update-test', dest = 'test2', action = 'store_true', help = 'start without update debug')
  options, args = parser.parse_args()
  if :
    print("-x param")
  if options.test2:
    print("-t param")
  App(redirect = False).MainLoop()

A little bit of explanation:

class App and App().MainLoop() is a fixed way to write, under the class App there is a def OnInit method to initialize the main Frame, will be centered and Show() out, there is nothing to say, the main look at the definition of the Frame

This gadget uses a boxSizer to layout, for simplicity I only use a boxSizer, all the controls inside using VERTICAL (vertical) way to layout, if you want to put the MD5 and the back of the text box in the same line, then you need to add a horizontal boxSizer, and then that will be this horizontal boxSizer and then into the main boxSizer

boxSizer = () # Initialize a vertical boxSizer, which is also the main Sizer for the entire framework

 = (self) # Initialize a panel that is put after the control is placed

filepath = (,-1,"FileDir(Please drag the file into this dialog box)") 
filetext = (,-1,"",size=(350,20)) 
md5st = (,-1,"MD5") 
md5tx = (,-1,size=(250,20)) 
filesizest = (,-1,'FileSize') 
filesizetx = (,-1,size=(250,20))



The above is the initialization of the corresponding static text and text box, the first parameter in the method is its parent window, here that is, in fact, you can not use panel, but will be placed directly into the boxSizer
(filepath,0,||,border=10) 

Add the filepath to the main boxSizer, here at first I had some confusion, at first I always thought that all the controls into the panel first, and then put the panel into the boxSizer, but this is not right, but should be directly into the boxSizer, will be the parent class of the control is set to panel, and then after that There is no step to put the panel into the boxSizer, |,border=10 This parameter means that the control is 10 pixels away from the top and the left, and then use it to make it fill the area where it is located, I once thought, can I set it to be 10px away from the top and 20px away from the left, but I can't set it this way, the Add function can only have one The Add function can only have one border parameter, in other words, it can only be set to the same value, after that I'll look again to see if it can be realized.

((-1,20)) #This one is adding an empty distance, 20px from the top

dropTarget = FileDropTarget(filetext,md5tx,filesizetx) 
( dropTarget )

This is to add a drag-and-drop method to the window class, which is also a fixed way to write it.

The __init__ and OnDropFiles methods in class FileDropTarget above are also fixed methods, just with different handlers inside.

wxPython in some of the style and flag and other parameters in the layout of the use of some experience, as well as many of its controls and binding methods, to be proficient also need to put in some effort, the following two sites are considered to be a more detailed introduction to check more!