Python写的简易代码统计工具(3)

Python写的简易代码统计工具(3)

本文介绍代码统计工具的窗口界面,使用wxPython库实现了简易界面,见下图:

Python写的简易代码统计工具(3)_第1张图片

用wxPython编写界面,可以分为以下四步:
第一步:搭好框架,定义wx.App类和wx.Frame类的子类。
第二步:创建控件。
第三步:绑定消息。
第四步:编写响应消息的函数。
界面编写只懂些皮毛,所以这个程序只是实现了功能,并没有什么出彩的地方。
下面是CodeCounterW.pyw文件中的代码:

#  -*- coding: cp936 -*-
'''
这是一个用Python写的简易代码统计工具。
作者:lemene
网址:http://www.cppblog/lemene
'''
import  wx
import  os
from  counter  import  CodeCounter

#  代码类型和对应的文件后缀名
codetyps  =  [[ ' C ' , ' Python ' ],
            [
' .c,.cpp,.h ' , ' .py ' ]]

class  ResultList(wx.ListCtrl):
    
''' 显示结果的控件 '''
    
def   __init__ (self, parent, ID =- 1 , pos = wx.DefaultPosition,
                 size
= wx.DefaultSize, style = wx.LC_REPORT):
        wx.ListCtrl.
__init__ (self, parent, ID, pos, size, style)
        self.InsertColumn(0, 
" 文件名 " )
        self.InsertColumn(
1 " 总行数 " )
        self.InsertColumn(
2 " 代码 " )
        self.InsertColumn(
3 " 注释 " )
        self.InsertColumn(
4 " 空行 " )

    
def  Clear(self):
        
''' 清空结果 '''
        self.DeleteAllItems()

    
def  ShowResult(self, results):
        
''' 显示结果 '''
        i 
=  0
        
for  res  in  results:
            self.InsertStringItem(i, res[0])
            self.SetStringItem(i, 
1 , str(res[ 1 ][ 4 ]))
            self.SetStringItem(i, 
2 , str(res[ 1 ][ 1 ] + res[ 1 ][ 3 ])) 
            self.SetStringItem(i, 
3 , str(res[ 1 ][ 2 ] + res[ 1 ][ 3 ])) 
            self.SetStringItem(i, 
4 , str(res[ 1 ][0]) )

class  CounterFrame(wx.Frame):
    
''' 程序界面 '''
    
def   __init__ (self, parent, title):
        wx.Frame.
__init__ (self, parent,  - 1 , title, size = ( 495 435 ),
                          style
= wx.DEFAULT_FRAME_STYLE  ^  wx.RESIZE_BORDER)

        
#  添加界面控件
        panel  =  wx.Panel(self)
        
#  第一行控件
        text1  =  wx.StaticText(panel,  - 1 " 代码类型: " ,style = wx.ALIGN_RIGHT)
        cb1 
=  wx.ComboBox(panel,  - 1 , codetyps[0][0],choices = codetyps[0],style = wx.CB_READONLY, size = ( 100 , - 1 ))
        text2 
=  wx.StaticText(panel,  - 1 " 后缀名: " )
        cb2 
=  wx.ComboBox(panel,  - 1 , codetyps[ 1 ][0],choices = codetyps[ 1 ],size = ( 190 , - 1 ))
        
        sizer1 
=  wx.BoxSizer(wx.HORIZONTAL)
        sizer1.Add(text1, 0, wx.RIGHT
| wx.LEFT,  10 )
        sizer1.Add(cb1, 0, wx.RIGHT
| wx.LEFT,  10 )
        sizer1.Add(text2, 0, wx.RIGHT
| wx.LEFT,  10 )
        sizer1.Add(cb2, 0, wx.RIGHT
| wx.LEFT,  10 )
        
        
#  第二行控件
        rb  =  wx.RadioBox(panel,  - 1 "" , wx.DefaultPosition, wx.DefaultSize,
                [
' 目录 ' , ' 文件 ' ])
        ckb 
=  wx.CheckBox(panel,  - 1 " 包括子目录 " )
        fordtx 
=  wx.TextCtrl(panel,  - 1 "" , size = ( 190 - 1 ))
        openfdbtn 
=  wx.Button(panel,  - 1 " " , size = ( 25 , 25 ))
        
        sizer2 
=  wx.BoxSizer(wx.HORIZONTAL)
        sizer2.Add(rb, 0, wx.RIGHT
| wx.LEFT | wx.ALIGN_CENTER ,  10 )
        sizer2.Add(ckb, 0, wx.RIGHT
| wx.LEFT | wx.ALIGN_CENTER ,  10 )
        sizer2.Add(fordtx, 0, wx.RIGHT
| wx.LEFT | wx.ALIGN_CENTER ,  10 )
        sizer2.Add(openfdbtn, 0, wx.RIGHT
| wx.LEFT | wx.ALIGN_CENTER ,  10 )

        
#  第三行控件
        rzlist  =  ResultList(panel,  - 1 , size = ( 470 , 250 ))

        
#  第四行控件
        countbtn  =  wx.Button(panel,  - 1 " 统计 " )
        savebtn 
=  wx.Button(panel,  - 1 " 保存 " )
        aboutbtn 
=  wx.Button(panel,  - 1 " 关于 " )
        sizer4 
