python编写windows桌面程序(小Demo)

来源:互联网 发布:autodesk软件卸载工具 编辑:程序博客网 时间:2024/06/09 19:37

前段时间,由于公司业务需求,需要导出腾讯云中的对象存储服务bucket下指定文件夹所有apk文件的下载地址和一些文件夹创建的操作,但因文件较多,人工去遍历肯定不可取,因此就想着撸个python桌面程序。功能比较简单,正好以此记录下学习过程。
1. 开发所需软件
python2.7 , wxPython3.0-for-py2.7 , py2exe0.6.9-for-py2.7 , setuptools0.6-for-py2.7
注:由于腾讯云的对象存储服务python的sdk使用的是2.7版本,加上python3没有向前兼容,因此这里选择2.7版本; wxPython主要是针对python在win下而产生的控件库; py2exe主要是将py文件包装为windows下可执行的exe文件; setuptools主要是用来安装一些第三方python库的时候使用的,当然也可以用pip。上述的软件python版本需要一致。
2. python环境配置
在环境变量添加PYTHON_HOME,地址指向Python安装目录,将PYTHON_HOME添加到Path中,并指向Python安装目录的子目录Scripts
3. 实现需求
准备工作: 下载对象存储服务Python端SDK,使用pip安装 pip install qcloud_cos_v4
具体实现:先看看最后的效果图

界面GUI:

     def setupMenuBar(self):            self.CreateStatusBar()            menubar = wx.MenuBar()            menufile = wx.Menu()            mnuabout = menufile.Append(wx.ID_ABOUT, u'&关于', 'about this shit')            mnuexit = menufile.Append(wx.ID_EXIT, u'&退出', 'end program')            menubar.Append(menufile, u'&操作')            self.Bind(wx.EVT_MENU, self.onAbout, mnuabout)            self.Bind(wx.EVT_MENU, self.onExit, mnuexit)            self.SetMenuBar(menubar)      def createUI(self):            panel = wx.Panel(self,-1)            config_channel=wx.StaticText(panel,-1,u"1.配置apk渠道信息:",(10,10))            bt3 = wx.Button(panel,-1,u'一键生成渠道包',(30,40))            userLabel=wx.StaticText(panel,-1,u"2.获取云端指定目录下所有apk下载地址:",(10,90))            self.userText=wx.TextCtrl(panel,-1,"",(120,120),size=(160,-1))            #设置默认的插入点,整数索引,开始位置为0            self.userText.SetInsertionPoint(120)            inputdic=wx.StaticText(panel,-1,u"输入目录名:",(30,120))            bt4 = wx.Button(panel,-1,u'立即获取',(320,120))            tv_download_url=wx.StaticText(panel,-1,u"3.生成apk下载地址:",(10,160))            tv_show_url=wx.StaticText(panel,-1,u"进度:",(30,200))            self.et_url=wx.TextCtrl(panel,-1,"",(90,200),size=(450,-1),style=wx.TE_MULTILINE)            self.et_url.SetInsertionPoint(90)            bt3.Bind(wx.EVT_BUTTON,self.createChannelInfo)            bt4.Bind(wx.EVT_BUTTON,self.createDirectory)

主要生成了菜单栏操作按钮和主界面一些布局控件,按钮和文本等

业务逻辑:
获取apk文件下载地址

    def createDirectory(self,evt):      self.et_url.SetValue(u'正在生成地址中,请稍后...')      #订阅线程回调      Publisher.subscribe(self.getDirFileListCallback, "getdirfilelist")      global apk_dir      apk_dir = self.userText.GetValue().replace(' ','')      GetDirFileListThread(apk_dir)    #获取指定目录的具体信息,包括所有文件的下载地址    class GetDirFileListThread(Thread):    #----------------------------------------------------------------------        def __init__(self,arg1):          """初始化"""          Thread.__init__(self)          self.str1 = arg1          self.start()    # 开启线程        def run(self):          # 配置信息从腾讯云后台获取          cos_client = CosClient(appid, secret_id, secret_key)          request = ListFolderRequest(bucket, u'/'+self.str1+'/')          list_folder_ret = cos_client.list_folder(request)          s = json.loads(json.dumps(list_folder_ret))          if s[u'message'] == u'SUCCESS':            wx.CallAfter(Publisher.sendMessage, "getdirfilelist", s)          else :            wx.CallAfter(Publisher.sendMessage, "getdirfilelist", 'error:'+s[u'message'])        #获取目录下文件信息成功与失败的回调,这里仅示范成功回调             def getDirFileListCallback(self, msg):         cloud_files = msg.data[u'data'][u'infos']         download_url = './apk_channel/'+apk_dir+'_url.txt'         if os.path.exists(download_url) :            os.remove(download_url)         url_file = open(download_url,'a')         # 将获取到的文件下载地址写入文本         for  i in range(0, len(cloud_files)):            logging.info(cloud_files[i][u'source_url'])            url_file.write(u''+str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))+'\t'+cloud_files[i][u'source_url']+'\n\n')             self.et_url.SetValue(u'已完成'+str(i+1)+'/'+str(len(cloud_files))+u',存放于:'+os.getcwdu()+os.sep+'apk_channel'+os.sep+apk_dir+'_url.txt')         url_file.close() 

这里并不是直接同步获取下载地址,同步获取容易造成ANR,UI界面卡死,因此采用异步回调的方式,这里使用的是python中的Publisher库配合子线程处理网络请求。Publisher就好比安卓中的EventBus,发布与订阅。

创建App实例:

class App(wx.App):  # 定义一个带有 OnInit()方法的 wx.App的子类    def OnInit(self):          self.frame = MainWindow(None, u'Demo') # 定义窗口名称        self.frame.Show()        self.SetTopWindow(self.frame)        return True#程序入口if __name__ == '__main__':    app = App()    app.MainLoop() # 程序主入口  class MainWindow(wx.Frame):  '''定义一个窗口类'''  def __init__(self, parent, title):    wx.Frame.__init__(self, parent, title=title, size=(600, 600))    self.setupMenuBar()     self.Centre()    self.SetCursor( wx.StockCursor( wx.CURSOR_HAND ) )      self.icon = wx.Icon('logo.ico',wx.BITMAP_TYPE_ICO) #设置logo    self.SetIcon(self.icon)    self.filepath = ''    self.filerename = ''    self.Bind(wx.EVT_CLOSE, self.closewindow)    self.createUI()

打包py脚本:
安装py2exe, 编写setup.py文件,代码如下:

# coding=utf-8 import distutilsimport py2exeoptions = {    "py2exe": {"packages": ['wx.lib.pubsub']}}distutils.core.setup(windows=[{"script": "Demo.py", "icon_resources": [(1, "start.ico")] }], options=options , version = "1.0.0",author = 'jeffer',author_email = 'jeffer7150@163.com')

保存, 执行该setup.py脚本,即可在该目录下生成dist文件夹,里面即生成了Demo.exe文件。

0 0