我的开发环境:
python2.7.5 下载地址 http://www.python.org/download/releases/2.7.5/
WMI-1.4.6.win32.exe 下载地址 https://pypi.python.org/pypi/WMI
wxPython2.9-win32-docs-demos-2.9.4.0.exe 下载地址 http://www.wxpython.org/download.php
wxPython2.9-win32-2.9.4.0-py27.exe 下载地址 http://www.wxpython.org/download.php
用到了标准库WMI、wx,需要用户自己下载安装WMIba包、wxpython包。
功能:获取本地所有磁盘,一次扫描所有图片格式的文件,包括'.bmp','jpeg','.gif','.psd','.png','.jpg'格式。
获取图片的全路径,通过logging模块将扫描结果写入文件scanpicture.log。用户也可导出该log文件,保存到自己选择的目录
自定义扫描功能暂时未添加。
扫描过程是通过threading.Thread模块开启线程实现。
效果截图:
重点:
1、如何获取本地所有磁盘信息?
通过WMI模块,objWmi = wmi.WMI(); 产生一个对象,[disk.Caption for disk in objWmi.Win32_LogicalDisk(DriveType=3)]即本地的磁盘列表,如[u'C:', u'D:', u'E:', u'F:'],还可通过disk.FreeSpace, disk.Size分别获取磁盘可用空间、磁盘大小,单位是byte
2、如何快速全路径扫描?
使用os.walk()即可
3、如何在扫描过程中停止扫描?
使用线程实现。
下面是详细代码:
1 #! /usr/bin/env python 2 #coding: utf-8 3 4 import wmi 5 import wx 6 import logging 7 import time 8 import os 9 import threading 10 from shutil import copy 11 12 13 logging.basicConfig(level=logging.DEBUG, 14 format='%(asctime)s %(message)s', 15 datefmt='%Y-%m-%d_%H:%M:%S.%U', 16 filename='scanpicture.log', 17 filemode='w') 18 19 # 自定义日志Handler来接收日志数据 20 class MyLogHandler(logging.Handler): 21 def __init__(self,obj): 22 logging.Handler.__init__(self); 23 self.Object = obj; 24 25 def emit(self,record): 26 if record.levelno<self.level: return; 27 tstr = time.strftime('%Y-%m-%d_%H:%M:%S.%U'); 28 self.Object.AppendText("[%s] %s "%(tstr,record.getMessage())); 29 30 class MyFrame(wx.Frame): 31 def __init__(self): 32 wx.Frame.__init__(self,parent=None,title="扫描本地图片", 33 pos=(100,100),size=(1180,600)); 34 c = wmi.WMI(); 35 self.lstDisks = [disk.Caption for disk in c.Win32_LogicalDisk (DriveType=3)]; 36 self.buildUI(); 37 self.CenterOnScreen() 38 39 def buildUI(self): 40 self.box1 = wx.BoxSizer(wx.HORIZONTAL); 41 self.text = wx.TextCtrl(parent=self,style=wx.TE_AUTO_SCROLL|wx.TE_MULTILINE); 42 self.box1.Add(self.text,1,wx.ALL|wx.EXPAND,5,5); 43 self.box2 = wx.BoxSizer(wx.VERTICAL); 44 self.btn1 = wx.Button(parent=self,label="全盘扫描"); 45 self.box2.Add(self.btn1,1,wx.ALL|wx.EXPAND,5,0); 46 self.btn2 = wx.Button(parent=self,label="停止扫描"); 47 self.box2.Add(self.btn2,1,wx.ALL|wx.EXPAND,5,0); 48 self.btn3 = wx.Button(parent=self,label="自定义扫描"); 49 self.box2.Add(self.btn3,1,wx.ALL|wx.EXPAND,5,0); 50 self.btn4 = wx.Button(parent=self,label="导出数据"); 51 self.box2.Add(self.btn4,1,wx.ALL|wx.EXPAND,5,0); 52 self.box1.Add(self.box2,0,wx.NORMAL,0,0); 53 self.SetSizer(self.box1); 54 55 self.text.SetEditable(False); 56 self.btn1.Enable(); 57 self.btn2.Disable(); 58 59 self.btn1.Bind(wx.EVT_BUTTON,self.OnButton1Event); 60 self.btn2.Bind(wx.EVT_BUTTON,self.OnButton2Event); 61 self.btn3.Bind(wx.EVT_BUTTON,self.OnButton3Event); 62 self.btn4.Bind(wx.EVT_BUTTON,self.OnButton4Event); 63 64 handler = MyLogHandler(self.text); 65 logging.getLogger().addHandler(handler); 66 67 def OnButton1Event(self,event): 68 self.btn1.Disable(); 69 self.btn2.Enable(); 70 # 检测日志,超过指定日志大小,就清空日志列表 71 if len(self.text.GetValue())>1024: 72 self.text.SetValue(''); 73 self.scan = ScanPicture(self.lstDisks) 74 # daemonic为True时,表示主线程结束时子线程也要跟着退出 75 self.scan.setDaemon(True) 76 self.scan.start() 77 78 def OnButton2Event(self,event): 79 self.scan.StopScan() 80 self.btn1.Enable(); 81 self.btn2.Disable(); 82 print(os.getpid()) 83 84 def OnButton3Event(self,event): 85 ''' 86 @summary: 自定义扫描 87 ''' 88 pass 89 90 def OnButton4Event(self,event): 91 ''' 92 @summary: 将扫描结果导出,并保存到指定地方 93 ''' 94 userPath = os.getcwd().decode('gb2312') 95 print(userPath) 96 dlg = wx.DirDialog(self, "Choose a directory:", 97 defaultPath=userPath, 98 style=wx.DD_DEFAULT_STYLE 99 #| wx.DD_DIR_MUST_EXIST 100 #| wx.DD_CHANGE_DIR 101 ) 102 if dlg.ShowModal() == wx.ID_OK: 103 savepath = dlg.GetPath() 104 if savepath == userPath: 105 return 106 try: 107 copy(os.path.join(userPath,'scanpicture.log'), savepath) 108 strResult = "导出文件成功!" 109 except: 110 strResult = "导出文件失败!" 111 dlg = wx.MessageDialog(self, strResult, 112 'A Message Box', 113 wx.OK | wx.ICON_INFORMATION 114 #wx.YES_NO | wx.NO_DEFAULT 115 #| wx.CANCEL | wx.ICON_INFORMATION 116 ) 117 dlg.ShowModal() 118 dlg.Destroy() 119 120 class ScanPicture(threading.Thread): 121 def __init__(self, lstDisks): 122 threading.Thread.__init__(self) 123 self.dicks = lstDisks 124 self.flag = True 125 126 def run(self): 127 for path in self.dicks: 128 self.GetScanResult(path) 129 130 def GetScanResult(self, path): 131 ''' 132 @summary: 获取扫描结果 133 ''' 134 lstImgExt = ['.bmp','jpeg','.gif','.psd','.png','.jpg']; 135 for root, dirs, files in os.walk(path, topdown=False): 136 for onefile in files: 137 if not self.flag: 138 return 139 strPath = os.path.join(root, onefile); 140 if strPath[-4:] in lstImgExt: 141 logging.error(strPath); 142 143 def StopScan(self): 144 ''' 145 @summary: 设置flag标志位,停止扫描 146 ''' 147 self.flag = False 148 149 class MyApp(wx.App): 150 def OnInit(self): 151 self.win = MyFrame(); 152 self.win.Show(True); 153 self.SetTopWindow(self.win); 154 return True; 155 156 if __name__ == "__main__": 157 app = MyApp(); 158 app.MainLoop();
注:第一篇随笔,给自己加油,希望自己能加倍努力,实现理想。