使用 subprocess.Popen 启动 pyuic5
Posted
技术标签:
【中文标题】使用 subprocess.Popen 启动 pyuic5【英文标题】:launch pyuic5 with subprocess.Popen 【发布时间】:2018-09-12 11:45:02 【问题描述】:我正在尝试使用subprocess.Popen
调用pyuic5
,以便在Windows 上的python 脚本中将qt5 .ui 文件转换为python。
command = "pyuic5 -x " + filein + " -o " + fileout
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=False, cwd=folderPath)
output = process.communicate()
给我以下错误:
Traceback (most recent call last):
File "N:\My Documents\Code\Python Projects\Work projects\PyQtConverter\src\fonctions.py", line 36, in convert_qt_2_py
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=False, cwd=folderPath)
File "C:\Python35\lib\subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "C:\Python35\lib\subprocess.py", line 997, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] Le fichier spécifié est introuvable
问题似乎来自于调用pyuic5
(尽管它被认为是 Windows cmd 的有效命令?)。
设置shell=True
解决了这个问题,但我一直在读到这个选项可能存在安全风险,不推荐。我应该以不同的方式做事吗?
【问题讨论】:
filein
和 fileout
是什么?
包含输入和输出文件名的变量。这些文件的路径在 folderPath 变量中
它们是绝对路径吗?
是的。但正如我上面所说,如果 shell 设置为 true,则该命令有效。同样 subprocess.popen("pyuic5") 返回相同的文件未找到错误,而 subprocess.popen("pyuic5", shell=True) 返回预期的“错误:必须指定一个输入 ui 文件”。我的猜测是 Popen 不知道如何在没有 shell=True 参数的情况下调用 pyuic5 ......这让我有点困惑
我认为你应该使用shell = True
,因为pyuic最终是一个.bat,如果你不做验证,你所说的安全风险是真的,例如主要验证是filein 是一个扩展名为 .ui 的 Existing 文件,这样就足够了,但想想看,如果这是一个不好的做法,不要认为 python 会消除选项 shell = True
。
【参考方案1】:
拿这个。在 win 10 上运行良好 ;)
必须更改 gui.ui (variableName: guiNameUi) 和 outputfile.py (variableName: guiNameUi) 的名称
例如:guiNameUi = r'Button.ui' 到 guiNameUi = r'yourGuiName.ui' guiNamePy = r'Button.py' 到 guiNameUi = r'yourGuiName.py'
至少有一个人必须像这样改变你到 pyuic5 的路径: 转换器 = r'C:\Users\YourPC\Anaconda3\Library\bin'
转换后的 gui 的 python 文件在标准应用中打开
"""
Created on Fri May 10 16:59:26 2019
@author: BlindSide
"""
"""
--version show program's version number and exit
-h, --help show this help message and exit
-p, --preview show a preview of the UI instead of generating code
-o FILE, --output=FILE
write generated code to FILE instead of stdout
-x, --execute generate extra code to test and display the class
-d, --debug show debug output
-i N, --indent=N set indent width to N spaces, tab if N is 0 [default:
4]
-w, --pyqt3-wrapper generate a PyQt v3 style wrapper
Code generation options:
--from-imports generate imports relative to '.'
--resource-suffix=SUFFIX
append SUFFIX to the basename of resource files
[default: _rc]
"""
#Used in converting Script
import os
import subprocess
# python file ConvertUiToPy.py and example.ui lies in same folder
# directory of file
currentWorkingDir = os.getcwd()
#name of GUI.ui
guiNameUi = r'Button.ui'
#name of GUI.py
guiNamePy = r'Button.py'
# concat WorkingDir und GUI
fullpathUi = os.path.join(currentWorkingDir, guiNameUi)
fullpathPy = os.path.join(currentWorkingDir, guiNamePy)
# directory of pyuic5.bat -> eg. Anaconda 3 replace XYZ with userAccount
converter = r'C:\Users\YourPC\Anaconda3\Library\bin'
try:
# change directory from to pyuic5
os.chdir(converter)
print("directory changed... \n...executing conversion")
#execute pyuic5 to convert files
p1 = subprocess.call("pyuic5 -x \"" + fullpathUi + "\" -o \"" + fullpathPy + "\"", shell=True)
#file exists?
if(os.path.isfile(fullpathPy)):
print("...open new gui.py")
#open file in standard app
os.startfile("\"" + fullpathPy + "\"")
else:
#file doesnt exists? throw exception!!!
raise
# handling exeception
except:
print("something went wrong")
# further work in workingDirectory
finally:
print("restore old path")
os.chdir(currentWorkingDir)
print("changed to:", os.getcwd())
【讨论】:
以上是关于使用 subprocess.Popen 启动 pyuic5的主要内容,如果未能解决你的问题,请参考以下文章
Python subprocess.Popen 用于多个 python 脚本
python subprocess.popen stdin.write
subprocess.Popen,从子进程(子)中获取变量[重复]