From 281f1b2bf9610f8654f7bd643b163bcfdac64a99 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 16 Oct 2021 09:20:20 +1000 Subject: [PATCH] build all the UI files in one go On macOS, the overhead of importing PyQt for each file far exceeds any gains we get from incremental recompilation. --- qt/aqt/forms/build_ui.py | 62 +++++++++++++++++++++++++++++----------- qt/aqt/forms/compile.bzl | 33 ++++++++++----------- 2 files changed, 61 insertions(+), 34 deletions(-) diff --git a/qt/aqt/forms/build_ui.py b/qt/aqt/forms/build_ui.py index 357584e3c..158ab0210 100644 --- a/qt/aqt/forms/build_ui.py +++ b/qt/aqt/forms/build_ui.py @@ -1,17 +1,21 @@ import re import sys import io +import os from PyQt6.uic import compileUi +from dataclasses import dataclass + def compile(ui_file: str) -> str: buf = io.StringIO() compileUi(open(ui_file), buf) return buf.getvalue() + def with_fixes_for_qt6(code: str) -> str: code = code.replace( "from PyQt6 import QtCore, QtGui, QtWidgets", - "from PyQt6 import QtCore, QtGui, QtWidgets\nfrom aqt.utils import tr\n" + "from PyQt6 import QtCore, QtGui, QtWidgets\nfrom aqt.utils import tr\n", ) code = re.sub( r'(?:QtGui\.QApplication\.)?_?translate\(".*?", "(.*?)"', "tr.\\1(", code @@ -28,28 +32,54 @@ def with_fixes_for_qt6(code: str) -> str: if line == "from . import icons_rc": continue line = line.replace(":/icons/", "icons:") - line = line.replace("QAction.PreferencesRole", "QAction.MenuRole.PreferencesRole") + line = line.replace( + "QAction.PreferencesRole", "QAction.MenuRole.PreferencesRole" + ) line = line.replace("QAction.AboutRole", "QAction.MenuRole.AboutRole") - line = line.replace("QComboBox.AdjustToMinimumContentsLength", "QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength") + line = line.replace( + "QComboBox.AdjustToMinimumContentsLength", + "QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength", + ) outlines.append(line) return "\n".join(outlines) + def with_fixes_for_qt5(code: str) -> str: code = code.replace("Qt6", "Qt5") code = code.replace("QtGui.QAction", "QtWidgets.QAction") return code + +@dataclass +class UiFileAndOutputs: + ui_file: str + qt5_file: str + qt6_file: str + + +def get_files() -> list[UiFileAndOutputs]: + ui_folder = os.path.dirname(sys.argv[1]) + py_folder = os.path.dirname(sys.argv[2]) + out = [] + for file in os.listdir(ui_folder): + if file.endswith(".ui"): + base = os.path.splitext(os.path.basename(file))[0] + out.append( + UiFileAndOutputs( + ui_file=os.path.join(ui_folder, file), + qt5_file=os.path.join(py_folder, base + "_qt5.py"), + qt6_file=os.path.join(py_folder, base + "_qt6.py"), + ) + ) + return out + + if __name__ == "__main__": - ui_file = sys.argv[1] - py5_file = sys.argv[2] - py6_file = sys.argv[3] - - stock = compile(ui_file) - for_qt6 = with_fixes_for_qt6(stock) - for_qt5 = with_fixes_for_qt5(for_qt6) - - with open(py5_file, "w") as file: - file.write(for_qt5) - - with open(py6_file, "w") as file: - file.write(for_qt6) + for entry in get_files(): + stock = compile(entry.ui_file) + for_qt6 = with_fixes_for_qt6(stock) + for_qt5 = with_fixes_for_qt5(for_qt6) + with open(entry.qt5_file, "w") as file: + file.write(for_qt5) + with open(entry.qt6_file, "w") as file: + file.write(for_qt6) diff --git a/qt/aqt/forms/compile.bzl b/qt/aqt/forms/compile.bzl index 3ceedcc93..3f0c9a9d0 100644 --- a/qt/aqt/forms/compile.bzl +++ b/qt/aqt/forms/compile.bzl @@ -1,20 +1,3 @@ -def compile(name, ui_file, qt5_file, qt6_file, builder): - native.genrule( - name = name, - srcs = [ui_file], - outs = [qt5_file, qt6_file], - cmd = "$(location {builder}) $(location {ui_file}) $(location {qt5_file}) $(location {qt6_file})".format( - builder = builder, - ui_file = ui_file, - qt5_file = qt5_file, - qt6_file = qt6_file, - ), - tools = [ - builder, - ], - message = "Building UI", - ) - def compile_all(name, builder, srcs): py_files = [] for ui_file in srcs: @@ -22,7 +5,21 @@ def compile_all(name, builder, srcs): qt5_file = base + "_qt5.py" qt6_file = base + "_qt6.py" py_files.extend([qt5_file, qt6_file]) - compile(base, ui_file, qt5_file, qt6_file, builder) + + native.genrule( + name = name + "_build", + srcs = srcs, + outs = py_files, + cmd = "$(location {builder}) $(location {first_ui}) $(location {first_py})".format( + builder = builder, + first_ui = srcs[0], + first_py = py_files[0], + ), + tools = [ + builder, + ], + message = "Building Qt UI", + ) native.filegroup( name = name,