Pattern, as a pane beside the 3-D view.
Pattern copies the solids picked in the tree in rows, columns and
layers, so a part with many identical holes or inserts does not need
each one added by hand. The pane takes how many along the geometry's
X, Y and Z (the originals included) and how far apart, and the copies
are drawn in the view as the numbers are typed. Pattern then runs the
project's pattern_solids, which makes one solid from the originals,
so changing an original changes every copy. One hole repeated 13 times
along X makes a row; that pattern picked and repeated twice along Y
makes two rows. A pattern's pencil in the tree opens the pane on it
again to change its counts and spacing.
The pane holds no rules of its own: the window draws the copies and
says what they are.
Classes:
| Name |
Description |
PatternPanel |
How many along each axis, how far apart, and the Pattern button.
|
Classes
PatternPanel
PatternPanel(parent: QWidget | None = None)
Bases: QWidget
How many along each axis, how far apart, and the Pattern button.
Methods:
| Name |
Description |
open_for |
Set the pane up with every count one and every spacing zero,
|
set_values |
Fill the fields by name, counts=(x, y, z) and
|
Source code in src/visualdynamics/gui/pattern_panel.py
| def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
self.title: QLabel = QLabel('Pattern')
grid = panel_grid(self, self.title)
self.parts_label: QLabel = QLabel()
self.parts_label.setWordWrap(True)
self.parts_label.setEnabled(False)
grid.addWidget(self.parts_label, 1, 0, 1, 3)
self.count_label: QLabel = QLabel('How many')
self.spacing_label: QLabel = QLabel('Spacing')
for label in (self.count_label, self.spacing_label):
label.setEnabled(False)
grid.addWidget(self.count_label, 2, 1)
grid.addWidget(self.spacing_label, 2, 2)
self.counts: list[SpinBox] = []
self.spacings: list[DoubleSpinBox] = []
for row, axis in enumerate('XYZ', start=3):
count = SpinBox()
count.setRange(1, 10_000)
count.setToolTip(f'How many along {axis}, the original included')
spacing = DoubleSpinBox()
spacing.setDecimals(LENGTH_DECIMALS)
spacing.setRange(-1e9, 1e9)
spacing.setToolTip(f'How far apart along {axis}; negative goes '
'the other way')
grid.addWidget(QLabel(axis), row, 0)
grid.addWidget(count, row, 1)
grid.addWidget(spacing, row, 2)
self.counts.append(count)
self.spacings.append(spacing)
self.reading_label: QLabel = QLabel()
self.reading_label.setWordWrap(True)
grid.addWidget(self.reading_label, 6, 0, 1, 3)
buttons = QHBoxLayout()
self.pattern_button: QPushButton = QPushButton('Pattern')
self.pattern_button.setToolTip('Make the copies the preview shows, '
'as one solid')
self.pattern_button.setDefault(True)
self.close_button: QPushButton = QPushButton('Close')
self.close_button.setToolTip('Put the pane away without making the '
'pattern')
buttons.addWidget(self.pattern_button)
buttons.addWidget(self.close_button)
grid.addLayout(buttons, 7, 0, 1, 3)
grid.setRowStretch(8, 1)
commit_on_enter(*self.counts, *self.spacings)
for box in (*self.counts, *self.spacings):
box.valueChanged.connect(lambda _value: self.changed.emit())
self.pattern_button.clicked.connect(self.pattern_asked.emit)
self.close_button.clicked.connect(self.close_asked.emit)
|
Methods:
open_for
open_for(unit: str, parts: str, editing: bool = False) -> None
Set the pane up with every count one and every spacing zero,
the spacing in the display unit unit and parts naming the
solids. editing opens it on a pattern already made, from its
row's pencil: the title reads Edit Pattern and the button
Apply.
Source code in src/visualdynamics/gui/pattern_panel.py
| def open_for(self, unit: str, parts: str, editing: bool = False) -> None:
"""Set the pane up with every count one and every spacing zero,
the spacing in the display unit `unit` and `parts` naming the
solids. `editing` opens it on a pattern already made, from its
row's pencil: the title reads Edit Pattern and the button
Apply."""
self.title.setText('Edit Pattern' if editing else 'Pattern')
self.pattern_button.setText('Apply' if editing else 'Pattern')
self.spacing_label.setText(f'Spacing [{unit}]')
self.set_values(counts=(1, 1, 1), spacing=(0.0, 0.0, 0.0), quiet=True)
self.parts_label.setText(f'Solids: {parts}')
|
set_values
set_values(quiet: bool = False, **values) -> None
Fill the fields by name, counts=(x, y, z) and
spacing=(x, y, z), as a test would type them. With quiet,
changed is not emitted.
Source code in src/visualdynamics/gui/pattern_panel.py
| def set_values(self, quiet: bool = False, **values) -> None:
"""Fill the fields by name, counts=(x, y, z) and
spacing=(x, y, z), as a test would type them. With `quiet`,
`changed` is not emitted."""
boxes = [*self.counts, *self.spacings]
for box in boxes:
box.blockSignals(True)
for key, numbers in values.items():
for box, number in zip(self.counts if key == 'counts'
else self.spacings, numbers):
box.setValue(number)
for box in boxes:
box.blockSignals(False)
if not quiet:
self.changed.emit()
|
Functions: