酷! 给python脚本配一个动画界面

python黑乎乎的命令行输出太乏味了。本篇用pyui4win开发一个有动画界面的python执行程序。 当用户选择执行时,动画开启,开始转圈,直到python功能函数执行完成。在执行过程中,界面上的信息也在不断更新。 为了让界面不被卡住,采用了多线程技术。 执行的功能函数在非界面线程执行。从结果可以看到,界面上的动画很流畅。

目录

  • 执行效果
  • 界面设计
  • 代码编辑与调试
  • 使用多线程保证界面流畅
  • 执行程序
  • 这是怎么回事?

执行效果

用户选择执行时,动画开启,开始转圈,直到python功能函数执行完成。在执行过程中,界面上的信息也在不断更新。最后动画停止。

执行效果

界面设计

主界面xml为MainFrame.xml,在skin中。所有的界面xml和界面图片都在该目录下。

在界面设计中,布局注意3点;一个是类似的空控件,它们是填充控件。 注意这个例子中的这些填充控件。2是如何让有的控件自适应大小,就像这个例子中的richedit控件。这时,不要给控件设置大小和位置属性即可。 3注意float属性,设置这个属性后,位置和大小就相对于父控件了。


...
    <VerticalLayout bordersize="2" height="654" bkimage="file=&apos;dialog_background_new.png&apos; corner=&apos;95,715,2,255&apos;">
        <HorizontalLayout name="HLU_caption" height="95">
            <HorizontalLayout width="179" height="95">
                <Label float="true" pos="43,11,0,0" width="72" height="72" bkimage="xiaoniu.png" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" />
            </HorizontalLayout>
            <VerticalLayout>
                <HorizontalLayout height="24">
                    <VerticalLayout />
                    <VerticalLayout width="79">
                        <HorizontalLayout>
                            <Button name="minbtn" width="25" height="24" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file=&apos;sysmenu_.png&apos; source=&apos;0,0,24,23&apos;" hotimage="file=&apos;sysmenu_.png&apos; source=&apos;25,0,49,23&apos;" pushedimage="file=&apos;sysmenu_.png&apos; source=&apos;50,0,74,23&apos;" />
                            <Button name="maxbtn" width="25" height="24" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file=&apos;sysbtn_max.png&apos; source=&apos;0,0,24,23&apos;" hotimage="file=&apos;sysbtn_max.png&apos; source=&apos;25,0,49,23&apos;" pushedimage="file=&apos;sysbtn_max.png&apos; source=&apos;50,0,74,23&apos;" />
                            <Button name="restorebtn" visible="false" width="25" height="24" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file=&apos;sysbtn_restore.png&apos; source=&apos;0,0,24,23&apos;" hotimage="file=&apos;sysbtn_restore.png&apos; source=&apos;25,0,49,23&apos;" pushedimage="file=&apos;sysbtn_restore.png&apos; source=&apos;50,0,74,23&apos;" />
                            <Button name="closebtn" width="29" height="24" textcolor="#FF000000" disabledtextcolor="#FFA7A6AA" align="center" normalimage="file=&apos;sysmenu_close.png&apos; source=&apos;0,0,28,23&apos;" hotimage="file=&apos;sysmenu_close.png&apos; source=&apos;29,0,57,23&apos;" pushedimage="file=&apos;sysmenu_close.png&apos; source=&apos;58,0,86,23&apos;" />
                        </HorizontalLayout>
                    </VerticalLayout>
                </HorizontalLayout>
                (中间一部分省略)...
        <TabLayout name="TLU_client">
            <VerticalLayout name="DriverDiagnoseTab">
                <Animation name="AnimationJuhua1" enabled="false" float="true" pos="350,150,0,0" width="95" height="95" framesize="95,95" animationimage="fw_update_soft_checking.png" frameinterval="200" />
                <RichEdit name="txtDiagnose" bordersize="1" bordercolor="#00008000" inset="1,1,1,1" vscrollbar="true" hscrollbar="true" autohscroll="true" autovscroll="true" />
                <HorizontalLayout height="62">
                    <VerticalLayout />
                    <VerticalLayout width="465">
                        <HorizontalLayout>
                            <Button name="btnOpenLog" text="打开日志" float="true" pos="0,10,0,0" width="134" height="42" textcolor="#00FFFBF0" disabledtextcolor="#FFA7A6AA" font="1" align="center" normalimage="reboot.png" hotimage="file=&apos;reboot-hot.png&apos; corner=&apos;20,20,20,20&apos;" pushedimage="reboot.png" focusedimage="reboot.png" />
                            <Button name="btnClearLog" text="清空日志" float="true" pos="155,10,0,0" width="134" height="42" textcolor="#00FFFBF0" disabledtextcolor="#FFA7A6AA" font="1" align="center" normalimage="reboot.png" hotimage="file=&apos;reboot-hot.png&apos; corner=&apos;20,20,20,20&apos;" pushedimage="reboot.png" focusedimage="reboot.png" />
                            <Button name="btnExcute" text="执行" float="true" pos="310,10,0,0" width="134" height="42" textcolor="#00FFFBF0" disabledtextcolor="#FFA7A6AA" font="1" align="center" normalimage="reboot.png" hotimage="file=&apos;reboot-hot.png&apos; corner=&apos;20,20,20,20&apos;" pushedimage="reboot.png" focusedimage="reboot.png" />
                        </HorizontalLayout>
                    </VerticalLayout>
                </HorizontalLayout>
            </VerticalLayout>
        </TabLayout>
	...

