0

I am trying to call pyuic5 with subprocess.Popen to convert qt5 .ui files to python from within a python script on Windows.

command = "pyuic5 -x " + filein + " -o " + fileout
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=False, cwd=folderPath)
output = process.communicate()

Gives me the following error:

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

It seems the issue comes from calling pyuic5 (although it is recognized as a valid command with the windows cmd?). Setting shell=True solves the problem, but I've been reading that this option could be a security risk and is not recommended. Should I be doing things differently?

MisterTea
  • 21
  • 1
  • 9
  • what are `filein` and `fileout`? – eyllanesc Sep 12 '18 at 12:06
  • The variables containing the file names for the input and output. The path to these files is in the folderPath variable – MisterTea Sep 12 '18 at 12:10
  • Are they absolute paths? – eyllanesc Sep 12 '18 at 12:10
  • Yes they are. But as i said above, the command works if shell is set to true. Also subprocess.popen("pyuic5") returns the same file not found error, whereas subprocess.popen("pyuic5", shell=True) returns the expected "Error: one input ui-file must be specified". My guess is that Popen does not know how to call pyuic5 without the shell=True argument... which confuses me a bit – MisterTea Sep 12 '18 at 12:37
  • I think you should use `shell = True`, because in the end pyuic is a .bat, what you indicate about security risk is true if you do not do a verification, for example the main verification is that filein is a Existing file with extension .ui, with that would be enough, but think about it do not think that python eliminates the option `shell = True` if it is a bad practice. – eyllanesc Sep 12 '18 at 15:52

1 Answers1

0

Take this one. Runs fine on win 10 ;)

One has to change the name of the gui.ui (variableName: guiNameUi) and your outputfile.py (variableName: guiNameUi)

eg.: guiNameUi = r'Button.ui' to guiNameUi = r'yourGuiName.ui' guiNamePy = r'Button.py' to guiNameUi = r'yourGuiName.py'

At least one has to change your path to pyuic5 like this one: converter = r'C:\Users\YourPC\Anaconda3\Library\bin'

After conversion python file of gui opens in standard app


"""
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())
BlindSide
  • 85
  • 1
  • 5