Fix Qt6 StandardButton TypeError and C++ ViewProvider Proxy errors

Three fixes:

1. Remove int() wrapper from getStandardButtons() return values.
   In Qt6/PySide6, the | operator on QDialogButtonBox.StandardButton
   returns a StandardButton enum that is not convertible to int via
   int(). FreeCAD's task panel system accepts the enum directly.
   Affected files: datum_commands.py, datum_viewprovider.py,
   assembly_pattern_commands.py

2. Guard _setup_ztools_viewprovider() against C++ ViewProviders.
   PartDesign datum objects (Plane, Line, Point) use pure C++
   ViewProviders (e.g. ViewProviderDatumPlane) that don't expose a
   Proxy attribute. The previous code crashed with:
   'Gui.ViewProviderGeometryObject' object has no attribute 'Proxy'
   Now checks hasattr(vo, 'Proxy') before attempting assignment and
   wraps the assignment in try/except as a secondary guard.

3. Use persistent setPropertyStatus('Hidden') instead of transient
   setEditorMode(2) for hiding attachment properties (MapMode,
   Support, etc.). setEditorMode is session-only and resets on
   document reload, leaving 'MapMode: Deactivated' visible in the
   property panel. setPropertyStatus persists in the document file.
This commit is contained in:
Zoe Forbes
2026-01-31 04:26:06 -06:00
parent 98bd444221
commit 0e95d1cc76
4 changed files with 23 additions and 19 deletions

View File

@@ -339,7 +339,7 @@ class AssemblyLinearPatternTaskPanel:
return None
def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
return QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel
class AssemblyLinearPatternCommand:
@@ -758,7 +758,7 @@ class AssemblyPolarPatternTaskPanel:
return None
def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
return QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel
class AssemblyPolarPatternCommand:

View File

@@ -814,7 +814,7 @@ class DatumCreatorTaskPanel:
return True
def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
return QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel
class ZTools_DatumCreator:

View File

@@ -32,7 +32,7 @@ class ZToolsDatumViewProvider:
self._hide_attachment_props(vobj)
def _hide_attachment_props(self, vobj):
"""Hide FreeCAD attachment properties."""
"""Hide FreeCAD attachment properties using persistent property status."""
if not vobj or not vobj.Object:
return
@@ -48,7 +48,7 @@ class ZToolsDatumViewProvider:
for prop in attachment_props:
try:
if hasattr(obj, prop):
vobj.setEditorMode(prop, 2) # 2 = Hidden
obj.setPropertyStatus(prop, "Hidden")
except Exception:
pass
@@ -402,4 +402,4 @@ class DatumEditTaskPanel:
def getStandardButtons(self):
"""Return dialog buttons."""
return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
return QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel

View File

@@ -71,17 +71,9 @@ def _hide_attachment_properties(obj):
Hide FreeCAD's vanilla attachment properties from the property editor.
This prevents user confusion since ZTools uses its own attachment system.
Editor modes:
0 = Normal (visible, editable)
1 = Read-only
2 = Hidden
Uses setPropertyStatus with "Hidden" which persists across save/restore,
unlike setEditorMode which is transient.
"""
if not hasattr(obj, "ViewObject") or obj.ViewObject is None:
return
vo = obj.ViewObject
# Hide attachment-related properties
attachment_props = [
"MapMode",
"MapPathParameter",
@@ -93,7 +85,7 @@ def _hide_attachment_properties(obj):
for prop in attachment_props:
try:
if hasattr(obj, prop):
vo.setEditorMode(prop, 2) # 2 = Hidden
obj.setPropertyStatus(prop, "Hidden")
except Exception:
pass # Property might not exist on all datum types
@@ -102,21 +94,33 @@ def _setup_ztools_viewprovider(obj):
"""
Set up a custom ViewProvider proxy for ZTools datums.
This enables custom double-click behavior to open ZTools editor.
Note: PartDesign datum ViewProviders (e.g. ViewProviderDatumPlane) are
pure C++ and do not support Python proxies. In that case we skip the
custom ViewProvider setup — the datum still works, just without custom
double-click edit behavior.
"""
if not hasattr(obj, "ViewObject") or obj.ViewObject is None:
return
vo = obj.ViewObject
# C++ ViewProviders for PartDesign datums don't expose a Proxy attribute
if not hasattr(vo, "Proxy"):
return
# Only set up if not already a ZTools ViewProvider
if hasattr(vo, "Proxy") and vo.Proxy is not None:
if vo.Proxy is not None:
if hasattr(vo.Proxy, "_is_ztools"):
return
# Import here to avoid circular imports
from ztools.commands.datum_viewprovider import ZToolsDatumViewProvider
ZToolsDatumViewProvider(vo)
try:
ZToolsDatumViewProvider(vo)
except Exception:
pass # C++ ViewProvider doesn't support Python proxy assignment
def _setup_ztools_datum(