Extract default preferences from ui file? Feasible or not?
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
Extract default preferences from ui file? Feasible or not?
The ui files used for the preferences also contain default values. In the Draft WB we have the issue that there are sometimes inconsistencies between the default values in the ui files and those used elsewhere in the code. One way this might be solved is to extract the defaults from the ui files, but them in a dictionary and then reference that dictionary whenever a default value is required. Is this idea feasible?
Re: Extract default preferences from ui file? Feasible or not?
as ui files are text files, probably some regex or other parsers could be useful.
But probably you have to write them for scratch, or maybe searching for "qt ui files parsing"
https://github.com/ordovician/QtUIParser.jl
It seems to be an xml file, so probably standard python tools could be used.
Hope it helps
Carlo D.
But probably you have to write them for scratch, or maybe searching for "qt ui files parsing"
https://github.com/ordovician/QtUIParser.jl
It seems to be an xml file, so probably standard python tools could be used.
Hope it helps
Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
Re: Extract default preferences from ui file? Feasible or not?
Thanks. Very early beginnings, but here is my code so far:
Code: Select all
# Preferences ui files are stored in resource files.
# For the Draft Workbench: /Mod/Draft/Draft_rc.py
import Draft_rc
import PySide.QtCore as QtCore
import xml.etree.ElementTree as ET
fnm = ":/ui/preferences-draftsnap.ui"
# https://stackoverflow.com/questions/14750997/load-txt-file-from-resources-in-python
fd = QtCore.QFile(fnm)
if fd.open(QtCore.QIODevice.ReadOnly | QtCore.QFile.Text):
text = QtCore.QTextStream(fd).readAll()
fd.close()
# https://docs.python.org/3/library/xml.etree.elementtree.html
root = ET.fromstring(text)
pref_widgets = [wid for wid in root.iter('widget') if "Gui::Pref" in wid.attrib["class"]]
Re: Extract default preferences from ui file? Feasible or not?
I have a question regarding this. Where should I put this preferences dictionary to make it available for all code in the Draft and Arch workbenches?
Add it as a property to the FreeCAD module, the same as is done for the DraftWorkingPlane, perhaps?
Add it as a property to the FreeCAD module, the same as is done for the DraftWorkingPlane, perhaps?
Code: Select all
if not hasattr(FreeCAD, "DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane = WorkingPlane.plane()
Re: Extract default preferences from ui file? Feasible or not?
FWIW the current code (still WIP):
Code: Select all
# Preferences ui files are stored in resource files.
# For the Draft Workbench: /Mod/Draft/Draft_rc.py
import Draft_rc
import PySide.QtCore as QtCore
import xml.etree.ElementTree as ET
# fnm = ":/ui/preferences-draft.ui"
# fnm = ":/ui/preferences-draftinterface.ui"
# fnm = ":/ui/preferences-draftsnap.ui"
# fnm = ":/ui/preferences-drafttexts.ui"
fnm = ":/ui/preferences-draftvisual.ui"
# https://stackoverflow.com/questions/14750997/load-txt-file-from-resources-in-python
fd = QtCore.QFile(fnm)
if fd.open(QtCore.QIODevice.ReadOnly | QtCore.QFile.Text):
str = QtCore.QTextStream(fd).readAll()
fd.close()
# https://docs.python.org/3/library/xml.etree.elementtree.html
root = ET.fromstring(str)
# pref_widgets = [wid for wid in root.iter('widget') if "Gui::Pref" in wid.attrib["class"]]
def pref_from_PrefCheckBox(widget):
val = False
for elem in list(widget):
att_name = elem.attrib["name"]
if att_name == "checked": # Can be missing.
val = elem.find("bool").text == "true"
elif att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
return [pref, path, val]
def pref_from_PrefComboBox(widget):
idx = 0
vals = []
for elem in list(widget):
if elem.tag == "property":
att_name = elem.attrib["name"]
if att_name == "currentIndex": # Can be missing.
idx = int(elem.find("number").text)
elif att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
elif elem.tag == "item":
val = list(elem)[0].find("string").text
vals.append(val)
return [pref, path, vals[idx]]
def pref_from_PrefSpinBox(widget):
val = 0
for elem in list(widget):
att_name = elem.attrib["name"]
if att_name == "value": # Can be missing.
val = int(elem.find("number").text)
elif att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
return [pref, path, val]
def pref_from_PrefDoubleSpinBox(widget):
val = 0.0
for elem in list(widget):
att_name = elem.attrib["name"]
if att_name == "value": # Can be missing.
val = float(elem.find("double").text)
elif att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
return [pref, path, val]
def pref_from_PrefQuantitySpinBox(widget):
val = "0"
for elem in list(widget):
att_name = elem.attrib["name"]
if att_name == "rawValue": # Not sure if this can be missing.
val = elem.find("double").text.rstrip(".0")
elif att_name == "unit":
unit = elem.find("string").text
elif att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
return [pref, path, val + " " + unit]
def pref_from_PrefColorButton(widget):
for elem in list(widget):
att_name = elem.attrib["name"]
if att_name == "color":
sub = list(elem)[0]
r = int(sub.find("red").text)
g = int(sub.find("green").text)
b = int(sub.find("blue").text)
elif att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
val = (r << 24) + (g << 16) + (b << 8) + 255
return [pref, path, val]
def pref_from_PrefLineEdit(widget):
val = None
for elem in list(widget):
att_name = elem.attrib["name"]
if att_name == "text": # Can be missing.
val = elem.find("string").text # If text is missing val will be None here.
elif att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
if val is None:
val = ""
return [pref, path, val]
def pref_from_PrefFileChooser(widget):
for elem in list(widget):
att_name = elem.attrib["name"]
if att_name == "prefEntry":
pref = elem.find("cstring").text
elif att_name == "prefPath":
path = elem.find("cstring").text
return [pref, path, ""]
i = 0
for widget in root.iter('widget'):
att_class = widget.attrib["class"]
if att_class == "Gui::PrefCheckBox":
print(pref_from_PrefCheckBox(widget))
i = i + 1
elif att_class == "Gui::PrefComboBox":
print(pref_from_PrefComboBox(widget))
i = i + 1
elif att_class == "Gui::PrefSpinBox":
print(pref_from_PrefSpinBox(widget))
i = i + 1
elif att_class == "Gui::PrefDoubleSpinBox":
print(pref_from_PrefDoubleSpinBox(widget))
i = i + 1
elif att_class == "Gui::PrefQuantitySpinBox":
print(pref_from_PrefQuantitySpinBox(widget))
i = i + 1
elif att_class == "Gui::PrefColorButton":
print(pref_from_PrefColorButton(widget))
i = i + 1
elif att_class == "Gui::PrefLineEdit":
print(pref_from_PrefLineEdit(widget))
i = i + 1
elif att_class == "Gui::PrefFileChooser":
print(pref_from_PrefFileChooser(widget))
i = i + 1
print(i)
Re: Extract default preferences from ui file? Feasible or not?
I have seen that if you set it in the InitGui it is spreaded all over FC.
Not surprisingly, as it is normal behaviour for Python, once I have done this:
1) I have set some "global" variables in the InitGui module, thinking there will be some "separation" between WB, so I have set something like WB_Name and sone it for two WB one real and one "test WB".
2) I have found that the second WB loaded will overwrite the WB_Name for the whole FC instance.
Probably this could be a way, or maybe making some WB wide "global variable module", in other work a module that contains all the variables that is imported in all other modules, say maybe using something similar to:
Code: Select all
import draft_vars as draft_v
Code: Select all
draft_v.something
But it is not "very polite" but it will not use globals and locals explicitly, that is generally considered "bad practice"
Hope it helps
Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
Re: Extract default preferences from ui file? Feasible or not?
Thanks. To keep things simple I have decided to use this:
https://docs.python.org/3/faq/programmi ... en-objects
Full code attached.
https://docs.python.org/3/faq/programmi ... en-objects
Code: Select all
# pref_default("Mod/Draft", "gridSpacing")
# pref_default("Mod/Arch", "WallHeight")
def pref_default(path, pref, pref_dict=pref_dictionary()):
if path not in pref_dict.keys():
return None
elif pref not in pref_dict[path].keys():
return None
else:
return pref_dict[path][pref]
- Attachments
-
- prefs.py
- (7.68 KiB) Downloaded 9 times
Re: Extract default preferences from ui file? Feasible or not?
Roy_043 wrote: ↑Thu Jul 07, 2022 3:20 pm ...
https://docs.python.org/3/faq/programmi ... en-objects
...
Many Thanks, interesting reading, now I have to rewrite most of my code.
Regards
Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/