diff --git a/ElaWidgetTools b/ElaWidgetTools index aa1856b..190c02e 160000 --- a/ElaWidgetTools +++ b/ElaWidgetTools @@ -1 +1 @@ -Subproject commit aa1856b8f8589ba0a82e50c0ac01e289eb3ff2c4 +Subproject commit 190c02e5bccb3614750a986945934a77ba7d90e7 diff --git a/scripts/dobuild.py b/scripts/dobuild.py index a8836e6..8e6aa26 100644 --- a/scripts/dobuild.py +++ b/scripts/dobuild.py @@ -73,7 +73,7 @@ def __parsefile(fn, cb, pr=False): lambda cml: cml.replace("add_subdirectory(ElaWidgetToolsExample)", ""), ) __parsefile( - "../ElaWidgetTools/ElaWidgetTools/ElaProperty.h", + "../ElaWidgetTools/ElaWidgetTools/ElaWidgetToolsExport.h", lambda cml: cml.replace( "Q_DECL_EXPORT", "", @@ -90,7 +90,6 @@ def __parsefile(fn, cb, pr=False): add_compile_definitions( _SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS _HAS_CXX17=1 - _HAS_CXX20=1 _CRT_SECURE_NO_WARNINGS ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17 /Zc:__cplusplus") @@ -98,7 +97,7 @@ def __parsefile(fn, cb, pr=False): """ __parsefile( - "../ElaWidgetTools/CMakeLists.txt", + "../ElaWidgetTools/ElaWidgetTools/CMakeLists.txt", lambda c: c.replace( "add_definitions(-DELAWIDGETTOOLS_LIBRARY)", "add_definitions(-DELAWIDGETTOOLS_LIBRARY)\n" + fix, diff --git a/scripts/pyqt/gen_Def.sip.py b/scripts/pyqt/gen_Def.sip.py index 62a38d4..35582a3 100644 --- a/scripts/pyqt/gen_Def.sip.py +++ b/scripts/pyqt/gen_Def.sip.py @@ -2,7 +2,7 @@ os.chdir(os.path.dirname(os.path.abspath(__file__))) -with open("../../ElaWidgetTools/ElaWidgetTools/ElaDef.h", "r", encoding="utf8") as ff: +with open("../../ElaWidgetTools/ElaWidgetTools/ElaWidgetToolsDef.h", "r", encoding="utf8") as ff: content = ff.read() import re @@ -48,7 +48,7 @@ def parse_def_h_to_sip(header_content): sip_output.append( """ %TypeHeaderCode -#include "ElaDef.h" +#include "ElaWidgetToolsDef.h" %End """ ) diff --git a/scripts/pyqt/gen_widgets.py b/scripts/pyqt/gen_widgets.py index c47b603..f490dab 100644 --- a/scripts/pyqt/gen_widgets.py +++ b/scripts/pyqt/gen_widgets.py @@ -306,18 +306,38 @@ def generate_sip_for_class__1(header_content, filename=""): base_class_name = class_match.group(3) sip_lines.append(f"class {class_name} : public {base_class_name}\n{{") sip_lines.append("%TypeHeaderCode") - sip_lines.append(f'#include "ElaDef.h"') + sip_lines.append(f'#include "ElaWidgetToolsDef.h"') sip_lines.append(f'#include "{os.path.basename(filename)}"') sip_lines.append("%End\n") # --- Properties --- - # Q_PROPERTY_CREATE_Q_H(type, Name) - # Assumes getter: Name() or isName() for bool, Setter: setName(type) - for pt in ("Q_PROPERTY_CREATE", "Q_PROPERTY_CREATE_Q_H", "Q_PROPERTY_REF_CREATE_Q_H"): + # Q_PROPERTY_* macros declare a notify signal (pXChanged) + getter/setter. + # Q_PRIVATE_* macros declare only getter/setter (no notify signal). + # Only scan the class body: property macros that belong to other types in the + # same header (e.g. ElaSuggestBox's nested SuggestData struct) must not be + # attributed to this class, or sip will generate accessors that don't exist. + _class_body_for_props = re.search( + r"class\s+ELA_EXPORT\s+\w+\s*:\s*public\s+\w+\s*\{(.*?)(\};)", + header_content, + re.DOTALL, + ) + prop_scan = _class_body_for_props.group(1) if _class_body_for_props else header_content + + PROP_MACROS = [ + ("Q_PROPERTY_CREATE", True), + ("Q_PROPERTY_CREATE_Q_H", True), + ("Q_PROPERTY_REF_CREATE_Q_H", True), + ("Q_PRIVATE_CREATE", False), + ("Q_PRIVATE_CREATE_Q_H", False), + ("Q_PRIVATE_REF_CREATE", False), + ("Q_PRIVATE_REF_CREATE_Q_H", False), + ] + has_public_section_for_props = False # To add "public:" if props are first + + for pt, has_signal in PROP_MACROS: prop_pattern = re.compile(rf"{pt}\((.*?),\s*(\w+)\)") - has_public_section_for_props = False # To add "public:" if props are first - for match in prop_pattern.finditer(header_content): + for match in prop_pattern.finditer(prop_scan): if not has_public_section_for_props: # Properties are usually public in SIP even if members are private # sip_lines.append("public:") # Not strictly needed for %Property @@ -336,7 +356,10 @@ def generate_sip_for_class__1(header_content, filename=""): # For now, assume they follow the macro's convention # sip_lines.append(f" // Property: {prop_name}") # sip_lines.append(f" %Property({sip_prop_type} {prop_name.lower()} READ {getter_name} WRITE {setter_name})\n") - sip_lines.append(f"public: Q_SIGNAL void p{prop_name}Changed();") + if has_signal: + sip_lines.append(f"public: Q_SIGNAL void p{prop_name}Changed();") + else: + sip_lines.append("public:") sip_lines.append( f" void {setter_name}({(prop_type_raw)} {prop_name});" ) # Use input version of type @@ -573,7 +596,9 @@ def cast_h_to_sip(filename): allfiles = [] for f in os.listdir(eladir): - if f.startswith("ElaDef"): + if f.startswith("ElaWidgetToolsDef"): + continue + if f.startswith("ElaWidgetToolsExport"): continue if f.startswith("ElaProperty"): continue diff --git a/scripts/pyside6/gen_xml.py b/scripts/pyside6/gen_xml.py index f719364..97a50e6 100644 --- a/scripts/pyside6/gen_xml.py +++ b/scripts/pyside6/gen_xml.py @@ -17,13 +17,13 @@ eladir = "../../ElaWidgetTools/ElaWidgetTools" -with open(eladir + "/ElaProperty.h", "r", encoding="utf8") as ff: +with open(eladir + "/ElaPropertyMacro.h", "r", encoding="utf8") as ff: pro = ff.read() # 如果不这样改,信号会被识别成方法。 if not ("Q_SIGNALS:Q_SIGNAL" in pro): pro = re.sub(r"Q_SIGNAL(.*?)\\", r"Q_SIGNALS:Q_SIGNAL \1\\\npublic:\\", pro) - with open(eladir + "/ElaProperty.h", "w", encoding="utf8") as ff: + with open(eladir + "/ElaPropertyMacro.h", "w", encoding="utf8") as ff: ff.write(pro) @@ -143,7 +143,9 @@ def gen_widgets(eladir: str): hs = [] xmls = [] for f in os.listdir(eladir): - if f.startswith("ElaDef"): + if f.startswith("ElaWidgetToolsDef"): + continue + if f.startswith("ElaWidgetToolsExport"): continue if f.startswith("ElaProperty"): continue @@ -158,7 +160,7 @@ def gen_widgets(eladir: str): def gen_defs(): - with open(eladir + "/ElaDef.h", "r", encoding="utf8") as ff: + with open(eladir + "/ElaWidgetToolsDef.h", "r", encoding="utf8") as ff: header_content = ff.read() sip_output = [] @@ -284,7 +286,7 @@ def maybeparse(xx: str): #endif """ -H_internal = """#include """ +H_internal = """#include """ with open("wrapper.hpp", "w", encoding="utf8") as ff: ff.write(wrapperbase.format(internal=H_internal + "\n" + h))