# Copyright (c) 2025 Riverbank Computing Limited # # This file is part of PyQt6. # # This file may be used under the terms of the GNU General Public License # version 3.0 as published by the Free Software Foundation and appearing in # the file LICENSE included in the packaging of this file. Please review the # following information to ensure the GNU General Public License version 3.0 # requirements will be met: http://www.gnu.org/copyleft/gpl.html. # # If you do not wish to use this file under the terms of the GPL version 3.0 # then you may purchase a commercial license. For more information contact # info@riverbankcomputing.com. # # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE # WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. import os import sys def main(): """ Convert a .ui file to a .py file. """ import argparse from PyQt6.QtCore import PYQT_VERSION_STR from .exceptions import (NoSuchClassError, NoSuchWidgetError, UIFileException) # The program name. PROGRAM_NAME = 'pyuic6' # Parse the command line. parser = argparse.ArgumentParser(prog=PROGRAM_NAME, description="Python User Interface Compiler") parser.add_argument('-V', '--version', action='version', version=PYQT_VERSION_STR) parser.add_argument('-p', '--preview', dest='preview', action='store_true', default=False, help="show a preview of the UI instead of generating code") parser.add_argument('-o', '--output', dest='output', default='-', metavar="FILE", help="write generated code to FILE instead of stdout") parser.add_argument('-x', '--execute', dest='execute', action='store_true', default=False, help="generate extra code to test and display the class") parser.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help="show debug output") parser.add_argument('-i', '--indent', dest='indent', action='store', type=int, default=4, metavar="N", help="set indent width to N spaces, tab if N is 0 [default: 4]") parser.add_argument('-w', '--max-workers', dest='max_workers', action='store', type=int, default=0, metavar="N", help="use a maximum of N worker processes when converting a directory [default: 0]") parser.add_argument('ui', help="the .ui file created by Qt Designer or a directory containing .ui files") args = parser.parse_args() # Carry out the required action. if args.debug: configure_logging() exit_status = 1 try: if args.preview: if os.path.isfile(args.ui): exit_status = preview(args.ui) else: raise UIFileException(args.ui, "must be a file") else: generate(args.ui, args.output, args.indent, args.execute, args.max_workers) exit_status = 0 except IOError as e: print("Error: {0}: '{1}'".format(e.strerror, e.filename), file=sys.stderr) except SyntaxError as e: print("Error in input file: {0}".format(e), file=sys.stderr) except (NoSuchClassError, NoSuchWidgetError, UIFileException) as e: print(e, file=sys.stderr) except Exception as e: if args.debug: import traceback traceback.print_exception(*sys.exc_info()) else: print("""An unexpected error occurred. Check that you are using the latest version of {name} and send an error report to the PyQt mailing list and include the following information: - your version of {name} ({version}) - the .ui file that caused this error - the debug output of {name} (use the --debug flag when calling {name})""".format(name=PROGRAM_NAME, version=PYQT_VERSION_STR), file=sys.stderr) return exit_status def configure_logging(): """ Configure logging when debug is enabled. """ import logging handler = logging.StreamHandler() handler.setFormatter(logging.Formatter("%(name)s: %(message)s")) logger = logging.getLogger('PyQt6.uic') logger.addHandler(handler) logger.setLevel(logging.DEBUG) def generate(ui_file, output, indent, execute, max_workers): """ Generate the Python code. """ from .exceptions import UIFileException if os.path.isdir(ui_file): if output == '-': map = None elif os.path.isdir(output) or not os.path.exists(output): map = lambda d, f: (output, f) else: raise UIFileException(output, f"must be a directory as {ui_file} is a directory") from .compile_ui import compileUiDir compileUiDir(ui_file, recurse=False, map=map, max_workers=max_workers, indent=indent, execute=execute) elif os.path.isdir(output): raise UIFileException(output, f"cannot be a directory unless {ui_file} is a directory") else: from .compile_ui import compileUi if output == '-': import io pyfile = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8') needs_close = False else: pyfile = open(output, 'wt', encoding='utf8') needs_close = True compileUi(ui_file, pyfile, execute, indent) if needs_close: pyfile.close() def preview(ui_file): """ Preview the .ui file. Return the exit status to be passed back to the parent process. """ from PyQt6.QtWidgets import QApplication from .load_ui import loadUi app = QApplication([ui_file]) ui = loadUi(ui_file) ui.show() return app.exec() if __name__ == '__main__': sys.exit(main())