如何在python开发的GUI界面程序中恰当地使用PyExecJS

点击上方蓝字[协议分析与还原]关注我们


解决一闪而过的黑框的小技巧。

在使用python开发过程中,不可避免地,会开发带界面的应用,也会经常使用js来完成一些功能,比如,我使用python开发个了一个小应用:

做了一款股票复盘工具

这个里面,使用PTQT5开发的界面UI,里面大部分功能使用Python实现的,但有很小的一些功能,是使用js来实现的,最后打包成exe,使用的是pyinstaller,很方便,但是也有些小问题。

我们的exe,是带界面的,当然不希望黑色的命令行窗口存在,如果代码实现中没有使用js,那很好解决:

pyinstaller -F -w xxx.py

看起来很像样子。

但是,如果用到了js,而我们又用到了PyExecJS库来执行js,那就有些麻烦了,这个库在没有打包时,一切都是正常的,但帮我们把exe打包后,这个库会在执行js的时候,让黑色的命令行窗口闪现,很讨厌,明明一切执行正常,却偏偏闪一下黑窗。

另外,这个库已经停止维护了,所以只能自己找原因了。

我们一般使用PyExecJS来执行js的方法如下:

import execjs
ctx = execjs.compile(jsstr) 
out =ctx.call('v')

出现pyinstaller打包程序黑窗一闪而过的原因,是因为call的最终执行的函数是_external_runtime.py里面某个类里的_exec_with_pipe(self, source),直接搜到它:

def _exec_with_pipe(self, source):
    cmd = self._runtime._binary()
    p = None
    try:
        p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=self._cwd, universal_newlines=True)
        input = self._compile(source)
        if six.PY2:
            input = input.encode(sys.getfilesystemencoding())
        stdoutdata, stderrdata = p.communicate(input=input)
        ret = p.wait()
    finally:
        del p
    self._fail_on_non_zero_status(ret, stdoutdata, stderrdata)
    return stdoutdata

看到了吗?上面这个函数的第五行,它使用的其实是Popen来实现执行js的功能。这个Popen,默认情况下当然会有黑色命令行界面的存在,在pyinstaller打包时设置了不要命令行界面也没有用。

找到了问题的原因,那就解决它,我们知道,Popen设置startupinfo为STARTF_USESHOWWINDOW即可隐藏命令行界面窗口,那我们就修改_external_runtime.py这个文件,加上它:

def _exec_with_pipe(self, source):
    cmd = self._runtime._binary()
    p = None
    try:
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        p = Popen(cmd, startupinfo=startupinfo, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=self._cwd, universal_newlines=True)
        input = self._compile(source)
        if six.PY2:
            input = input.encode(sys.getfilesystemencoding())
        stdoutdata, stderrdata = p.communicate(input=input)
        ret = p.wait()
    finally:
        del p
    self._fail_on_non_zero_status(ret, stdoutdata, stderrdata)
    return stdoutdata

再试试使用pyinstaller来打包用PyExecJS库来执行js的GUI应用,是不是一切正常没有讨厌的一闪而过的黑框了?

解决了这个问题,一下子让GUI应用高档不少,不再山寨了。

上次开发的股票复牌工具,虽然发给了几个朋友,但是,真的很山寨,现在把它更新了一番,想更新的,找我要啦。

如果有想法,随时交流。

别忘点“在看”、“赞”和“分享”

新的规则,及时收推文要先给公号星标

别忘了星标一下,不然就错过了

长按进行关注,时刻进行交流。

猜你喜欢

转载自blog.csdn.net/yeyiqun/article/details/119880896
今日推荐