diff --git a/fixtracks/detectionmerge.py b/fixtracks/detectionmerge.py index 697f5c3..326b7b2 100644 --- a/fixtracks/detectionmerge.py +++ b/fixtracks/detectionmerge.py @@ -1,10 +1,10 @@ import logging -from PyQt6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QLabel, QPushButton, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene, QGraphicsLineItem -from PyQt6.QtCore import QThreadPool, QLineF, QPointF, QRectF, Qt +from PyQt6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene, QGraphicsLineItem, QSpacerItem +from PyQt6.QtCore import QThreadPool, Qt, pyqtSignal from PyQt6.QtGui import QImage, QPixmap, QColor, QPen -from fixtracks.util import ImageReader +from fixtracks.util import ImageReader, DataFrameReader class VideoPreview(QWidget): @@ -47,15 +47,18 @@ class VideoPreview(QWidget): class MergeDetections(QWidget): + back = pyqtSignal() + def __init__(self, parent=None): super().__init__(parent) self._files = [] self.threadpool = QThreadPool() self.right_imagereader = None self.left_imagereader = None - - layout = QVBoxLayout() - layout.addWidget(QLabel("Merge Detections!")) + self.right_dataframereader = None + self.left_dataframereader = None + self._left_data = None + self._right_data = None self.left_datacombo = QComboBox() self.left_videocombo = QComboBox() @@ -64,7 +67,7 @@ class MergeDetections(QWidget): self.left_posspinner = QSpinBox() self.left_posspinner.valueChanged.connect(self.on_leftmergelinemove) self.left_preview = VideoPreview() - + self.right_datacombo = QComboBox() self.right_videocombo = QComboBox() self.right_datacombo.addItems(self._files) @@ -73,14 +76,34 @@ class MergeDetections(QWidget): self.right_posspinner.valueChanged.connect(self.on_rightmergelinemove) self.right_preview = VideoPreview(left=False) - layout.addLayout(self.layout_controls()) - splitter = QGridLayout() - splitter.addWidget(self.left_preview, 0, 0) - splitter.addWidget(self.right_preview, 0, 1) - splitter.setColumnStretch(0, 1) - splitter.setColumnStretch(1, 1) - layout.addLayout(splitter) + self._mergePreviewBtn = QPushButton("Preview") + self._mergePreviewBtn.clicked.connect(self.on_mergePreview) + self._mergePreviewBtn.setEnabled(False) + self._mergeBtn = QPushButton("Merge!") + self._mergeBtn.setEnabled(False) + self._mergeBtn.setToolTip("Apply cutting and merge the data files into one") + self._mergeBtn.clicked.connect(self.on_merge) + self._backBtn = QPushButton("Back") + self._backBtn.clicked.connect(self.on_back) + + grid = QGridLayout() + grid.addWidget(self.left_preview, 0, 0) + grid.addWidget(self.right_preview, 0, 1) + grid.setColumnStretch(0, 1) + grid.setColumnStretch(1, 1) + + btnBox = QHBoxLayout() + btnBox.setAlignment(Qt.AlignmentFlag.AlignLeft) + btnBox.addWidget(self._backBtn) + btnBox.addItem(QSpacerItem(100, 10, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)) + btnBox.addWidget(self._mergePreviewBtn) + btnBox.addWidget(self._mergeBtn) + layout = QVBoxLayout() + layout.addWidget(QLabel("Merge Detections!")) + layout.addLayout(self.layout_controls()) + layout.addLayout(grid) + layout.addLayout(btnBox) self.setLayout(layout) def layout_controls(self): @@ -136,8 +159,11 @@ class MergeDetections(QWidget): self.left_datacombo.addItems(self.fileList) self.left_datacombo.setCurrentIndex(0) self.right_datacombo.setCurrentIndex(0) + + self.left_datacombo.currentIndexChanged.connect(self.on_leftDataSelection) + self.right_datacombo.currentIndexChanged.connect(self.on_rightDataSelection) self.right_videocombo.currentIndexChanged.connect(self.on_rightvideoSelection) - self.left_videocombo.currentIndexChanged.connect(self.on_leftvideoSelection) + self.left_videocombo.currentIndexChanged.connect(self.on_leftVideoSelection) def _toImage(self, frame): height, width, _ = frame.shape @@ -158,8 +184,9 @@ class MergeDetections(QWidget): self.right_preview.set_image(img) self.right_posspinner.setMaximum(img.width() - 1) self.right_posspinner.setValue(0) + self.checkButtons() - def on_leftvideoSelection(self): + def on_leftVideoSelection(self): logging.debug("Video selection of the %s side", "left") self.left_imagereader = ImageReader(self.left_videocombo.currentText(), 100) self.left_imagereader.signals.finished.connect(self.left_imgreaderDone) @@ -172,9 +199,58 @@ class MergeDetections(QWidget): self.left_preview.set_image(img) self.left_posspinner.setMaximum(img.width() - 1) self.left_posspinner.setValue(img.width() - 1) + self.checkButtons() + + def on_leftDataSelection(self): + logging.debug("Data selection of the %s side", "left") + self.left_dataframereader = DataFrameReader(self.left_datacombo.currentText()) + self.left_dataframereader.signals.finished.connect(self.left_dfreaderDone) + self.threadpool.start(self.left_dataframereader) + + def left_dfreaderDone(self, state): + logging.debug("Left data reader done with state %s", str(state)) + if state: + self._left_data = self.left_dataframereader.dataframe + else: + self._left_data = None + self.checkButtons() + + def on_rightDataSelection(self): + logging.debug("Data selection of the %s side", "right") + self.right_dataframereader = DataFrameReader(self.right_datacombo.currentText()) + self.right_dataframereader.signals.finished.connect(self.right_dfreaderDone) + self.threadpool.start(self.right_dataframereader) + + def right_dfreaderDone(self, state): + logging.debug("Right data reader done with state %s", str(state)) + if state: + self._right_data = self.right_dataframereader.dataframe + else: + self._right_data = None + self.checkButtons() def on_leftmergelinemove(self): self.left_preview.set_lineposition(self.left_posspinner.value()) def on_rightmergelinemove(self): self.right_preview.set_lineposition(self.right_posspinner.value()) + + def on_mergePreview(self): + logging.debug("detectionmerge: mergePreview pressed") + print("Sorry, not implemented yet!") + + def on_merge(self): + logging.debug("detectionmerge: merge pressed") + + pass + + def checkButtons(self): + merge_enabled = self._left_data is not None and self._right_data is not None + logging.debug("CheckButtons: %s", str(merge_enabled)) + self._mergeBtn.setEnabled(merge_enabled) + preview_enabled = self.left_videocombo.currentIndex() > 0 and self.right_videocombo.currentIndex() > 0 + self._mergePreviewBtn.setEnabled(preview_enabled) + + def on_back(self): + logging.debug("Back button pressed!") + self.back.emit() \ No newline at end of file diff --git a/fixtracks/util.py b/fixtracks/util.py index a52f7ff..ab39d16 100644 --- a/fixtracks/util.py +++ b/fixtracks/util.py @@ -49,3 +49,31 @@ class ImageReader(QRunnable): @property def frame(self): return self._frame + + +class DataFrameReader(QRunnable): + finished = pyqtSignal(bool) + + def __init__(self, filename) -> None: + super().__init__() + self._filename = filename + self._signals = ProducerSignals() + self._dataframe = None + + @pyqtSlot() + def run(self): + ''' + Your code goes in this function + ''' + logging.debug("DataFrameReader: trying to open file %s", self._filename) + self._dataframe = pd.read_csv(self._filename, sep=";", index_col=0) + self._signals.finished.emit(True) + + @property + def signals(self): + return self._signals + + @property + def dataframe(self): + return self._dataframe +