RCAIDE-GUI 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- common_widgets/__init__.py +6 -0
- common_widgets/animated_toggle.py +141 -0
- common_widgets/color.py +17 -0
- common_widgets/data_entry_widget.py +337 -0
- common_widgets/image_widget.py +21 -0
- common_widgets/unit_picker_widget.py +48 -0
- main.py +168 -0
- rcaide_gui-1.0.0.dist-info/METADATA +96 -0
- rcaide_gui-1.0.0.dist-info/RECORD +170 -0
- rcaide_gui-1.0.0.dist-info/WHEEL +5 -0
- rcaide_gui-1.0.0.dist-info/entry_points.txt +2 -0
- rcaide_gui-1.0.0.dist-info/top_level.txt +5 -0
- rcaide_io.py +818 -0
- tabs/__init__.py +10 -0
- tabs/aircraft_configs/__init__.py +3 -0
- tabs/aircraft_configs/aircraft_configs.py +301 -0
- tabs/analysis/__init__.py +4 -0
- tabs/analysis/analysis.py +92 -0
- tabs/analysis/widgets/__init__.py +13 -0
- tabs/analysis/widgets/aeroacoustics_widget.py +158 -0
- tabs/analysis/widgets/aerodynamics_widget.py +108 -0
- tabs/analysis/widgets/analysis_data_widget.py +29 -0
- tabs/analysis/widgets/atmosphere_widget.py +49 -0
- tabs/analysis/widgets/costs_widget.py +35 -0
- tabs/analysis/widgets/energy_widget.py +32 -0
- tabs/analysis/widgets/geometry_widget.py +55 -0
- tabs/analysis/widgets/planets_widget.py +34 -0
- tabs/analysis/widgets/propulsion_widget.py +53 -0
- tabs/analysis/widgets/stability_widget.py +34 -0
- tabs/analysis/widgets/weights_widget.py +94 -0
- tabs/geometry/__init__.py +6 -0
- tabs/geometry/aircraft_configs.py +232 -0
- tabs/geometry/frames/__init__.py +15 -0
- tabs/geometry/frames/booms/__init__.py +5 -0
- tabs/geometry/frames/booms/boom_frame.py +238 -0
- tabs/geometry/frames/cargo_bays/__init__.py +5 -0
- tabs/geometry/frames/cargo_bays/cargo_bay_frame.py +159 -0
- tabs/geometry/frames/default_frame.py +23 -0
- tabs/geometry/frames/energy_network/__init__.py +2 -0
- tabs/geometry/frames/energy_network/turbofan_network/__init__.py +3 -0
- tabs/geometry/frames/energy_network/turbofan_network/frames/__init__.py +1 -0
- tabs/geometry/frames/energy_network/turbofan_network/widgets/__init__.py +1 -0
- tabs/geometry/frames/fuselages/__init__.py +5 -0
- tabs/geometry/frames/fuselages/fuselage_frame.py +294 -0
- tabs/geometry/frames/geometry_frame.py +91 -0
- tabs/geometry/frames/landing_gears/__init__.py +5 -0
- tabs/geometry/frames/landing_gears/landing_gear_frame.py +189 -0
- tabs/geometry/frames/nacelles/__init__.py +1 -0
- tabs/geometry/frames/powertrain/__init__.py +6 -0
- tabs/geometry/frames/powertrain/converters/__init__.py +5 -0
- tabs/geometry/frames/powertrain/converters/converter_frame.py +137 -0
- tabs/geometry/frames/powertrain/distributors/__init__.py +5 -0
- tabs/geometry/frames/powertrain/distributors/distributor_frame.py +143 -0
- tabs/geometry/frames/powertrain/nacelles/__init__.py +5 -0
- tabs/geometry/frames/powertrain/nacelles/nacelle_frame.py +283 -0
- tabs/geometry/frames/powertrain/powertrain_frame.py +259 -0
- tabs/geometry/frames/powertrain/propulsors/__init__.py +5 -0
- tabs/geometry/frames/powertrain/propulsors/propulsor_frame.py +146 -0
- tabs/geometry/frames/powertrain/sources/__init__.py +6 -0
- tabs/geometry/frames/powertrain/sources/energy_source_frame.py +147 -0
- tabs/geometry/frames/vehicle_frame.py +171 -0
- tabs/geometry/frames/wings/__init__.py +5 -0
- tabs/geometry/frames/wings/wings_frame.py +457 -0
- tabs/geometry/geometry.py +513 -0
- tabs/geometry/widgets/__init__.py +12 -0
- tabs/geometry/widgets/booms/__init__.py +6 -0
- tabs/geometry/widgets/booms/boom_section_widget.py +109 -0
- tabs/geometry/widgets/cargo_bays/__init__.py +1 -0
- tabs/geometry/widgets/fuselages/__init__.py +8 -0
- tabs/geometry/widgets/fuselages/cabin_class_widget.py +188 -0
- tabs/geometry/widgets/fuselages/cabin_widget.py +217 -0
- tabs/geometry/widgets/fuselages/fuselage_section_widget.py +190 -0
- tabs/geometry/widgets/geometry_data_widget.py +25 -0
- tabs/geometry/widgets/landing_gears/__init__.py +6 -0
- tabs/geometry/widgets/nacelles/__init__.py +1 -0
- tabs/geometry/widgets/powertrain/__init__.py +9 -0
- tabs/geometry/widgets/powertrain/converters/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/converters/turboelectric_generator_widget.py +74 -0
- tabs/geometry/widgets/powertrain/distributors/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/distributors/fuel_line_widget.py +81 -0
- tabs/geometry/widgets/powertrain/modulators/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/modulators/esc_widget.py +58 -0
- tabs/geometry/widgets/powertrain/nacelles/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/nacelles/nacelle_section_widget.py +115 -0
- tabs/geometry/widgets/powertrain/powertrain_connector_widget.py +136 -0
- tabs/geometry/widgets/powertrain/powertrain_widget.py +206 -0
- tabs/geometry/widgets/powertrain/propulsors/__init__.py +5 -0
- tabs/geometry/widgets/powertrain/propulsors/turbofan_widget.py +462 -0
- tabs/geometry/widgets/powertrain/sources/__init__.py +6 -0
- tabs/geometry/widgets/powertrain/sources/fuel_tank_widget.py +103 -0
- tabs/geometry/widgets/powertrain/sources/source_selector_widget.py +35 -0
- tabs/geometry/widgets/wings/__init__.py +7 -0
- tabs/geometry/widgets/wings/wing_cs_widget.py +198 -0
- tabs/geometry/widgets/wings/wing_section_widget.py +298 -0
- tabs/home/__init__.py +3 -0
- tabs/home/home.py +585 -0
- tabs/mission/__init__.py +4 -0
- tabs/mission/mission.py +1124 -0
- tabs/mission/widgets/__init__.py +3 -0
- tabs/mission/widgets/flight_controls_widget.py +186 -0
- tabs/mission/widgets/mission_analysis_widget.py +166 -0
- tabs/mission/widgets/mission_segment_helper.py +358 -0
- tabs/mission/widgets/mission_segment_widget.py +358 -0
- tabs/solve/__init__.py +4 -0
- tabs/solve/plots/__init__.py +12 -0
- tabs/solve/plots/aeroacoustics/__init__.py +6 -0
- tabs/solve/plots/aeroacoustics/plot_2D_noise_contour.py +184 -0
- tabs/solve/plots/aeroacoustics/plot_3D_noise_contour.py +219 -0
- tabs/solve/plots/aeroacoustics/plot_noise_certification_contour.py +115 -0
- tabs/solve/plots/aeroacoustics/plot_noise_level.py +118 -0
- tabs/solve/plots/aerodynamics/__init__.py +10 -0
- tabs/solve/plots/aerodynamics/plot_aerodynamic_coefficients.py +156 -0
- tabs/solve/plots/aerodynamics/plot_aerodynamic_forces.py +155 -0
- tabs/solve/plots/aerodynamics/plot_aircraft_aerodynamics.py +136 -0
- tabs/solve/plots/aerodynamics/plot_drag_components.py +157 -0
- tabs/solve/plots/aerodynamics/plot_lift_distribution.py +107 -0
- tabs/solve/plots/aerodynamics/plot_rotor_conditions.py +255 -0
- tabs/solve/plots/aerodynamics/plot_rotor_disc_performance.py +144 -0
- tabs/solve/plots/aerodynamics/plot_rotor_performance.py +124 -0
- tabs/solve/plots/common/__init__.py +4 -0
- tabs/solve/plots/common/plot_style.py +71 -0
- tabs/solve/plots/common/set_axes.py +55 -0
- tabs/solve/plots/create_plot_widgets.py +34 -0
- tabs/solve/plots/emissions/__init__.py +3 -0
- tabs/solve/plots/emissions/plot_emissions.py +167 -0
- tabs/solve/plots/energy/__init__.py +12 -0
- tabs/solve/plots/energy/plot_altitude_sfc_weight.py +134 -0
- tabs/solve/plots/energy/plot_battery_cell_conditions.py +154 -0
- tabs/solve/plots/energy/plot_battery_degradation.py +157 -0
- tabs/solve/plots/energy/plot_battery_module_C_rates.py +139 -0
- tabs/solve/plots/energy/plot_battery_module_conditions.py +157 -0
- tabs/solve/plots/energy/plot_battery_pack_conditions.py +164 -0
- tabs/solve/plots/energy/plot_battery_ragone_diagram.py +97 -0
- tabs/solve/plots/energy/plot_battery_temperature.py +136 -0
- tabs/solve/plots/energy/plot_electric_propulsor_efficiencies.py +136 -0
- tabs/solve/plots/energy/plot_propulsor_throttles.py +119 -0
- tabs/solve/plots/mission/__init__.py +5 -0
- tabs/solve/plots/mission/plot_aircraft_velocities.py +145 -0
- tabs/solve/plots/mission/plot_flight_conditions.py +236 -0
- tabs/solve/plots/mission/plot_flight_trajectory.py +172 -0
- tabs/solve/plots/stability/__init__.py +5 -0
- tabs/solve/plots/stability/plot_flight_forces_and_moments.py +163 -0
- tabs/solve/plots/stability/plot_lateral_stability.py +151 -0
- tabs/solve/plots/stability/plot_longitudinal_stability.py +173 -0
- tabs/solve/plots/thermal_management/__init__.py +7 -0
- tabs/solve/plots/thermal_management/plot_air_cooled_conditions.py +152 -0
- tabs/solve/plots/thermal_management/plot_cross_flow_heat_exchanger_conditions.py +185 -0
- tabs/solve/plots/thermal_management/plot_reservoir_conditions.py +141 -0
- tabs/solve/plots/thermal_management/plot_thermal_management_performance.py +105 -0
- tabs/solve/plots/thermal_management/plot_wavy_channel_conditions.py +161 -0
- tabs/solve/plots/weights/__init__.py +4 -0
- tabs/solve/plots/weights/plot_load_diagram.py +163 -0
- tabs/solve/plots/weights/plot_weight_breakdown.py +164 -0
- tabs/solve/solve.py +1498 -0
- tabs/style_sheet.py +114 -0
- tabs/tab_widget.py +14 -0
- tabs/visualize_geometry/__init__.py +4 -0
- tabs/visualize_geometry/core_3d_viewer.py +253 -0
- tabs/visualize_geometry/features/__init__.py +10 -0
- tabs/visualize_geometry/features/axes_gizmo.py +173 -0
- tabs/visualize_geometry/features/background.py +161 -0
- tabs/visualize_geometry/features/blueprint.py +685 -0
- tabs/visualize_geometry/features/camera.py +364 -0
- tabs/visualize_geometry/features/drag_aircraft.py +219 -0
- tabs/visualize_geometry/features/grid.py +194 -0
- tabs/visualize_geometry/features/measurement.py +367 -0
- tabs/visualize_geometry/features/screenshot.py +91 -0
- tabs/visualize_geometry/geometry_helper_functions.py +3 -0
- tabs/visualize_geometry/visualize_geometry.py +731 -0
- utilities.py +257 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/aircraft_configs.py
|
|
2
|
+
|
|
3
|
+
# RCAIDE imports
|
|
4
|
+
import RCAIDE
|
|
5
|
+
|
|
6
|
+
# RCAIDE-GUI imports
|
|
7
|
+
from tabs.geometry.frames import *
|
|
8
|
+
from tabs import TabWidget
|
|
9
|
+
from utilities import set_data
|
|
10
|
+
import rcaide_io
|
|
11
|
+
from common_widgets import Color
|
|
12
|
+
|
|
13
|
+
# PyQt imports
|
|
14
|
+
from PyQt6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QComboBox, QStackedLayout, QTreeWidget, QTreeWidgetItem, QLabel, QLineEdit
|
|
15
|
+
|
|
16
|
+
# Python imports
|
|
17
|
+
import json
|
|
18
|
+
from typing import Type
|
|
19
|
+
|
|
20
|
+
# WARNING: This file is incomplete and is not intended to be used yet.
|
|
21
|
+
|
|
22
|
+
# ------------------------------------------------------------------------------
|
|
23
|
+
# Aircraft Configs Widget
|
|
24
|
+
# ------------------------------------------------------------------------------
|
|
25
|
+
class AircraftConfigsWidget(TabWidget):
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Create a widget for entering vehicle geometry."""
|
|
28
|
+
super(AircraftConfigsWidget, self).__init__()
|
|
29
|
+
|
|
30
|
+
# Define actions based on the selected index
|
|
31
|
+
self.frames: list[Type[GeometryFrame]] = [DefaultFrame, FuselageFrame, WingsFrame,
|
|
32
|
+
LandingGearFrame, PowertrainFrame]
|
|
33
|
+
|
|
34
|
+
self.tabs = ["", "Booms", "Cargo Bars", "Fuselages","Landing Gear","Wings", "Powertrain"]
|
|
35
|
+
|
|
36
|
+
options = ["Add Vehicle Component", "Add Boom", "Add Cargo Bay", "Add Fuselage",
|
|
37
|
+
"Add Landing Gear" , "Add Powertrain", "Add Wing"]
|
|
38
|
+
|
|
39
|
+
self.selected_config_index = 0
|
|
40
|
+
|
|
41
|
+
rcaide_io.config_data = [[]]
|
|
42
|
+
|
|
43
|
+
for _ in range(len(self.tabs)):
|
|
44
|
+
rcaide_io.config_data[0].append([])
|
|
45
|
+
|
|
46
|
+
base_layout = QHBoxLayout()
|
|
47
|
+
self.tree_frame_layout = QVBoxLayout()
|
|
48
|
+
self.right_layout = QVBoxLayout()
|
|
49
|
+
self.main_layout = QStackedLayout()
|
|
50
|
+
|
|
51
|
+
for index, frame in enumerate(self.frames):
|
|
52
|
+
frame_widget = frame()
|
|
53
|
+
frame_widget.set_save_function(self.save_data)
|
|
54
|
+
frame_widget.set_tab_index(index)
|
|
55
|
+
self.main_layout.addWidget(frame_widget) # type: ignore
|
|
56
|
+
|
|
57
|
+
vehicle_name_layout = QHBoxLayout()
|
|
58
|
+
vehicle_name_layout.addWidget(QLabel("Configuration Name:"))
|
|
59
|
+
rcaide_io.vehicle_name_input = QLineEdit()
|
|
60
|
+
vehicle_name_layout.addWidget(rcaide_io.vehicle_name_input)
|
|
61
|
+
self.tree_frame_layout.addLayout(vehicle_name_layout)
|
|
62
|
+
|
|
63
|
+
self.dropdown = QComboBox()
|
|
64
|
+
self.dropdown.addItems(options)
|
|
65
|
+
self.dropdown.currentIndexChanged.connect(self.on_dropdown_change)
|
|
66
|
+
self.tree_frame_layout.addWidget(self.dropdown)
|
|
67
|
+
|
|
68
|
+
# Create a QComboBox and add options
|
|
69
|
+
self.tree = QTreeWidget()
|
|
70
|
+
self.tree.setColumnCount(1)
|
|
71
|
+
self.tree.setHeaderLabels(["Vehicle Components"])
|
|
72
|
+
self.tree.itemClicked.connect(self.on_tree_item_clicked)
|
|
73
|
+
|
|
74
|
+
config_items = [QTreeWidgetItem(["Base Configuration"])]
|
|
75
|
+
self.tree.addTopLevelItems(config_items)
|
|
76
|
+
self.tree_frame_layout.addWidget(self.tree)
|
|
77
|
+
|
|
78
|
+
self.right_layout.addWidget(Color("blue"), 3)
|
|
79
|
+
self.right_layout.addLayout(self.main_layout, 7)
|
|
80
|
+
base_layout.addLayout(self.tree_frame_layout, 1)
|
|
81
|
+
base_layout.addLayout(self.right_layout, 4)
|
|
82
|
+
|
|
83
|
+
self.main_layout.setSpacing(3)
|
|
84
|
+
base_layout.setSpacing(3)
|
|
85
|
+
|
|
86
|
+
# Initially display the DefaultFrame
|
|
87
|
+
self.main_layout.setCurrentIndex(0)
|
|
88
|
+
self.setLayout(base_layout)
|
|
89
|
+
|
|
90
|
+
def on_dropdown_change(self, index):
|
|
91
|
+
"""Change the index of the main layout based on the selected index of the dropdown.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
index: The index of the selected item in the dropdown.
|
|
95
|
+
"""
|
|
96
|
+
layout = self.layout()
|
|
97
|
+
if layout:
|
|
98
|
+
self.main_layout.setCurrentIndex(index)
|
|
99
|
+
|
|
100
|
+
def on_tree_item_clicked(self, item: QTreeWidgetItem, _col):
|
|
101
|
+
"""Change the index of the main layout based on the selected item in the tree.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
item: The selected item in the tree.
|
|
105
|
+
_col: The column index of the selected item. (Not used)
|
|
106
|
+
|
|
107
|
+
"""
|
|
108
|
+
assert item is not None
|
|
109
|
+
# get item depth
|
|
110
|
+
depth = 0
|
|
111
|
+
|
|
112
|
+
item2: QTreeWidgetItem = item
|
|
113
|
+
while item2.parent():
|
|
114
|
+
parent = item2.parent()
|
|
115
|
+
assert parent is not None
|
|
116
|
+
|
|
117
|
+
item2 = parent
|
|
118
|
+
depth += 1
|
|
119
|
+
|
|
120
|
+
if depth == 0:
|
|
121
|
+
self.main_layout.setCurrentIndex(0)
|
|
122
|
+
return
|
|
123
|
+
if depth == 1:
|
|
124
|
+
top_item = item.parent()
|
|
125
|
+
|
|
126
|
+
assert top_item is not None
|
|
127
|
+
tree_index = top_item.indexOfChild(item)
|
|
128
|
+
tab_index = self.find_tab_index(tree_index)
|
|
129
|
+
|
|
130
|
+
self.main_layout.setCurrentIndex(tab_index)
|
|
131
|
+
if depth == 2:
|
|
132
|
+
component_item = item.parent()
|
|
133
|
+
|
|
134
|
+
assert component_item is not None
|
|
135
|
+
top_item = component_item.parent()
|
|
136
|
+
assert top_item is not None
|
|
137
|
+
|
|
138
|
+
tree_index = top_item.indexOfChild(component_item)
|
|
139
|
+
tab_index = self.find_tab_index(tree_index)
|
|
140
|
+
self.main_layout.setCurrentIndex(tab_index)
|
|
141
|
+
|
|
142
|
+
index = component_item.indexOfChild(item)
|
|
143
|
+
frame = self.main_layout.currentWidget()
|
|
144
|
+
assert isinstance(frame, GeometryFrame)
|
|
145
|
+
frame.load_data(rcaide_io.config_data[tab_index][index], index)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def save_data(self, tab_index, vehicle_component=None, index=0, data=None, new=False):
|
|
149
|
+
"""Save the entered data in a frame to the list.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
tab_index: The index of the tab.
|
|
153
|
+
index: The index of the vehicle element in the list. (Within its type, eg fuselage #0, #1, etc.)
|
|
154
|
+
vehicle_component: The vehicle component to be appended to the vehicle.
|
|
155
|
+
data: The data to be saved.
|
|
156
|
+
new: A flag to indicate if the data is of a new element.
|
|
157
|
+
"""
|
|
158
|
+
if data is None:
|
|
159
|
+
return
|
|
160
|
+
|
|
161
|
+
top_item = self.tree.topLevelItem(self.selected_config_index)
|
|
162
|
+
tree_index = self.find_tree_index(tab_index)
|
|
163
|
+
assert top_item is not None
|
|
164
|
+
|
|
165
|
+
if not rcaide_io.config_data[tab_index]:
|
|
166
|
+
component_item = QTreeWidgetItem([self.tabs[tab_index]])
|
|
167
|
+
top_item.insertChild(tree_index, component_item)
|
|
168
|
+
|
|
169
|
+
if new:
|
|
170
|
+
rcaide_io.config_data[tab_index].append(data)
|
|
171
|
+
child = QTreeWidgetItem([data["name"]])
|
|
172
|
+
item = top_item.child(tree_index)
|
|
173
|
+
assert item is not None
|
|
174
|
+
item.addChild(child)
|
|
175
|
+
index = item.indexOfChild(child)
|
|
176
|
+
else:
|
|
177
|
+
rcaide_io.config_data[tab_index][index] = data
|
|
178
|
+
child = top_item.child(tree_index)
|
|
179
|
+
assert child is not None
|
|
180
|
+
child = child.child(index)
|
|
181
|
+
assert child is not None
|
|
182
|
+
child.setText(0, data["name"])
|
|
183
|
+
|
|
184
|
+
# with open("app_data/geometry.json", "w") as f:
|
|
185
|
+
# f.write(json.dumps(rcaide_io.config_data, indent=2))
|
|
186
|
+
|
|
187
|
+
if vehicle_component:
|
|
188
|
+
# Check if it is an energy network being added
|
|
189
|
+
if tab_index == 5:
|
|
190
|
+
rcaide_io.vehicle.append_energy_network(vehicle_component)
|
|
191
|
+
else:
|
|
192
|
+
rcaide_io.vehicle.append_component(vehicle_component)
|
|
193
|
+
|
|
194
|
+
return index
|
|
195
|
+
|
|
196
|
+
def get_vehicle(self):
|
|
197
|
+
return rcaide_io.vehicle
|
|
198
|
+
|
|
199
|
+
def get_data(self):
|
|
200
|
+
return rcaide_io.config_data
|
|
201
|
+
|
|
202
|
+
def find_tree_index(self, tab_index):
|
|
203
|
+
tree_index = tab_index
|
|
204
|
+
for i in range(tree_index):
|
|
205
|
+
if not rcaide_io.config_data[i]:
|
|
206
|
+
tree_index -= 1
|
|
207
|
+
|
|
208
|
+
tree_index = max(0, tree_index)
|
|
209
|
+
return tree_index
|
|
210
|
+
|
|
211
|
+
def find_tab_index(self, tree_index):
|
|
212
|
+
print(tree_index)
|
|
213
|
+
tab_index = 0
|
|
214
|
+
count = 0
|
|
215
|
+
|
|
216
|
+
for i in range(1, len(rcaide_io.config_data)):
|
|
217
|
+
if not rcaide_io.config_data[i]:
|
|
218
|
+
continue
|
|
219
|
+
count += 1
|
|
220
|
+
if count == tree_index + 1:
|
|
221
|
+
tab_index = i
|
|
222
|
+
break
|
|
223
|
+
return tab_index
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def get_widget() -> QWidget:
|
|
227
|
+
"""Return the geometry widget.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
The geometry widget.
|
|
231
|
+
"""
|
|
232
|
+
return AircraftConfigsWidget()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/frames/__init__.py
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
3
|
+
# IMPORT
|
|
4
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
from tabs.geometry.frames.geometry_frame import GeometryFrame
|
|
7
|
+
from tabs.geometry.frames.default_frame import DefaultFrame
|
|
8
|
+
from tabs.geometry.frames.vehicle_frame import VehicleFrame
|
|
9
|
+
|
|
10
|
+
from tabs.geometry.frames.booms import *
|
|
11
|
+
from tabs.geometry.frames.cargo_bays import *
|
|
12
|
+
from tabs.geometry.frames.fuselages import *
|
|
13
|
+
from tabs.geometry.frames.landing_gears import *
|
|
14
|
+
from tabs.geometry.frames.powertrain import *
|
|
15
|
+
from tabs.geometry.frames.wings import *
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/frames/booms/__init__.py
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
3
|
+
# IMPORT
|
|
4
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
from tabs.geometry.frames.booms.boom_frame import BoomFrame
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/frames/booms/boom_frame.py
|
|
2
|
+
#
|
|
3
|
+
# Created: Dec 2025, M. Clarke
|
|
4
|
+
|
|
5
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
6
|
+
# IMPORT
|
|
7
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
# RCAIDE imports
|
|
9
|
+
import RCAIDE
|
|
10
|
+
|
|
11
|
+
# RCAIDE GUI imports
|
|
12
|
+
from tabs.geometry.frames import GeometryFrame
|
|
13
|
+
from tabs.geometry.widgets.booms import BoomSectionWidget
|
|
14
|
+
from utilities import show_popup, create_line_bar, set_data, Units, create_scroll_area, clear_layout
|
|
15
|
+
from common_widgets import DataEntryWidget
|
|
16
|
+
|
|
17
|
+
# PyQT imports
|
|
18
|
+
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QPushButton, QLineEdit, QHBoxLayout, \
|
|
19
|
+
QSpacerItem, QSizePolicy, QScrollArea
|
|
20
|
+
|
|
21
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
22
|
+
# Boom Frame
|
|
23
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
24
|
+
class BoomFrame(GeometryFrame):
|
|
25
|
+
# List of data labels
|
|
26
|
+
data_units_labels = [
|
|
27
|
+
("Fineness Nose", Units.Unitless, "fineness.nose"),
|
|
28
|
+
("Fineness Tail", Units.Unitless, "fineness.tail"),
|
|
29
|
+
("Lengths Nose", Units.Length, "lengths.nose"),
|
|
30
|
+
("Lengths Tail", Units.Length, "lengths.tail"),
|
|
31
|
+
("Lengths Total", Units.Length, "lengths.total"),
|
|
32
|
+
("Width", Units.Length, "width"),
|
|
33
|
+
("Heights Maximum", Units.Length, "heights.maximum"),
|
|
34
|
+
("Height at Quarter", Units.Length, "heights.at_quarter_length"),
|
|
35
|
+
("Height at Three Quarters", Units.Length, "heights.at_three_quarters_length"),
|
|
36
|
+
("Height at Wing Root Quarter Chord", Units.Length, "heights.at_wing_root_quarter_chord"),
|
|
37
|
+
("Areas Side Projected", Units.Area, "areas.side_projected"),
|
|
38
|
+
("Area Wetted", Units.Area, "areas.wetted"),
|
|
39
|
+
("Area Front Projected", Units.Area, "areas.front_projected"),
|
|
40
|
+
("Differential Pressure", Units.Pressure, "differential_pressure"),
|
|
41
|
+
("Effective Diameter", Units.Length, "effective_diameter"),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
def __init__(self):
|
|
45
|
+
"""Create a frame for entering boom data."""
|
|
46
|
+
super(BoomFrame, self).__init__()
|
|
47
|
+
self.data_entry_widget: DataEntryWidget | None = None
|
|
48
|
+
|
|
49
|
+
create_scroll_area(self)
|
|
50
|
+
|
|
51
|
+
assert self.main_layout is not None
|
|
52
|
+
self.main_layout.addWidget(QLabel("<b>Booms</b>"))
|
|
53
|
+
self.main_layout.addWidget(create_line_bar())
|
|
54
|
+
self.index = -1
|
|
55
|
+
|
|
56
|
+
self.add_name_layout()
|
|
57
|
+
|
|
58
|
+
# Add the data entry widget to the main layout
|
|
59
|
+
self.data_entry_widget = DataEntryWidget(self.data_units_labels)
|
|
60
|
+
self.wire_auto_save(self.data_entry_widget)
|
|
61
|
+
self.main_layout.addWidget(self.data_entry_widget)
|
|
62
|
+
self.main_layout.addWidget(create_line_bar())
|
|
63
|
+
|
|
64
|
+
# Add the sections layout to the main layout
|
|
65
|
+
self.boom_sections_layout = QVBoxLayout()
|
|
66
|
+
self.main_layout.addLayout(self.boom_sections_layout)
|
|
67
|
+
|
|
68
|
+
self.add_buttons_layout()
|
|
69
|
+
|
|
70
|
+
# Adds scroll function
|
|
71
|
+
self.main_layout.addItem(QSpacerItem(
|
|
72
|
+
20, 40, QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Expanding))
|
|
73
|
+
|
|
74
|
+
def add_name_layout(self):
|
|
75
|
+
name_layout = QHBoxLayout()
|
|
76
|
+
spacer_left = QSpacerItem(
|
|
77
|
+
50, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
78
|
+
spacer_right = QSpacerItem(
|
|
79
|
+
200, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
80
|
+
self.name_line_edit = QLineEdit(self)
|
|
81
|
+
name_layout.addItem(spacer_left)
|
|
82
|
+
name_layout.addWidget(QLabel("Name: "))
|
|
83
|
+
name_layout.addWidget(self.name_line_edit)
|
|
84
|
+
name_layout.addItem(spacer_right)
|
|
85
|
+
|
|
86
|
+
assert self.main_layout is not None
|
|
87
|
+
self.main_layout.addLayout(name_layout)
|
|
88
|
+
|
|
89
|
+
# noinspection PyUnresolvedReferences
|
|
90
|
+
def add_buttons_layout(self):
|
|
91
|
+
"""Add the save, delete, and new buttons to the layout."""
|
|
92
|
+
new_section_button = QPushButton("New Boom Section", self)
|
|
93
|
+
new_section_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
94
|
+
save_button = QPushButton("Save Data", self)
|
|
95
|
+
save_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
96
|
+
delete_button = QPushButton("Delete Data", self)
|
|
97
|
+
delete_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
98
|
+
new_button = QPushButton("New Boom Structure", self)
|
|
99
|
+
new_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
100
|
+
|
|
101
|
+
new_section_button.clicked.connect(self.add_boom_section)
|
|
102
|
+
save_button.clicked.connect(self.save_data)
|
|
103
|
+
delete_button.clicked.connect(self.delete_data)
|
|
104
|
+
new_button.clicked.connect(self.create_new_structure)
|
|
105
|
+
|
|
106
|
+
buttons_layout = QHBoxLayout()
|
|
107
|
+
buttons_layout.addWidget(new_section_button)
|
|
108
|
+
buttons_layout.addWidget(save_button)
|
|
109
|
+
buttons_layout.addWidget(delete_button)
|
|
110
|
+
buttons_layout.addWidget(new_button)
|
|
111
|
+
|
|
112
|
+
assert self.main_layout is not None
|
|
113
|
+
self.main_layout.addLayout(buttons_layout)
|
|
114
|
+
|
|
115
|
+
# noinspection DuplicatedCode
|
|
116
|
+
def save_data(self):
|
|
117
|
+
"""Call the save function and pass the entered data to it."""
|
|
118
|
+
entered_data, boom = self.get_data_values()
|
|
119
|
+
if self.save_function:
|
|
120
|
+
if self.index >= 0:
|
|
121
|
+
self.index = self.save_function(
|
|
122
|
+
tab_index=self.tab_index, index=self.index, data=entered_data, persist=True)
|
|
123
|
+
return
|
|
124
|
+
else:
|
|
125
|
+
self.index = self.save_function(
|
|
126
|
+
tab_index=self.tab_index, vehicle_component=boom, data=entered_data, new=True, persist=True)
|
|
127
|
+
|
|
128
|
+
show_popup("Data Saved!", self)
|
|
129
|
+
|
|
130
|
+
def add_boom_section(self):
|
|
131
|
+
self.boom_sections_layout.addWidget(BoomSectionWidget(
|
|
132
|
+
self.boom_sections_layout.count(), self.delete_boom_section))
|
|
133
|
+
|
|
134
|
+
def delete_boom_section(self, index):
|
|
135
|
+
item = self.boom_sections_layout.itemAt(index)
|
|
136
|
+
assert item is not None
|
|
137
|
+
widget = item.widget()
|
|
138
|
+
assert widget is not None
|
|
139
|
+
|
|
140
|
+
widget.deleteLater()
|
|
141
|
+
self.boom_sections_layout.removeWidget(widget)
|
|
142
|
+
self.boom_sections_layout.update()
|
|
143
|
+
|
|
144
|
+
for i in range(index, self.boom_sections_layout.count()):
|
|
145
|
+
item = self.boom_sections_layout.itemAt(i)
|
|
146
|
+
if item is None:
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
widget = item.widget()
|
|
150
|
+
if widget is not None and isinstance(widget, BoomSectionWidget):
|
|
151
|
+
widget.index = i
|
|
152
|
+
|
|
153
|
+
# TODO: Implement proper deletion of data
|
|
154
|
+
def delete_data(self):
|
|
155
|
+
pass
|
|
156
|
+
|
|
157
|
+
def create_new_structure(self):
|
|
158
|
+
"""Create a new boom structure."""
|
|
159
|
+
# Clear the main data values
|
|
160
|
+
assert self.data_entry_widget is not None and self.name_line_edit is not None
|
|
161
|
+
self.data_entry_widget.clear_values()
|
|
162
|
+
self.name_line_edit.clear()
|
|
163
|
+
|
|
164
|
+
# Clear the boom sections
|
|
165
|
+
for i in range(self.boom_sections_layout.count()):
|
|
166
|
+
item = self.boom_sections_layout.itemAt(i)
|
|
167
|
+
assert item is not None
|
|
168
|
+
|
|
169
|
+
widget = item.widget()
|
|
170
|
+
assert widget is not None
|
|
171
|
+
|
|
172
|
+
widget.deleteLater()
|
|
173
|
+
|
|
174
|
+
self.boom_sections_layout.update()
|
|
175
|
+
self.index = -1
|
|
176
|
+
|
|
177
|
+
def create_rcaide_structure(self):
|
|
178
|
+
assert self.data_entry_widget is not None
|
|
179
|
+
data = self.data_entry_widget.get_values_si()
|
|
180
|
+
boom = RCAIDE.Library.Components.Booms.Boom()
|
|
181
|
+
for data_unit_label in self.data_units_labels:
|
|
182
|
+
rcaide_label = data_unit_label[-1]
|
|
183
|
+
user_label = data_unit_label[0]
|
|
184
|
+
set_data(boom, rcaide_label, data[user_label][0])
|
|
185
|
+
|
|
186
|
+
for i in range(self.boom_sections_layout.count()):
|
|
187
|
+
item = self.boom_sections_layout.itemAt(i)
|
|
188
|
+
if item is None:
|
|
189
|
+
continue
|
|
190
|
+
|
|
191
|
+
boom_section = item.widget()
|
|
192
|
+
if boom_section is not None and isinstance(boom_section, BoomSectionWidget):
|
|
193
|
+
_, segment = boom_section.get_data_values()
|
|
194
|
+
boom.segments.append(segment)
|
|
195
|
+
|
|
196
|
+
return boom
|
|
197
|
+
|
|
198
|
+
def get_data_values(self):
|
|
199
|
+
"""Retrieve the entered data values from the text fields."""
|
|
200
|
+
assert self.data_entry_widget is not None
|
|
201
|
+
data = self.data_entry_widget.get_values()
|
|
202
|
+
boom = self.create_rcaide_structure()
|
|
203
|
+
|
|
204
|
+
data["sections"] = []
|
|
205
|
+
for i in range(self.boom_sections_layout.count()):
|
|
206
|
+
item = self.boom_sections_layout.itemAt(i)
|
|
207
|
+
if item is None:
|
|
208
|
+
continue
|
|
209
|
+
|
|
210
|
+
boom_section = item.widget()
|
|
211
|
+
if boom_section is not None and isinstance(boom_section, BoomSectionWidget):
|
|
212
|
+
segment_data, segment = boom_section.get_data_values()
|
|
213
|
+
data["sections"].append(segment_data)
|
|
214
|
+
boom.append_segment(segment)
|
|
215
|
+
|
|
216
|
+
assert self.name_line_edit is not None
|
|
217
|
+
data["name"] = self.name_line_edit.text()
|
|
218
|
+
return data, boom
|
|
219
|
+
|
|
220
|
+
def load_data(self, data, index):
|
|
221
|
+
"""Load the data into the widgets.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
data: The data to be loaded into the widgets.
|
|
225
|
+
index: The index of the data in the list.
|
|
226
|
+
"""
|
|
227
|
+
assert self.data_entry_widget is not None
|
|
228
|
+
self.data_entry_widget.load_data(data)
|
|
229
|
+
|
|
230
|
+
clear_layout(self.boom_sections_layout)
|
|
231
|
+
|
|
232
|
+
for section in data["sections"]:
|
|
233
|
+
self.boom_sections_layout.addWidget(BoomSectionWidget(
|
|
234
|
+
self.boom_sections_layout.count(), self.delete_boom_section, section))
|
|
235
|
+
|
|
236
|
+
assert self.name_line_edit is not None
|
|
237
|
+
self.name_line_edit.setText(data["name"])
|
|
238
|
+
self.index = index
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/frames/cargo_bays/__init__.py
|
|
2
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
3
|
+
# IMPORT
|
|
4
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
5
|
+
from tabs.geometry.frames.cargo_bays.cargo_bay_frame import CargoBayFrame
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/frames/cargo_bays/cargo_bay_frame.py
|
|
2
|
+
#
|
|
3
|
+
# Created: Dec 2025, M. Clarke
|
|
4
|
+
|
|
5
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
6
|
+
# IMPORT
|
|
7
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
# RCAIDE imports
|
|
9
|
+
import RCAIDE
|
|
10
|
+
|
|
11
|
+
# PyQT imports
|
|
12
|
+
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QPushButton, QLineEdit, QHBoxLayout, \
|
|
13
|
+
QSpacerItem, QSizePolicy, QScrollArea
|
|
14
|
+
|
|
15
|
+
# RCAIDE GUI imports
|
|
16
|
+
from tabs.geometry.frames import GeometryFrame
|
|
17
|
+
from utilities import show_popup, create_line_bar, set_data, Units, create_scroll_area, clear_layout
|
|
18
|
+
from common_widgets import DataEntryWidget
|
|
19
|
+
|
|
20
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
21
|
+
# Cargo Bay Frame
|
|
22
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
23
|
+
class CargoBayFrame(GeometryFrame):
|
|
24
|
+
# List of data labels
|
|
25
|
+
data_units_labels = [
|
|
26
|
+
("Length", Units.Unitless, "length"),
|
|
27
|
+
("Width", Units.Unitless, "width"),
|
|
28
|
+
("Height", Units.Length, "height"),
|
|
29
|
+
# RCAIDE Cargo_Bay stores cargo mass directly; it has no baggage/container subobjects.
|
|
30
|
+
("Cargo Mass", Units.Mass, "mass_properties.mass"),
|
|
31
|
+
("Center of Gravity", Units.Position, "mass_properties.center_of_gravity"),
|
|
32
|
+
("Origin", Units.Position, "origin"),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
"""Create a frame for entering cargo bay data."""
|
|
37
|
+
super(CargoBayFrame, self).__init__()
|
|
38
|
+
self.data_entry_widget: DataEntryWidget | None = None
|
|
39
|
+
|
|
40
|
+
create_scroll_area(self)
|
|
41
|
+
|
|
42
|
+
assert self.main_layout is not None
|
|
43
|
+
self.main_layout.addWidget(QLabel("<b>Cargo Bays</b>"))
|
|
44
|
+
self.main_layout.addWidget(create_line_bar())
|
|
45
|
+
self.index = -1
|
|
46
|
+
|
|
47
|
+
self.add_name_layout()
|
|
48
|
+
|
|
49
|
+
# Add the data entry widget to the main layout
|
|
50
|
+
self.data_entry_widget = DataEntryWidget(self.data_units_labels)
|
|
51
|
+
self.wire_auto_save(self.data_entry_widget)
|
|
52
|
+
self.main_layout.addWidget(self.data_entry_widget)
|
|
53
|
+
self.main_layout.addWidget(create_line_bar())
|
|
54
|
+
|
|
55
|
+
self.add_buttons_layout()
|
|
56
|
+
|
|
57
|
+
# Adds scroll function
|
|
58
|
+
self.main_layout.addItem(QSpacerItem(
|
|
59
|
+
20, 40, QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Expanding))
|
|
60
|
+
|
|
61
|
+
def add_name_layout(self):
|
|
62
|
+
name_layout = QHBoxLayout()
|
|
63
|
+
spacer_left = QSpacerItem(
|
|
64
|
+
50, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
65
|
+
spacer_right = QSpacerItem(
|
|
66
|
+
200, 5, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
|
67
|
+
self.name_line_edit = QLineEdit(self)
|
|
68
|
+
name_layout.addItem(spacer_left)
|
|
69
|
+
name_layout.addWidget(QLabel("Name: "))
|
|
70
|
+
name_layout.addWidget(self.name_line_edit)
|
|
71
|
+
name_layout.addItem(spacer_right)
|
|
72
|
+
|
|
73
|
+
assert self.main_layout is not None
|
|
74
|
+
self.main_layout.addLayout(name_layout)
|
|
75
|
+
|
|
76
|
+
# noinspection PyUnresolvedReferences
|
|
77
|
+
def add_buttons_layout(self):
|
|
78
|
+
"""Add the save, delete, and new buttons to the layout."""
|
|
79
|
+
save_button = QPushButton("Save Data", self)
|
|
80
|
+
save_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
81
|
+
delete_button = QPushButton("Delete Data", self)
|
|
82
|
+
delete_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
83
|
+
new_button = QPushButton("New Cargo Bay", self)
|
|
84
|
+
new_button.setStyleSheet("color:#dbe7ff; font-weight:500; margin:0; padding:0;")
|
|
85
|
+
|
|
86
|
+
save_button.clicked.connect(self.save_data)
|
|
87
|
+
delete_button.clicked.connect(self.delete_data)
|
|
88
|
+
new_button.clicked.connect(self.create_new_structure)
|
|
89
|
+
|
|
90
|
+
buttons_layout = QHBoxLayout()
|
|
91
|
+
buttons_layout.addWidget(save_button)
|
|
92
|
+
buttons_layout.addWidget(delete_button)
|
|
93
|
+
buttons_layout.addWidget(new_button)
|
|
94
|
+
|
|
95
|
+
assert self.main_layout is not None
|
|
96
|
+
self.main_layout.addLayout(buttons_layout)
|
|
97
|
+
|
|
98
|
+
# noinspection DuplicatedCode
|
|
99
|
+
def save_data(self):
|
|
100
|
+
"""Call the save function and pass the entered data to it."""
|
|
101
|
+
entered_data, cargo_bay = self.get_data_values()
|
|
102
|
+
if self.save_function:
|
|
103
|
+
if self.index >= 0:
|
|
104
|
+
self.index = self.save_function(
|
|
105
|
+
tab_index=self.tab_index, index=self.index, data=entered_data, persist=True)
|
|
106
|
+
return
|
|
107
|
+
else:
|
|
108
|
+
self.index = self.save_function(
|
|
109
|
+
tab_index=self.tab_index, vehicle_component=cargo_bay, data=entered_data, new=True, persist=True)
|
|
110
|
+
|
|
111
|
+
show_popup("Data Saved!", self)
|
|
112
|
+
else:
|
|
113
|
+
print("No save function set.")
|
|
114
|
+
|
|
115
|
+
# TODO: Implement proper deletion of data
|
|
116
|
+
def delete_data(self):
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
def create_new_structure(self):
|
|
120
|
+
"""Create a new cargo bay structure."""
|
|
121
|
+
# Clear the main data values
|
|
122
|
+
assert self.data_entry_widget is not None and self.name_line_edit is not None
|
|
123
|
+
self.data_entry_widget.clear_values()
|
|
124
|
+
self.name_line_edit.clear()
|
|
125
|
+
|
|
126
|
+
def create_rcaide_structure(self):
|
|
127
|
+
assert self.data_entry_widget is not None
|
|
128
|
+
data = self.data_entry_widget.get_values_si()
|
|
129
|
+
cargo_bay = RCAIDE.Library.Components.Cargo_Bays.Cargo_Bay()
|
|
130
|
+
for data_unit_label in self.data_units_labels:
|
|
131
|
+
rcaide_label = data_unit_label[-1]
|
|
132
|
+
user_label = data_unit_label[0]
|
|
133
|
+
set_data(cargo_bay, rcaide_label, data[user_label][0])
|
|
134
|
+
|
|
135
|
+
return cargo_bay
|
|
136
|
+
|
|
137
|
+
def get_data_values(self):
|
|
138
|
+
"""Retrieve the entered data values from the text fields."""
|
|
139
|
+
assert self.data_entry_widget is not None
|
|
140
|
+
data = self.data_entry_widget.get_values()
|
|
141
|
+
cargo_bay = self.create_rcaide_structure()
|
|
142
|
+
|
|
143
|
+
assert self.name_line_edit is not None
|
|
144
|
+
data["name"] = self.name_line_edit.text()
|
|
145
|
+
return data, cargo_bay
|
|
146
|
+
|
|
147
|
+
def load_data(self, data, index):
|
|
148
|
+
"""Load the data into the widgets.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
data: The data to be loaded into the widgets.
|
|
152
|
+
index: The index of the data in the list.
|
|
153
|
+
"""
|
|
154
|
+
assert self.data_entry_widget is not None
|
|
155
|
+
self.data_entry_widget.load_data(data)
|
|
156
|
+
|
|
157
|
+
assert self.name_line_edit is not None
|
|
158
|
+
self.name_line_edit.setText(data["name"])
|
|
159
|
+
self.index = index
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# RCAIDE_GUI/tabs/geometry/frames/default_frame.py
|
|
2
|
+
#
|
|
3
|
+
# Created: Dec 2025, M. Clarke
|
|
4
|
+
|
|
5
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
6
|
+
# IMPORT
|
|
7
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
from PyQt6.QtCore import Qt
|
|
9
|
+
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout
|
|
10
|
+
|
|
11
|
+
from tabs.geometry.frames import GeometryFrame
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DefaultFrame(GeometryFrame):
|
|
15
|
+
def __init__(self):
|
|
16
|
+
super(DefaultFrame, self).__init__()
|
|
17
|
+
|
|
18
|
+
# Create a QVBoxLayout for the DefaultFrame
|
|
19
|
+
layout = QVBoxLayout(self)
|
|
20
|
+
|
|
21
|
+
# Add a QLabel with the text to the layout
|
|
22
|
+
label = QLabel("Please select or create a configuration to begin!")
|
|
23
|
+
layout.addWidget(label, alignment=Qt.AlignmentFlag.AlignCenter)
|