מדריך: יצירת תוספים עבור FreeCAD
מטרת השיעור: צור חלון עם שדות להזנת אורך, רוחב וגובה, ובנה קופסה עם פרמטרים אלו בלחיצה על כפתור.
חלק 1. כיצד פועל הממשק הגרפי ב-FreeCAD?
FreeCAD משתמש ב-PySide – מעטפת פייתון לספריית Qt (אותה ספריה המשמשת גם ב-Blender, Maya ותוכניות רבות אחרות).
רכיבים עיקריים:
QtGui.QDialog— חלון מודאליQtGui.QLineEdit— שדה קלט טקסטQtGui.QPushButton— כפתורQtGui.QFormLayout— עיצוב נוח בסגנון "תווית + שדה"
כל רכיבי הממשק נוצרים בתוך סקריפט פייתון – ללא קבצים חיצוניים (למרות שניתן להשתמש בקבצי .ui מתוך Qt Designer; נתחיל עם משהו פשוט).
חלק 2. תוסף: "בונה קופסאות עם ממשק גרפי"
נשפר את התוסף הקודם על ידי הוספת חלון דו-שיח.
שלב 1. יצירת תיקייה
.../Mod/BoxBuilderAddon/
שלב 2. קובץ InitGui.py
# InitGui.py
import FreeCADGui
from BoxBuilderAddon.box_builder_workbench import BoxBuilderWorkbench
FreeCADGui.addWorkbench(BoxBuilderWorkbench())
שלב 3. קובץ box_builder_workbench.py
# box_builder_workbench.py
import FreeCAD, FreeCADGui
from PySide import QtGui, QtCore
# === פונקציית יצירת הקופסה ===
def create_box(length, width, height, name="CustomBox"):
doc = FreeCAD.ActiveDocument
if not doc:
doc = FreeCAD.newDocument("BoxBuilder")
# שם ייחודי
base_name = name
index = 1
obj_name = base_name
while obj_name in [obj.Name for obj in doc.Objects]:
obj_name = f"{base_name}_{index}"
index += 1
box = doc.addObject("Part::Box", obj_name)
box.Length = length
box.Width = width
box.Height = height
doc.recompute()
return box
# === חלון דו-שיח ===
class BoxBuilderDialog(QtGui.QDialog):
def __init__(self):
super(BoxBuilderDialog, self).__init__()
self.setWindowTitle("בונה קופסאות")
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
self.resize(300, 150)
# שדות קלט
self.length_input = QtGui.QLineEdit("30.0")
self.width_input = QtGui.QLineEdit("20.0")
self.height_input = QtGui.QLineEdit("10.0")
# כפתורים
self.create_button = QtGui.QPushButton("צור קופסה")
self.cancel_button = QtGui.QPushButton("ביטול")
# חיבור כפתורים
self.create_button.clicked.connect(self.on_create)
self.cancel_button.clicked.connect(self.reject)
# עיצוב
layout = QtGui.QFormLayout()
layout.addRow("אורך (מ\"מ):", self.length_input)
layout.addRow("רוחב (מ\"מ):", self.width_input)
layout.addRow("גובה (מ\"מ):", self.height_input)
button_layout = QtGui.QHBoxLayout()
button_layout.addWidget(self.create_button)
button_layout.addWidget(self.cancel_button)
main_layout = QtGui.QVBoxLayout()
main_layout.addLayout(layout)
main_layout.addLayout(button_layout)
self.setLayout(main_layout)
def on_create(self):
try:
length = float(self.length_input.text())
width = float(self.width_input.text())
height = float(self.height_input.text())
if length <= 0 or width <= 0 or height <= 0:
raise ValueError("כל הממדים חייבים להיות חיוביים")
create_box(length, width, height)
self.accept() # סגירת החלון
except ValueError as e:
QtGui.QMessageBox.warning(self, "שגיאת קלט", f"קלט לא חוקי:\n{str(e)}")
# === פקודה ===
class BoxBuilderCommand:
def GetResources(self):
return {
"MenuText": "בונה קופסאות",
"ToolTip": "צור קופסה עם ממדים מותאמים אישית"
}
def Activated(self):
dialog = BoxBuilderDialog()
dialog.exec_() # קריאה מודאלית
def IsActive(self):
return True
# === סביבת עבודה ===
class BoxBuilderWorkbench(FreeCADGui.Workbench):
MenuText = "בונה קופסאות"
ToolTip = "צור קופסאות מותאמות עם ממשק גרפי"
def Initialize(self):
self.list = ["BoxBuilderCommand"]
self.appendToolbar("כלי קופסאות", self.list)
self.appendMenu("בונה קופסאות", self.list)
def GetClassName(self):
return "Gui::PythonWorkbench"
FreeCADGui.addCommand("BoxBuilderCommand", BoxBuilderCommand())
ניתוח החלקים המרכזיים
- חלון דו-שיח (
BoxBuilderDialog)
- יורש מ-
QtGui.QDialog - משתמש ב-
QFormLayoutלארגון נקי של השדות - הכפתור "צור קופסה" מפעיל את
on_create(), וכפתור "ביטול" סוגר את החלון
- עיבוד קלט
- ממיר טקסט ל-
float - בודק שהערכים חיוביים
- במקרה של שגיאה – מציג אזהרה באמצעות
QMessageBox.warning
- יצירת אובייקט
- הפונקציה
create_box()מופרדת – לקוד נקי - מייצר שם ייחודי כדי להימנע מתנגנויות
- הפעלת החלון
dialog.exec_()הופך את החלון למודאלי (לא ניתן לערוך את FreeCAD בזמן שהוא פתוח)
שלב 4. בדיקת תפקוד
- שמור את הקבצים
- הפעל מחדש את FreeCAD
- בחר את סביבת העבודה "בונה קופסאות"
- לחץ על הכפתור "בונה קופסאות"
- הזן ממדים בחלון שמופיע → לחץ על "צור קופסה"
קופסה עם הפרמטרים שלך אמורה להופיע!
נסה את הדברים הבאים:
- הזן אותיות → תופיע שגיאה
- הזן מספר שלילי → שגיאה
- הזן מספרים עשרוניים (למשל 12.5) → עובד!
משימה מעשית
- הוסף שדה רביעי: "שם" – כדי שהמשתמש יוכל לקבוע את שם האובייקט.
- ודא שאם השם ריק, יוגדר ערך ברירת מחדל (
"CustomBox"). - הוסף תיבת סימון "מרכז בראשית הצירים" – אם מסומן, הקופסה תتمركز בראשית הצירים.
רמז למרכזון:
לאחר יצירת הקופסה, שנה את מאפיין ה-Placement:
from FreeCAD import Vector
box.Placement.Base = Vector(-length/2, -width/2, -height/2)
טיפים לעבודה עם ממשק גרפי
- תמיד עטוף קלט ב-
try/except– המשתמש יכול להזין כל דבר - באפשרותך להשתמש ב-
QDoubleValidatorכדי לאפשר רק מספרים (אופציונלי) - עבור ממשקים מורכבים עדיף להשתמש ב-Qt Designer ולטעון קבצי
.ui, אך עבור משימות פשוטות – הקוד קל יותר
מה הלאה?
בשיעור 5 נלמד:
- כיצד לשמור הגדרות בין הפעלות של FreeCAD
- לוודא שערכי הממדים האחרונים נשמרים
- להשתמש במנגנון המובנה של FreeCAD:
FreeCAD.ParamGet()
כך התוסף שלך יהפוך לנוח עוד יותר!
שיעור 4. ממשק משתמש גרפי (GUI): חלון דו-שיח עם שדות קלט
מאת hypo69 / 03.10.2025
מדריך: יצירת תוספים עבור FreeCAD
מטרת השיעור: צור חלון עם שדות להזנת אורך, רוחב וגובה, ובנה קופסה עם פרמטרים אלו בלחיצה על כפתור.
חלק 1. כיצד פועל הממשק הגרפי ב-FreeCAD?
FreeCAD משתמש ב-PySide – מעטפת פייתון לספריית Qt (אותה ספריה המשמשת גם ב-Blender, Maya ותוכניות רבות אחרות).
רכיבים עיקריים:
QtGui.QDialog— חלון מודאליQtGui.QLineEdit— שדה קלט טקסטQtGui.QPushButton— כפתורQtGui.QFormLayout— עיצוב נוח בסגנון "תווית + שדה"
כל רכיבי הממשק נוצרים בתוך סקריפט פייתון – ללא קבצים חיצוניים (למרות שניתן להשתמש בקבצי .ui מתוך Qt Designer; נתחיל עם משהו פשוט).
חלק 2. תוסף: "בונה קופסאות עם ממשק גרפי"
נשפר את התוסף הקודם על ידי הוספת חלון דו-שיח.
שלב 1. יצירת תיקייה
.../Mod/BoxBuilderAddon/
שלב 2. קובץ InitGui.py
# InitGui.py
import FreeCADGui
from BoxBuilderAddon.box_builder_workbench import BoxBuilderWorkbench
FreeCADGui.addWorkbench(BoxBuilderWorkbench())
שלב 3. קובץ box_builder_workbench.py
# box_builder_workbench.py
import FreeCAD, FreeCADGui
from PySide import QtGui, QtCore
# === פונקציית יצירת הקופסה ===
def create_box(length, width, height, name="CustomBox"):
doc = FreeCAD.ActiveDocument
if not doc:
doc = FreeCAD.newDocument("BoxBuilder")
# שם ייחודי
base_name = name
index = 1
obj_name = base_name
while obj_name in [obj.Name for obj in doc.Objects]:
obj_name = f"{base_name}_{index}"
index += 1
box = doc.addObject("Part::Box", obj_name)
box.Length = length
box.Width = width
box.Height = height
doc.recompute()
return box
# === חלון דו-שיח ===
class BoxBuilderDialog(QtGui.QDialog):
def __init__(self):
super(BoxBuilderDialog, self).__init__()
self.setWindowTitle("בונה קופסאות")
self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
self.resize(300, 150)
# שדות קלט
self.length_input = QtGui.QLineEdit("30.0")
self.width_input = QtGui.QLineEdit("20.0")
self.height_input = QtGui.QLineEdit("10.0")
# כפתורים
self.create_button = QtGui.QPushButton("צור קופסה")
self.cancel_button = QtGui.QPushButton("ביטול")
# חיבור כפתורים
self.create_button.clicked.connect(self.on_create)
self.cancel_button.clicked.connect(self.reject)
# עיצוב
layout = QtGui.QFormLayout()
layout.addRow("אורך (מ\"מ):", self.length_input)
layout.addRow("רוחב (מ\"מ):", self.width_input)
layout.addRow("גובה (מ\"מ):", self.height_input)
button_layout = QtGui.QHBoxLayout()
button_layout.addWidget(self.create_button)
button_layout.addWidget(self.cancel_button)
main_layout = QtGui.QVBoxLayout()
main_layout.addLayout(layout)
main_layout.addLayout(button_layout)
self.setLayout(main_layout)
def on_create(self):
try:
length = float(self.length_input.text())
width = float(self.width_input.text())
height = float(self.height_input.text())
if length <= 0 or width <= 0 or height <= 0:
raise ValueError("כל הממדים חייבים להיות חיוביים")
create_box(length, width, height)
self.accept() # סגירת החלון
except ValueError as e:
QtGui.QMessageBox.warning(self, "שגיאת קלט", f"קלט לא חוקי:\n{str(e)}")
# === פקודה ===
class BoxBuilderCommand:
def GetResources(self):
return {
"MenuText": "בונה קופסאות",
"ToolTip": "צור קופסה עם ממדים מותאמים אישית"
}
def Activated(self):
dialog = BoxBuilderDialog()
dialog.exec_() # קריאה מודאלית
def IsActive(self):
return True
# === סביבת עבודה ===
class BoxBuilderWorkbench(FreeCADGui.Workbench):
MenuText = "בונה קופסאות"
ToolTip = "צור קופסאות מותאמות עם ממשק גרפי"
def Initialize(self):
self.list = ["BoxBuilderCommand"]
self.appendToolbar("כלי קופסאות", self.list)
self.appendMenu("בונה קופסאות", self.list)
def GetClassName(self):
return "Gui::PythonWorkbench"
FreeCADGui.addCommand("BoxBuilderCommand", BoxBuilderCommand())
ניתוח החלקים המרכזיים
- חלון דו-שיח (
BoxBuilderDialog)
- יורש מ-
QtGui.QDialog - משתמש ב-
QFormLayoutלארגון נקי של השדות - הכפתור "צור קופסה" מפעיל את
on_create(), וכפתור "ביטול" סוגר את החלון
- עיבוד קלט
- ממיר טקסט ל-
float - בודק שהערכים חיוביים
- במקרה של שגיאה – מציג אזהרה באמצעות
QMessageBox.warning
- יצירת אובייקט
- הפונקציה
create_box()מופרדת – לקוד נקי - מייצר שם ייחודי כדי להימנע מתנגנויות
- הפעלת החלון
dialog.exec_()הופך את החלון למודאלי (לא ניתן לערוך את FreeCAD בזמן שהוא פתוח)
שלב 4. בדיקת תפקוד
- שמור את הקבצים
- הפעל מחדש את FreeCAD
- בחר את סביבת העבודה "בונה קופסאות"
- לחץ על הכפתור "בונה קופסאות"
- הזן ממדים בחלון שמופיע → לחץ על "צור קופסה"
קופסה עם הפרמטרים שלך אמורה להופיע!
נסה את הדברים הבאים:
- הזן אותיות → תופיע שגיאה
- הזן מספר שלילי → שגיאה
- הזן מספרים עשרוניים (למשל 12.5) → עובד!
משימה מעשית
- הוסף שדה רביעי: "שם" – כדי שהמשתמש יוכל לקבוע את שם האובייקט.
- ודא שאם השם ריק, יוגדר ערך ברירת מחדל (
"CustomBox"). - הוסף תיבת סימון "מרכז בראשית הצירים" – אם מסומן, הקופסה תتمركز בראשית הצירים.
רמז למרכזון:
לאחר יצירת הקופסה, שנה את מאפיין ה-Placement:
from FreeCAD import Vector
box.Placement.Base = Vector(-length/2, -width/2, -height/2)
טיפים לעבודה עם ממשק גרפי
- תמיד עטוף קלט ב-
try/except– המשתמש יכול להזין כל דבר - באפשרותך להשתמש ב-
QDoubleValidatorכדי לאפשר רק מספרים (אופציונלי) - עבור ממשקים מורכבים עדיף להשתמש ב-Qt Designer ולטעון קבצי
.ui, אך עבור משימות פשוטות – הקוד קל יותר
מה הלאה?
בשיעור 5 נלמד:
- כיצד לשמור הגדרות בין הפעלות של FreeCAD
- לוודא שערכי הממדים האחרונים נשמרים
- להשתמש במנגנון המובנה של FreeCAD:
FreeCAD.ParamGet()
כך התוסף שלך יהפוך לנוח עוד יותר!