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.
This commit is contained in:
Damien Elmes 2021-10-16 09:20:20 +10:00
parent 2c17105a35
commit 281f1b2bf9
2 changed files with 61 additions and 34 deletions

View file

@ -1,17 +1,21 @@
import re import re
import sys import sys
import io import io
import os
from PyQt6.uic import compileUi from PyQt6.uic import compileUi
from dataclasses import dataclass
def compile(ui_file: str) -> str: def compile(ui_file: str) -> str:
buf = io.StringIO() buf = io.StringIO()
compileUi(open(ui_file), buf) compileUi(open(ui_file), buf)
return buf.getvalue() return buf.getvalue()
def with_fixes_for_qt6(code: str) -> str: def with_fixes_for_qt6(code: str) -> str:
code = code.replace( code = code.replace(
"from PyQt6 import QtCore, QtGui, QtWidgets", "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( code = re.sub(
r'(?:QtGui\.QApplication\.)?_?translate\(".*?", "(.*?)"', "tr.\\1(", code 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": if line == "from . import icons_rc":
continue continue
line = line.replace(":/icons/", "icons:") 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("QAction.AboutRole", "QAction.MenuRole.AboutRole")
line = line.replace("QComboBox.AdjustToMinimumContentsLength", "QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength") line = line.replace(
"QComboBox.AdjustToMinimumContentsLength",
"QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength",
)
outlines.append(line) outlines.append(line)
return "\n".join(outlines) return "\n".join(outlines)
def with_fixes_for_qt5(code: str) -> str: def with_fixes_for_qt5(code: str) -> str:
code = code.replace("Qt6", "Qt5") code = code.replace("Qt6", "Qt5")
code = code.replace("QtGui.QAction", "QtWidgets.QAction") code = code.replace("QtGui.QAction", "QtWidgets.QAction")
return code return code
if __name__ == "__main__":
ui_file = sys.argv[1]
py5_file = sys.argv[2]
py6_file = sys.argv[3]
stock = compile(ui_file) @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__":
for entry in get_files():
stock = compile(entry.ui_file)
for_qt6 = with_fixes_for_qt6(stock) for_qt6 = with_fixes_for_qt6(stock)
for_qt5 = with_fixes_for_qt5(for_qt6) for_qt5 = with_fixes_for_qt5(for_qt6)
with open(entry.qt5_file, "w") as file:
with open(py5_file, "w") as file:
file.write(for_qt5) file.write(for_qt5)
with open(entry.qt6_file, "w") as file:
with open(py6_file, "w") as file:
file.write(for_qt6) file.write(for_qt6)

View file

@ -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): def compile_all(name, builder, srcs):
py_files = [] py_files = []
for ui_file in srcs: for ui_file in srcs:
@ -22,7 +5,21 @@ def compile_all(name, builder, srcs):
qt5_file = base + "_qt5.py" qt5_file = base + "_qt5.py"
qt6_file = base + "_qt6.py" qt6_file = base + "_qt6.py"
py_files.extend([qt5_file, qt6_file]) 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( native.filegroup(
name = name, name = name,