代码编辑与调试

界面设计完成后,选择设计器中的编辑->生成python类来生成一个界面类MainFrame.py。将该文件拷贝到父目录中。执行Launcher.exe可以看到界面效果。

现在我们加入业务处理代码。

# 界面事件处理
    def OnNotify(self, sendor, sType, wParam, lParam):
        # 用户点击事件
        if sType == DUI_MSGTYPE_CLICK:
            ...
            elif sendor == "btnExcute":
                self.ExecutePython()
            ...

    ...
    # 真正业务函数
    def ExecutePython(self,):
        CommonUtils.ReverseToExePath()
        ISOTIMEFORMAT='%Y-%m-%d %X'
        self.ShowAndLog(time.strftime( ISOTIMEFORMAT, time.localtime() ))

        i = 0
        while i < 20:
            self.AppendAndLog('等待了%d秒' % i)
            time.sleep(1)
            i = i + 1

        self.AppendAndLog('成功')

执行程序,点击执行按钮,发现界面卡住了。过了20秒界面才正常。这是这个业务函数需要执行20秒导致的。

使用多线程保证界面流畅

当用户选择执行时,动画开启,开始转圈,直到python功能函数执行完成。在执行过程中,界面上的信息也在不断更新。 为了让界面不被卡住,采用了多线程技术。执行的功能函数在非界面线程执行。下面分析一下代码。

# 界面事件处理
    def OnNotify(self, sendor, sType, wParam, lParam):
        # 用户点击事件
        if sType == DUI_MSGTYPE_CLICK:
            ...
            elif sendor == "btnExcute":
                t = threading.Thread(target=PyThreadPythonExecute,args=(self,)) #启动了业务线程
                t.start()
            ...
注意ExecutePython是真正的业务处理函数,在该python类中定义。PyThreadPythonExecute只是真正业务函数的代理,并且在该python类外定义。 这时多线程编程中常用的方法。

代理函数,在python类外定义:

# 业务线程实际上只是一个代理函数
def PyThreadPythonExecute(PyClassInstance, ):
    try:
        PyClassInstance.StartAnimation()
        PyClassInstance.ExecutePython()
    except Exception, e:
        PyLog().LogText(str(e))
    PyClassInstance.StopAnimation()
    PyLog().LogText('PyThreadExecute exit')

执行程序

执行Launcher.exe或者DebugEntry.py,点击执行按钮。现在动画开启,开始转圈,直到python功能函数执行完成。 在执行过程中,界面上的信息也在不断更新。界面很流畅。

这是怎么回事?

有趣的是,在pyui4win中,使用ctyps中的界面相关函数,会导致程序崩溃。日志里头输出是

'exceptions.WindowsError': exception: access violation writing 0x0000000C...
错误原因还没有找到。 比如在这个例子中,对打开日志的处理中:
...
            elif sendor == "btnOpenLog":
                if os.path.isfile(PyWinUtils().GetExeDirectory() + '\\applog.ini'):
                    shell32 = ctypes.windll.LoadLibrary("shell32.dll");
                    #shell32.ShellExecuteA(None,'open', 'notepad',PyWinUtils().GetExeDirectory() + '\\applog.ini','',1);
                    PyWinUtils().ShellExcute(0, 'open', PyWinUtils().GetExeDirectory() + '\\applog.ini', '', '', 1)
                else:
                    UICommon.ShowMessageBox(self.GetHWnd(), '错误', '日志文件不存在')
            ...

如果使用shell32.ShellExecuteA就会崩溃。你知道是什么原因吗?

不要使用ctyps中的界面相关函数,否则会导致程序崩溃。该原因还没有找到。但是,针对常用的界面函数,如MessageBox等,请使用PyWinUtils类中的对应函数

转载于:https://my.oschina.net/u/159675/blog/156815

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Maya是一款用于3D图形和动画设计的软件,而Python是一种流行的脚本语言。Maya脚本语言Python教程是一种教授如何使用Python语言编写脚本来扩展和自定义Maya软件功能的教程。 这个教程通常涵盖了Python语法基础知识,如变量、数据类型、条件语句、循环等。此外,它还涵盖了Maya软件的基本概念和操作,以及如何使用Python与Maya的API(应用程序编程接口)进行交互。 Maya脚本语言Python教程具有以下优点和用途: 1. 扩展功能:通过编写Python脚本,用户可以利用Maya软件的API来创建自定义的工具和插件,以满足个人或专业需求。这些脚本可以用于自动化重复性任务、批量处理场景、模型和动画的创建,以及创建自定义用户界面等。 2. 快速迭代:Python是一种易于学习和使用的语言,具有直观的语法和丰富的标准库。使用Python编写Maya脚本可以快速迭代和测试想法,提高工作效率。 3. 与其他工具集成:Python是一种广泛使用的语言,它具有丰富的第三方库和工具。通过将Python与其他工具集成,如数据分析库、数学库等,可以进一步扩展Maya的功能。 总而言之,Maya脚本语言Python教程是学习如何通过Python编写脚本来定制和增强Maya软件功能的教程。它为使用Maya软件进行3D图形和动画设计的人员提供了更大的灵活性和创造力。无论是初学者还是有经验的用户,都可以通过学习这个教程来提高他们的技能和工作效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值