Перейти до вмісту
> 💻 🧠 Код 1001 > 🧪📓 Без категорії > Урок 5. Збереження та Завантаження Налаштувань

Урок 5. Збереження та Завантаження Налаштувань

  • від

Мета уроку: Зробити так, щоб додаток “Box Builder” запам’ятовував останні введені розміри та відновлював їх при наступному запуску.


💾 Частина 1. Як FreeCAD зберігає налаштування?

FreeCAD надає вбудований механізм для зберігання користувацьких параметрів — через Менеджер Параметрів (Parameter Manager).

Він працює з ієрархічною базою даних параметрів, схожою на Реєстр Windows.

Основні методи:

# Отримати групу параметрів
1    params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/MyAddon")
2    
3    # Зберегти значення
4    params.SetFloat("LastLength", 30.0)
5    params.SetString("LastName", "MyBox")
6    
7    # Завантажити значення (зі значенням за замовчуванням)
8    length = params.GetFloat("LastLength", 10.0) # 10.0 — якщо такий
9    parameter does not exist
10   name = params.GetString("LastName", "DefaultBox")

💡 Шлях "User parameter:BaseApp/Preferences/..." є стандартним місцем для користувацьких налаштувань.

2/9

🛠️ Частина 2. Оновлений Додаток: “Box Builder with Memory”

Ми модифікуємо попередній додаток, додавши збереження та завантаження останніх значень.

Файл box_builder_workbench.py (оновлена версія)

# box_builder_workbench.py
1    import FreeCAD, FreeCADGui
2    from PySide import QtGui, QtCore
3    
4    # === ШЛЯХ ДО НАЛАШТУВАНЬ ===
5    PARAM_PATH = "User parameter:BaseApp/Preferences/BoxBuilderAddon"
6    
7    def get_saved_settings():
8        """Завантажує збережені налаштування або повертає значення за замовчуванням"""
9        params = FreeCAD.ParamGet(PARAM_PATH)
10       return {
11           "length": params.GetFloat("LastLength", 30.0),
12           "width": params.GetFloat("LastWidth", 20.0),
13           "height": params.GetFloat("LastHeight", 10.0),
14           "name": params.GetString("LastName", "CustomBox")
15       }
16   
17   def save_settings(length, width, height, name):
18       """Зберігає поточні налаштування"""
19       params = FreeCAD.ParamGet(PARAM_PATH)
20       params.SetFloat("LastLength", length)
21       params.SetFloat("LastWidth", width)
22       params.SetFloat("LastHeight", height)
23       params.SetString("LastName", name)
24   
25   
26   # === ФУНКЦІЯ СТВОРЕННЯ КОРОБКИ ===
27   def create_box(length, width, height, name="CustomBox"):
28       doc = FreeCAD.ActiveDocument
29       if not doc:
30           doc = FreeCAD.newDocument("BoxBuilder")
31       
32       # Унікальне ім'я
33       base_name = name
34       index = 1
35       obj_name = base_name
36       while obj_name in [obj.Name for obj in doc.Objects]:
37           obj_name = f"{base_name}_{index}"
38           index += 1
39       
40       box = doc.addObject("Part::Box", obj_name)
41       box.Length = length
42       box.Width = width
43       box.Height = height
44       doc.recompute()
45       return box
46   
47   # === ДІАЛОГОВЕ ВІКНО ===
48   class BoxBuilderDialog (QtGui.QDialog):
49       def __init__(self):
50           super(BoxBuilderDialog, self).__init__()
51           self.setWindowTitle("Box Builder")
52           self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
53           self.resize(300, 180)
54   
55           # Завантажити збережені налаштування
56           settings = get_saved_settings()
57   
58           # Поля введення
59           self.length_input = QtGui.QLineEdit(str(settings["length"]))
60           self.width_input = QtGui.QLineEdit(str(settings["width"]))
61           self.height_input = QtGui.QLineEdit(str(settings["height"]))
62           self.name_input = QtGui.QLineEdit(settings["name"])
63   
64           # Кнопки
65           self.create_button = QtGui.QPushButton("Create Box")
66           self.cancel_button = QtGui.QPushButton("Cancel")
67   
68           # Підключення
69           self.create_button.clicked.connect(self.on_create)
70           self.cancel_button.clicked.connect(self.reject)
71   
72           # Макет
73           layout = QtGui.QFormLayout()
74           layout.addRow("Name:", self.name_input)
75           layout.addRow("Length (mm):", self.length_input)
76           layout.addRow("Width (mm):", self.width_input)
77           layout.addRow("Height (mm):", self.height_input)
78   
79           button_layout = QtGui.QHBoxLayout()
80           button_layout.addWidget(self.create_button)
81           button_layout.addWidget(self.cancel_button)
82   
83           main_layout = QtGui.QVBoxLayout()
84           main_layout.addLayout(layout)
85           main_layout.addLayout(button_layout)
86           self.setLayout(main_layout)
87   
88       def on_create(self):
89           try:
90               name = self.name_input.text().strip()
91               if not name:
92                   name = "CustomBox"
93   
94               length = float(self.length_input.text())
95               width = float(self.width_input.text())
96               height = float(self.height_input.text())
97   
98               if length <= 0 or width <= 0 or height <= 0:
99                   raise ValueError("Всі розміри мають бути позитивними")
100  
101              # Створити об'єкт
102              create_box(length, width, height, name)
103  
104              # Зберегти налаштування
105              save_settings(length, width, height, name)
106  
107              self.accept()
108  
109          except ValueError as e:
110              QtGui.QMessageBox.warning(self, "Помилка введення", f"Недійсне введення:\n{str(e)}")
111  
112      # === КОМАНДА ТА РОБОЧЕ СЕРЕДОВИЩЕ (без змін) ===
113  class BoxBuilderCommand:
114      def GetResources(self):
115          return {"MenuText": "Box Builder", "ToolTip": "Створити коробку з власними розмірами"}
116  
117      def Activated(self):
118          dialog = BoxBuilderDialog()
119          dialog.exec_()
120  
121      def IsActive(self):
122          return True
123  
124  class BoxBuilderWorkbench(FreeCADGui.Workbench):
125      MenuText = "Box Builder"
126      ToolTip = "Створення власних коробок за допомогою GUI"
127  
128      def Initialize(self):
129          self.list = ["BoxBuilderCommand"]
130          self.appendToolbar("Box Tools", self.list)
131          self.appendMenu("Box Builder", self.list)
132  
133      def GetClassName(self):
134          return "Gui::PythonWorkbench"
135  
136  FreeCADGui.addCommand("BoxBuilderCommand", BoxBuilderCommand())

