| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- # Copyright (c) 2023 Riverbank Computing Limited.
- # Copyright (c) 2006 Thorsten Marek.
- # All right reserved.
- #
- # This file is part of PyQt.
- #
- # You may use this file under the terms of the GPL v3 or the revised BSD
- # license as follows:
- #
- # "Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are
- # met:
- # * Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- # * Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in
- # the documentation and/or other materials provided with the
- # distribution.
- # * Neither the name of the Riverbank Computing Limited nor the names
- # of its contributors may be used to endorse or promote products
- # derived from this software without specific prior written
- # permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
- from .Compiler import indenter, compiler
- _header = """# Form implementation generated from reading ui file '{}'
- #
- # Created by: PyQt6 UI code generator {}
- #
- # WARNING: Any manual changes made to this file will be lost when pyuic6 is
- # run again. Do not edit this file unless you know what you are doing.
- """
- _display_code = """
- if __name__ == "__main__":
- import sys
- app = QtWidgets.QApplication(sys.argv)
- %(widgetname)s = QtWidgets.%(baseclass)s()
- ui = %(uiclass)s()
- ui.setupUi(%(widgetname)s)
- %(widgetname)s.show()
- sys.exit(app.exec())"""
- def compileUiDir(dir, recurse=False, map=None, max_workers=0, **compileUi_args):
- """compileUiDir(dir, recurse=False, map=None, **compileUi_args)
- Creates Python modules from Qt Designer .ui files in a directory or
- directory tree.
- dir is the name of the directory to scan for files whose name ends with
- '.ui'. By default the generated Python module is created in the same
- directory ending with '.py'.
- recurse is set if any sub-directories should be scanned. The default is
- False.
- map is an optional callable that is passed the name of the directory
- containing the '.ui' file and the name of the Python module that will be
- created. The callable should return a tuple of the name of the directory
- in which the Python module will be created and the (possibly modified)
- name of the module. The default is None.
- max_workers is the maximum number of worker processes to use. A value of 0
- means only the current process is used. A value of None means that the
- number of processors on the machine is used.
- compileUi_args are any additional keyword arguments that are passed to
- the compileUi() function that is called to create each Python module.
- """
- from functools import partial
- import os
- jobs = []
- # Add a compilation job.
- def add_job(ui_dir, ui_file):
- # Ignore if it doesn't seem to be a .ui file.
- if ui_file.endswith('.ui'):
- py_dir = ui_dir
- py_file = ui_file[:-3] + '.py'
- # Allow the caller to change the name of the .py file or generate
- # it in a different directory.
- if map is not None:
- py_dir, py_file = map(py_dir, py_file)
- ui_path = os.path.join(ui_dir, ui_file)
- jobs.append((ui_path, py_dir, py_file))
- if recurse:
- for root, _, files in os.walk(dir):
- for ui in files:
- add_job(root, ui)
- else:
- for ui in os.listdir(dir):
- if os.path.isfile(os.path.join(dir, ui)):
- add_job(dir, ui)
- if jobs and max_workers != 0:
- from concurrent.futures import ProcessPoolExecutor
- with ProcessPoolExecutor(max_workers=max_workers) as executor:
- executor.map(partial(_run_job, **compileUi_args), jobs)
- else:
- for job in jobs:
- _run_job(job, **compileUi_args)
- def _run_job(job, **compileUi_args):
- """ Run a job to compile a single .ui file. """
- import os
- ui_path, py_dir, py_file = job
- # Make sure the destination directory exists.
- try:
- os.makedirs(py_dir)
- except:
- pass
- py_path = os.path.join(py_dir, py_file)
- with open(py_path, 'w', encoding='utf-8') as py_f:
- compileUi(ui_path, py_f, **compileUi_args)
- def compileUi(uifile, pyfile, execute=False, indent=4):
- """compileUi(uifile, pyfile, execute=False, indent=4)
- Creates a Python module from a Qt Designer .ui file.
-
- uifile is a file name or file-like object containing the .ui file.
- pyfile is the file-like object to which the Python code will be written to.
- execute is optionally set to generate extra Python code that allows the
- code to be run as a standalone application. The default is False.
- indent is the optional indentation width using spaces. If it is 0 then a
- tab is used. The default is 4.
- """
- from PyQt6.QtCore import PYQT_VERSION_STR
- try:
- uifname = uifile.name
- except AttributeError:
- uifname = uifile
- indenter.indentwidth = indent
- pyfile.write(_header.format(uifname, PYQT_VERSION_STR))
- winfo = compiler.UICompiler().compileUi(uifile, pyfile)
- if execute:
- indenter.write_code(_display_code % winfo)
|