用python开发绚丽的windows程序 (1)

 python是一种快速开发的脚本语言,我在工作中经常用它,用它写一些项目辅助脚本之类。后来因项目需要,要把这些辅助功能组织一下,做成一个界面辅助工具。因为这些功能脚本都有了,所以就想直接用python,这样就不用再用别的语言实现一遍功能。但是, 我做项目都是用c++,界面库都是direct ui,没有用过python开发界面程序,而我也不想再去学python的界面库了。于是萌生一个想法,为什么不把direct ui和python结合起来呢?用direct ui做界面,而且只要美工好,界面想怎么好看都可以实现。而业务逻辑用python来写,做到快速开发。经过一段时间的摸索,终于搞出了一个框架。现在已经开源,放在https://code.google.com/p/py-ui4win/上。先上图,不过我不是做美工的,所以界面很简陋。



看看python是如何实现这个窗口的:
# coding=gbk

import string, os, commands, time
import threading
from distutils import dir_util
from shutil import make_archive
import win32api

from PyUI import *
from MsgBox import *
from PyFrameBase import *
import UICommon

def execute_dos_cmd(cmd):
    output = os.popen(cmd)
    for line in output:
        PyLog().LogText(line)

def PyThreadEncrypt(PyClassInstance, solution_path):
    try:
        PyClassInstance.EncryptAndPack(solution_path)
    except Exception, e:
        PyLog().LogText(str(e))

    PyLog().LogText('PyThreadEncrypt exit')

class MainFrame(PyFrameBase):
    def __init__(self):
        super(MainFrame, self).__init__()
        #PyFrameBase.__init__(self)
        self.msg = 'msg origer'

    #virtual LPCSTR GetSkinFile();
    def GetSkinFile(self):
        return 'main.xml'

    #virtual LPCSTR GetWindowClassName() const;
    def GetWindowClassName(self):
        return 'MainFrame'

    #virtual void OnPrepare(LPCSTR sendor, WPARAM wParam, LPARAM lParam);
    def OnPrepare(self, sendor, wParam, lParam):
        self.funcTabLayout = self.PyFindTabLayout("FunctionTabs")
        self.edtRomPath = self.PyFindControl("edtRomPath")
        self.txtDiagnose = self.PyFindControl("txtDiagnose")
        self.txtInstallLog = self.PyFindControl("txtInstallLog")
        self.LblStatus = self.PyFindControl("LblStatus")
        self.btnPyTest = self.PyFindControl("btnPyTest")
        self.LblStatus.SetText('辅助工具')
        #self.btnPyTest.SetVisible(False)
        self.btnPyTest.SetText('手机信息')
        PyWinUtils().SetTimer(self.GetHWnd(), 1, 10)

    #virtual LPCSTR GetWindowClassName() const;
    def TestObj(self, msg):
        self.msg = msg

    #virtual void OnNotify(LPCSTR sendor, LPCSTR sType, WPARAM wParam, LPARAM lParam);
    def OnNotify(self, sendor, sType, wParam, lParam):
        if sType == "click":
            if sendor == "BtnClose":
                #execute_dos_cmd('adb kill-server')
                self.ExitApp()

#            elif sendor == "btnPyTest":
#                self.funcTabLayout.SelectItem(0)
#                #UICommon.ShowMessageBox(self.GetHWnd(), '对话框标题', '你点击了对话框按钮')
#                infPath = PyWinUtils().SelectFile(self.GetHWnd(), "py(*.py)\0*.py\0")
#                if len(infPath) > 0:
#                    dirs = infPath.split('\\')
#                    dirname = dirs[-1]
#                    module = dirname.split('.')
#                    PyScript().RunPy(module[0], 'test')

            elif sendor == "btnPyTest":
                self.funcTabLayout.SelectItem(0)

            elif sendor == "btnEncrypt":
                self.funcTabLayout.SelectItem(3)

                solPath = PyWinUtils().SelectFolder(self.GetHWnd(), "请选择解决方案包:", "solutionpath")
                if len(solPath):
