Initial MVP application skeleton
Add PySide6 camera UI, YOLO/Tesseract detection pipeline, capture metadata, configuration, and project gitignore.
This commit is contained in:
125
app/settings_dialog.py
Normal file
125
app/settings_dialog.py
Normal file
@@ -0,0 +1,125 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import deepcopy
|
||||
from typing import Any
|
||||
|
||||
from PySide6.QtCore import Qt, Signal
|
||||
from PySide6.QtWidgets import (
|
||||
QCheckBox,
|
||||
QDialog,
|
||||
QFormLayout,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QPushButton,
|
||||
QSlider,
|
||||
QSpinBox,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
|
||||
|
||||
CAMERA_PROPERTY_LABELS = {
|
||||
"brightness": "Jasnosc",
|
||||
"contrast": "Kontrast",
|
||||
"saturation": "Nasycenie",
|
||||
"hue": "Barwa",
|
||||
"gain": "Gain",
|
||||
"exposure": "Ekspozycja",
|
||||
"sharpness": "Ostrosc",
|
||||
"auto_exposure": "Auto ekspozycja",
|
||||
"focus": "Focus",
|
||||
"auto_focus": "Auto focus",
|
||||
}
|
||||
|
||||
|
||||
class PropertySlider(QWidget):
|
||||
value_changed = Signal(str, object)
|
||||
|
||||
def __init__(self, name: str, value: float | None) -> None:
|
||||
super().__init__()
|
||||
self.name = name
|
||||
self.enabled_box = QCheckBox()
|
||||
self.enabled_box.setChecked(value is not None)
|
||||
self.slider = QSlider(Qt.Horizontal)
|
||||
self.slider.setRange(-100, 100)
|
||||
self.slider.setValue(int(value) if value is not None else 0)
|
||||
self.value_box = QSpinBox()
|
||||
self.value_box.setRange(-100, 100)
|
||||
self.value_box.setValue(self.slider.value())
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.addWidget(self.enabled_box)
|
||||
layout.addWidget(self.slider, 1)
|
||||
layout.addWidget(self.value_box)
|
||||
|
||||
self.slider.valueChanged.connect(self.value_box.setValue)
|
||||
self.value_box.valueChanged.connect(self.slider.setValue)
|
||||
self.slider.valueChanged.connect(self._emit_value)
|
||||
self.enabled_box.toggled.connect(self._emit_value)
|
||||
|
||||
def _emit_value(self) -> None:
|
||||
self.value_changed.emit(self.name, self.value())
|
||||
|
||||
def value(self) -> float | None:
|
||||
if not self.enabled_box.isChecked():
|
||||
return None
|
||||
return float(self.slider.value())
|
||||
|
||||
|
||||
class SettingsDialog(QDialog):
|
||||
settings_saved = Signal(dict)
|
||||
|
||||
def __init__(self, config: dict[str, Any], parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("Ustawienia obrazu")
|
||||
self.setMinimumWidth(520)
|
||||
self.config = deepcopy(config)
|
||||
self.property_widgets: dict[str, PropertySlider] = {}
|
||||
|
||||
camera_cfg = self.config["camera"]
|
||||
main_layout = QVBoxLayout(self)
|
||||
form = QFormLayout()
|
||||
|
||||
self.width_box = QSpinBox()
|
||||
self.width_box.setRange(160, 7680)
|
||||
self.width_box.setValue(int(camera_cfg.get("width", 1920)))
|
||||
self.height_box = QSpinBox()
|
||||
self.height_box.setRange(120, 4320)
|
||||
self.height_box.setValue(int(camera_cfg.get("height", 1080)))
|
||||
self.fps_box = QSpinBox()
|
||||
self.fps_box.setRange(1, 240)
|
||||
self.fps_box.setValue(int(camera_cfg.get("fps", 30)))
|
||||
|
||||
form.addRow("Szerokosc", self.width_box)
|
||||
form.addRow("Wysokosc", self.height_box)
|
||||
form.addRow("FPS", self.fps_box)
|
||||
|
||||
for name, label in CAMERA_PROPERTY_LABELS.items():
|
||||
widget = PropertySlider(name, camera_cfg.get("properties", {}).get(name))
|
||||
self.property_widgets[name] = widget
|
||||
form.addRow(QLabel(label), widget)
|
||||
|
||||
main_layout.addLayout(form)
|
||||
|
||||
buttons = QHBoxLayout()
|
||||
buttons.addStretch(1)
|
||||
cancel_button = QPushButton("Anuluj")
|
||||
save_button = QPushButton("Zapisz")
|
||||
save_button.setDefault(True)
|
||||
buttons.addWidget(cancel_button)
|
||||
buttons.addWidget(save_button)
|
||||
main_layout.addLayout(buttons)
|
||||
|
||||
cancel_button.clicked.connect(self.reject)
|
||||
save_button.clicked.connect(self._save)
|
||||
|
||||
def _save(self) -> None:
|
||||
self.config["camera"]["width"] = int(self.width_box.value())
|
||||
self.config["camera"]["height"] = int(self.height_box.value())
|
||||
self.config["camera"]["fps"] = int(self.fps_box.value())
|
||||
self.config["camera"]["properties"] = {
|
||||
name: widget.value() for name, widget in self.property_widgets.items()
|
||||
}
|
||||
self.settings_saved.emit(self.config["camera"])
|
||||
self.accept()
|
||||
Reference in New Issue
Block a user