=  wx.BoxSizer(wx.HORIZONTAL)
        sizer4.Add(countbtn, 0, wx.RIGHT
| wx.LEFT,  40 )
        sizer4.Add(savebtn, 0, wx.RIGHT
| wx.LEFT,  40 )
        sizer4.Add(aboutbtn, 0, wx.RIGHT
| wx.LEFT,  40 )

        
#  排列这四行控件
        sizer  =  wx.BoxSizer(wx.VERTICAL)
        sizer.Add(sizer1, 0, wx.ALL, 
8 )
        sizer.Add(sizer2, 0, wx.ALL, 
8 )
        sizer.Add(rzlist, 0, wx.ALL, 
8 )
        sizer.Add(sizer4, 0, wx.ALL, 
8 )
        panel.SetSizer(sizer)
        panel.Layout()

        
#  控件消息
        self.Bind(wx.EVT_BUTTON, self.OnOpenForD, openfdbtn)
        self.Bind(wx.EVT_BUTTON, self.OnCount, countbtn)
        self.Bind(wx.EVT_BUTTON, self.OnSave, savebtn)
        self.Bind(wx.EVT_BUTTON, self.OnAbout, aboutbtn)
        self.Bind(wx.EVT_COMBOBOX, self.OnChoiceCodeType, cb1)
        
        
#  保存控件引用
        self.codetype_cb  =  cb1
        self.filetype_cb 
=  cb2
        self.fordname_tx 
=  fordtx
        self.ford_rb 
=  rb
        self.subdir_ckb 
=  ckb
        self.result_list 
=  rzlist

        
#  存放结果
        self.result  =  []

    
def  OnOpenForD(self, evn):
        
''' 得到需要统计的文件或目录的路径 '''
        
if  self.ford_rb.GetSelection()  ==  0:
            dlg 
=  wx.DirDialog(self,  " 选择目录: " ,
                               style
= wx.DD_DIR_MUST_EXIST
                               )
        
else :
            dlg 
=  wx.FileDialog(
                self, message
= " 选择文件 " ,
                defaultDir
= "" ,
                defaultFile
= "" ,
                style
= wx.OPEN  |  wx.CHANGE_DIR
                )
        
if  dlg.ShowModal()  ==  wx.ID_OK:
            self.fordname_tx.SetValue(dlg.GetPath())
            
        dlg.Destroy()
        
    
def  OnCount(self, evn):
        
''' 统计代码 '''
        self.result_list.Clear()
        self.result 
=  []

        
try :
            counter 
=  CodeCounter(codefiles = [])
            self.SetCounter(counter)
            counter.Count(self.result)
        
except :
            self.ErrMsg(
" 输入错误 " )            
        
        all 
=  [0,0,0,0,0]
        
for  ele  in  self.result:
            
for  i  in  range(len(ele[ 1 ])):
                all[i] 
+=  ele[ 1 ][i]
        self.result.append([
' 总计 ' , all])
        
        self.result_list.ShowResult(self.result)

    
def  OnSave(self, evn):
        
''' 保存统计结果 '''
        dlg 
=  wx.FileDialog(
            self, message
= " Choose a file " ,
            defaultDir
= "" ,
            defaultFile
= "" ,
            wildcard
= " TXT files (*.txt)|*.txt|All files (*.*)|*.* " ,
            style
= wx.SAVE 
            )
        
        
if  dlg.ShowModal()  ==  wx.ID_OK:
            f 
=  open(dlg.GetPath(),  ' wt ' )
            
for  res  in  self.result:
                f.write((
" %d\t%d\t%d\t%d\t%s\n "   %  (res[ 1 ][ 4 ],res[ 1 ][ 1 ] + res[ 1 ][ 3 ],
                        res[
1 ][ 2 ] + res[ 1 ][ 3 ], res[ 1 ][0], res[0])))
                
        dlg.Destroy()

    
def  OnChoiceCodeType(self, evn):
        idx 
=  self.codetype_cb.GetSelection()
        self.filetype_cb.SetSelection(idx)

    
def  OnAbout(self, evn):
        dlg 
=  wx.MessageDialog(self,  __doc__ ,
                               
' About ' ,
                               wx.OK 
|  wx.ICON_INFORMATION
                               )
        dlg.ShowModal()
        dlg.Destroy()

    
def  ErrMsg(self,msg):
        dlg 
=  wx.MessageDialog(self, msg,
                               
' Err ' ,
                               wx.OK 
|  wx.ICON_INFORMATION
                               )
        dlg.ShowModal()
        dlg.Destroy()
        
    
def  SetCounter(self, counter):
        
''' 从界面读入配置设置统计工具 '''
        
if  self.subdir_ckb.IsChecked():  #  是否包含子目录
            counter.SetLevel( - 1 )

        
if  self.fordname_tx.GetValue()  !=   '' :
            
#  判断是选择文件还是目录
            t  =   ' f '      
            
if  self.ford_rb.GetSelection()  ==  0:
                t 
=   ' d '
            counter.AddCodeFiles(t, self.fordname_tx.GetValue())

        
#  设置要统计的代码类型
        val  =  self.codetype_cb.GetValue()
        
if  val  ==   ' C ' :
            counter.SetCodeType(
' c ' )
        
elif  val  ==   ' Python ' :
            counter.SetCodeType(
' py ' )
        
        
#  设置后缀名
        counter.SetModes(self.filetype_cb.GetValue())

class  CounterApp(wx.App):
    
def  OnInit(self):
        frame 
=  CounterFrame(None,  " 代码计算器 " )
        self.SetTopWindow(frame)
        frame.Show(True)
        
return  True

if   __name__   ==   ' __main__ ' :
    app 
=  CounterApp(redirect = False)
    app.MainLoop()
        

你可能感兴趣的:(Python写的简易代码统计工具(3))