#                    PyWinUtils().SetWaitCursor()
#                    self.EncryptAndPack(solPath)
#                    PyWinUtils().SetArrowCursor()
                    t = threading.Thread(target=PyThreadEncrypt,args=(self,solPath))
                    t.start()
                    #t.join(1)

            elif sendor == "btnDriverDiagnose":
                self.funcTabLayout.SelectItem(3)
                self.diagnose()

            elif sendor == 'btnOpenLog':
                if os.path.isfile(PyWinUtils().GetExeDirectory() + '\\applog.ini'):
                    PyWinUtils().ShellExcute(0, 'open', PyWinUtils().GetExeDirectory() + '\\applog.ini', '', '', 1)
                else:
                    UICommon.ShowMessageBox(self.GetHWnd(), '错误', '日志文件不存在')
                #win32api.ShellExecute(0, 'open', 'e:\\applog.ini', None, "", 1)

            elif sendor == 'btnClearLog':
                self.txtDiagnose.SetText('')
                if os.path.isfile(PyWinUtils().GetExeDirectory() + '\\applog.ini'):
                    os.remove(PyWinUtils().GetExeDirectory() + '\\applog.ini')
                #win32api.ShellExecute(0, 'open', 'e:\\applog.ini', None, "", 1)

            elif sendor == 'btnDriverInstall':
                self.funcTabLayout.SelectItem(1)
                self.txtInstallLog.SetText('')

            elif sendor == 'btnChooseInf':
                infPath = PyWinUtils().SelectFile(self.GetHWnd(), "inf(*.inf)\0*.inf\0")
                if len(infPath) > 0:
                    self.edtRomPath.SetText(infPath)

            elif sendor == 'btnInstallDriver':
                msg = self.edtRomPath.GetText()
                if len(msg) > 0:
                    PyWinUtils().SetWaitCursor()
                    DriverInstaller().InstallDriverFromInf(msg)
                    PyWinUtils().SetArrowCursor()
                    self.txtInstallLog.SetText('安装完成. 请重新检测驱动状态.')
                else:
                    mbox1 = PyFrameCreator()
                    UICommon.ShowMessageBox(self.GetHWnd(), '错误', '没有选择inf文件')

    def AppendAndLog(self, line):
        PyLog().LogText( line)
        msg = self.txtDiagnose.GetText()
        self.txtDiagnose.SetText(msg + '\n' + line)

    def ShowAndLog(self, line):
        PyLog().LogText( line)
        self.txtDiagnose.SetText(line)

    def diagnose(self):
        PyWinUtils().SetCurrentDirectoryToExePath()
        os.system('adb devices')
        #pid = subprocess.Popen(["adb", "devices"]).pid
        #subprocess.Popen("adb devices")
        #self.ShowAndLog( "\n")
        ISOTIMEFORMAT='%Y-%m-%d %X'
        self.ShowAndLog(time.strftime( ISOTIMEFORMAT, time.localtime() ))
        self.AppendAndLog( "----------------------------------------------驱动检测----------------------------------------------")
        self.AppendAndLog(DriverStatus().DriverDiagnose())
        self.AppendAndLog( "----------------------------------------------手机模式检测----------------------------------------------")
        self.AppendAndLog( 'adb devices 输出:')
        output = os.popen('adb devices')
        for line in output:
            self.AppendAndLog( line)

        self.AppendAndLog( 'fastboot devices 输出:')
        output = os.popen('fastboot devices')
        for line in output:
            self.AppendAndLog( line)

        self.AppendAndLog( "----------------------------------------------手机设备检测----------------------------------------------")
        output = os.popen(r'devcon find usb\*')
        for line in output:
            if line.find('VID_04E8') != -1:
                line = line.replace('\n', '')
                self.AppendAndLog(line)
                self.AppendAndLog('三星')
            elif line.find('VID_19D2') != -1:
                line = line.replace('\n', '')
                self.AppendAndLog( line)
                self.AppendAndLog( '中兴')
            elif line.find('VID_19D2') != -1:
                line = line.replace('\n', '')
                self.AppendAndLog( line)
                self.AppendAndLog( '中兴')
            elif line.find('VID_12D1') != -1:
                line = line.replace('\n', '')
                self.AppendAndLog( line)
                self.AppendAndLog( '华为')
            else:
                line = line.replace('\n', '')
                self.AppendAndLog( line)

            if line.find('ADB') != -1:
                self.AppendAndLog( "***********************")

        return True

    def generateConfig(self, solutionPath):
        flag = ''
        commonFile=file(solutionPath + '\\common.lua','r')
        shuajiFile=file(solutionPath + '\\shuaji.lua','r+')

        temp=file(solutionPath + '\\tmp.lua','w+')
        for line in commonFile:
            temp.write(line)
        temp.write('\n')
        for line in shuajiFile:
            temp.write(line)
        temp.write('\n')
        temp.flush()
        temp.close()

        shuajiFile.close()
        os.remove(solutionPath + '\\shuaji.lua')
        if os.path.isfile(solutionPath + '\\config.lua'):
            os.remove(solutionPath + '\\config.lua')
        os.rename(solutionPath + '\\tmp.lua', solutionPath + '\\config.lua')

    def generatebackup(self, solutionPath):
        flag = ''
        commonFile=file(solutionPath + '\\common.lua','r')
        shuajiFile=file(solutionPath + '\\systembackup.lua','r+')

        temp=file(solutionPath + '\\tmp.lua','w+')
        for line in commonFile:
            temp.write(line)
        temp.write('\n')
        for line in shuajiFile:
            temp.write(line)
        temp.write('\n')
        temp.flush()
        temp.close()

        shuajiFile.close()
        os.remove(solutionPath + '\\systembackup.lua')
        os.rename(solutionPath + '\\tmp.lua', solutionPath + '\\systembackup.lua')

    def generaterecovery(self, solutionPath):
        flag = ''
        commonFile=file(solutionPath + '\\common.lua','r')
        shuajiFile=file(solutionPath + '\\systemrestore.lua','r+')

        temp=file(solutionPath + '\\tmp.lua','w+')
        for line in commonFile:
            temp.write(line)
        temp.write('\n')
        for line in shuajiFile:
            temp.write(line)
        temp.write('\n')
        temp.flush()
        temp.close()

        shuajiFile.close()
        os.remove(solutionPath + '\\systemrestore.lua')
        os.rename(solutionPath + '\\tmp.lua', solutionPath + '\\systemrestore.lua')

    def EncryptAndPack(self, solutionPath):
        PyWinUtils().SetCurrentDirectoryToExePath()
        ISOTIMEFORMAT='%Y-%m-%d %X'
        self.ShowAndLog(time.strftime( ISOTIMEFORMAT, time.localtime() ))
        self.AppendAndLog('打包目录 = %s' % solutionPath )

        if not os.path.isfile(solutionPath + '\\shuaji.lua'):
            self.AppendAndLog('%s 不是解决方案目录' % solutionPath )
            return

        dirs = solutionPath.split('\\')
        dirname = dirs[-1]
        self.AppendAndLog( dirname)
        tmpdir = solutionPath + '_tmp'
        PyLog().LogText( '1')
        if os.path.isdir(tmpdir):
            dir_util.remove_tree(tmpdir)
        PyLog().LogText( '2')
        PyWinUtils().CreateDirectory(tmpdir)
        #dir_util.mkpath(tmpdir)
        PyLog().LogText( '3')
#        time.sleep(10)
        PyLog().LogText( '3.5')
         i = 0
         while i<100:
             i = i + 1
             self.AppendAndLog('%d' % i )
             time.sleep(1)

        self.AppendAndLog('成功')

def PyAppInit():
    pyFrameObj = PyFrameCreator()
    obj = pyFrameObj.CreateForm(0, 'PyMain', 'MainFrame')
    obj.TestObj('msg changed')
    pyFrameObj.ShowModal()



代码说明:
def PyAppInit():
    pyFrameObj = PyFrameCreator()
    obj = pyFrameObj.CreateForm(0, 'PyMain', 'MainFrame')
    obj.TestObj('msg changed')
    pyFrameObj.ShowModal()
这是整个程序的入口,obj = pyFrameObj.CreateForm(0, 'PyMain', 'MainFrame') 意思是说用PyMain模块中的MainFrame创建一个窗口,pyFrameObj.ShowModal()就是显示这个窗口

    def GetSkinFile(self):
        return 'main.xml'
返回对应的皮肤文件名字,一定要正确才行

    def GetWindowClassName(self):
        return 'MainFrame'
返回这个类的名字,一定要正确才行


    def OnPrepare(self, sendor, wParam, lParam):
        self.funcTabLayout = self.PyFindTabLayout("FunctionTabs")
        self.edtRomPath = self.PyFindControl("edtRomPath")
        self.txtDiagnose = self.PyFindControl("txtDiagnose")
        self.txtInstallLog = self.PyFindControl("txtInstallLog")
        self.LblStatus = self.PyFindControl("LblStatus")
        self.btnPyTest = self.PyFindControl("btnPyTest")
        self.LblStatus.SetText('辅助工具')
        #self.btnPyTest.SetVisible(False)
        self.btnPyTest.SetText('手机信息')
        PyWinUtils().SetTimer(self.GetHWnd(), 1, 10)
这段代码的作用是取得一些控件并在界面上设置一些信息

    #virtual void OnNotify(LPCSTR sendor, LPCSTR sType, WPARAM wParam, LPARAM lParam);
    def OnNotify(self, sendor, sType, wParam, lParam):
        if sType == "click":
            if sendor == "BtnClose":
                #execute_dos_cmd('adb kill-server')
                self.ExitApp()
这段代码是说如果用户click了BtnClose,那么程序退出。click是表示click事件,sendor表示是哪个控件



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值