[merge] more buttons, concurrent reading of data frame

This commit is contained in:
Jan Grewe 2024-12-22 12:45:18 +01:00
parent 4a5f6eebea
commit b24c4435e7
2 changed files with 120 additions and 16 deletions

View File

@ -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()
@ -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()

View File

@ -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