🔎 Що змінилося?

1. Додано функції:

  • get_saved_settings() — завантажує останні значення
  • save_settings() — зберігає поточні значення

2. Шлях до параметрів:

1    PARAM_PATH = "User parameter:BaseApp/Preferences/BoxBuilderAddon"

Усі налаштування зберігаються в окремій групі, не заважаючи іншим додаткам.

3. Додано поле для імені в інтерфейс.

4. При запуску вікна поля заповнюються збереженими значеннями.

5. Після створення поточні значення зберігаються автоматично.

📋 Перевірка роботи

  1. Запустіть FreeCAD
  2. Відкрийте Box Builder
  3. Введіть, наприклад:
    • Name: MyTestBox
    • Length: 50
    • Width: 30
    • Height: 20
  4. Натисніть Create Box
  5. Закрийте FreeCAD
  6. Запустіть знову
  7. Відкрийте Box Builder

✅ Поля мають бути заповнені тими самими значеннями!


❓ Де зберігаються ці налаштування?

  • Windows: у реєстрі (HKEY_CURRENT_USER\SOFTWARE\FreeCAD\...)
  • Linux/macOS: у файлі user.cfg всередині теки FreeCAD

Але вам не потрібно цього знати — FreeCAD сам керує зберіганням.


🥕 Практичне завдання

  1. Додайте прапорець “Center on origin” (Центрувати по початку координат) і збережіть його стан між запусками.
  2. Переконайтеся, що при першому запуску додатка використовуються розумні значення за замовчуванням (вже реалізовано).
  3. Додайте кнопку “Reset to defaults” (Скинути до замовчування), яка скидає поля до значень за замовчуванням і очищає збережені налаштування.

💡 Підказка для скидання:

def reset_settings():
1    params = FreeCAD.ParamGet(PARAM_PATH)
2    params.RemGroup("BoxBuilderAddon") # Видаляє всю групу
3    

💡 Поради

  • Завжди вказуйте значення за замовчуванням у GetFloat(), GetString() тощо.
  • Не зберігайте занадто багато — лише те, що дійсно потрібно користувачеві
  • Використовуйте унікальний шлях (BoxBuilderAddon), щоб уникнути конфліктів з іншими додатками

⏭️ Що далі?

В Уроці 6 ми:

  • Додамо іконки до кнопок та робочого середовища
  • Дізнаємося, як використовувати SVG та PNG в інтерфейсі
  • Зробимо додаток візуально привабливим

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *