Compare commits

..

No commits in common. "20b2915b6bd2dc26daff4f8002f4472eac5478b8" and "47b198853920e558e7928ed07f45099c5ba66322" have entirely different histories.

6 changed files with 182 additions and 309 deletions

View File

@ -1,9 +1,11 @@
from PySide6.QtCore import QSize, Qt from PySide6.QtCore import QSize, Qt
from PySide6.QtWidgets import QMainWindow, QWidget, QToolBar, QSizePolicy, QFileDialog from PySide6.QtWidgets import QMainWindow, QWidget, QToolBar, QMenu, QMenuBar, QSizePolicy, QFileDialog
from PySide6.QtGui import QKeySequence, QAction, QIcon from PySide6.QtWidgets import QDialog, QVBoxLayout
from PySide6.QtGui import QKeySequence, QAction, QIcon, QPalette
from fixtracks.widgets.centralwidget import CentralWidget from fixtracks.widgets.centralwidget import CentralWidget
from fixtracks.dialogs.previewdialog import PreviewDialog from fixtracks.dialogs.previewdialog import PreviewDialog
from fixtracks.utils.reader import ImageReader, DataFrameReader
from fixtracks.dialogs.about import AboutDialog from fixtracks.dialogs.about import AboutDialog
from fixtracks.dialogs.help import HelpDialog from fixtracks.dialogs.help import HelpDialog
import fixtracks.resources import fixtracks.resources

View File

@ -54,7 +54,6 @@ class TrackingData(QObject):
return self._indices return self._indices
def setSelectionRange(self, col, start, stop): def setSelectionRange(self, col, start, stop):
logging.debug("Trackingdata: set selection range based on column %s to %.2f - %.2f", col, start, stop)
self._start = start self._start = start
self._stop = stop self._stop = stop
self._selection_column = col self._selection_column = col
@ -65,7 +64,7 @@ class TrackingData(QObject):
def setUserSelection(self, ids): def setUserSelection(self, ids):
""" """
Set the user selections. That is, e.g. when the user selected a number of detection ids (aka the index of the original data frame entries). Set the user selections. That is, e.g. when the user selected a number of ids.
Parameters Parameters
---------- ----------
ids : array-like ids : array-like
@ -74,33 +73,16 @@ class TrackingData(QObject):
""" """
self._user_selections = ids.astype(int) self._user_selections = ids.astype(int)
def assignUserSelection(self, track_id:int, userFlag:bool=True)-> None: def assignUserSelection(self, track_id:int)-> None:
"""Assign a new track_id to the user-selected detections """Assign a new track_id to the user-selected detections
Parameters Parameters
---------- ----------
track_id : int track_id : int
The new track id for the user-selected detections The new track id for the user-selected detections
userFlag : bool
Should the "userlabeled" state of the detections be set to True or False?
""" """
self._data["track"][self._user_selections] = track_id self._data["track"][self._user_selections] = track_id
self.setAssignmentStatus(userFlag) self._data["userlabeled"][self._user_selections] = True
def setAssignmentStatus(self, isTrue: bool):
self._data["userlabeled"][self._user_selections] = isTrue
def revertAssignmentStatus(self):
self._data["userlabeled"][:] = False
def deleteDetections(self):
# from IPython import embed
# if self._user_selections is not None:
# ids = self._user_selections
# for c in self.columns:
# pass
# embed()
pass
def assignTracks(self, tracks): def assignTracks(self, tracks):
"""assignTracks _summary_ """assignTracks _summary_
@ -133,7 +115,7 @@ class TrackingData(QObject):
return 0 return 0
return self._data["keypoints"][0].shape[0] return self._data["keypoints"][0].shape[0]
def coordinates(self, selection=False): def coordinates(self):
""" """
Returns the coordinates of all keypoints as a NumPy array. Returns the coordinates of all keypoints as a NumPy array.
@ -141,9 +123,6 @@ class TrackingData(QObject):
np.ndarray: A NumPy array of shape (N, M, 2) where N is the number of detections, np.ndarray: A NumPy array of shape (N, M, 2) where N is the number of detections,
and M is number of keypoints and M is number of keypoints
""" """
if selection:
return np.stack(self._data["keypoints"][self._start:self._stop, :, :]).astype(np.float32)
else:
return np.stack(self._data["keypoints"]).astype(np.float32) return np.stack(self._data["keypoints"]).astype(np.float32)
def keypointScores(self): def keypointScores(self):
@ -223,6 +202,14 @@ class TrackingData(QObject):
def __getitem__(self, key): def __getitem__(self, key):
return self._data[key] return self._data[key]
# def __setitem__(self, key, value):
# self._data[key] = value
"""
self._data.setSelectionRange("index", 0, self._data.numDetections)
self._data.assignTracks(tracks)
self._timeline.setDetectionData(self._data.data)
self.update()
"""
def main(): def main():
import pandas as pd import pandas as pd
@ -230,8 +217,6 @@ def main():
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from fixtracks.info import PACKAGE_ROOT from fixtracks.info import PACKAGE_ROOT
logging.basicConfig(level=logging.DEBUG, force=True)
def as_dict(df:pd.DataFrame): def as_dict(df:pd.DataFrame):
d = {c: df[c].values for c in df.columns} d = {c: df[c].values for c in df.columns}
d["index"] = df.index.values d["index"] = df.index.values
@ -266,7 +251,7 @@ def main():
plt.plot([positions[si, 0], positions[ei, 0]], plt.plot([positions[si, 0], positions[ei, 0]],
[positions[si, 1], positions[ei, 1]], color="tab:green") [positions[si, 1], positions[ei, 1]], color="tab:green")
datafile = PACKAGE_ROOT / "data/merged_small.pkl" datafile = PACKAGE_ROOT / "data/merged2.pkl"
with open(datafile, "rb") as f: with open(datafile, "rb") as f:
df = pickle.load(f) df = pickle.load(f)

View File

@ -239,7 +239,7 @@ class SizeClassifier(QWidget):
def setCoordinates(self, coordinates): def setCoordinates(self, coordinates):
self._coordinates = coordinates self._coordinates = coordinates
self._sizes = self.estimate_length(coordinates, bodyaxis=[0, 1, 2, 5]) self._sizes = self.estimate_length(coordinates)
n, e = self.estimate_histogram(self._sizes) n, e = self.estimate_histogram(self._sizes)
plot = self._plot_widget.addPlot() plot = self._plot_widget.addPlot()
bgi = pg.BarGraphItem(x0=e[:-1], x1=e[1:], height=n, pen='w', brush=(0,0,255,150)) bgi = pg.BarGraphItem(x0=e[:-1], x1=e[1:], height=n, pen='w', brush=(0,0,255,150))
@ -600,7 +600,6 @@ def main():
df = pickle.load(f) df = pickle.load(f)
data = TrackingData() data = TrackingData()
data.setData(as_dict(df)) data.setData(as_dict(df))
coords = data.coordinates()
app = QApplication([]) app = QApplication([])
window = QWidget() window = QWidget()
@ -611,7 +610,6 @@ def main():
# else: # else:
w = ClassifierWidget() w = ClassifierWidget()
w.setData(data) w.setData(data)
w.size_classifier.setCoordinates(coords)
layout = QVBoxLayout() layout = QVBoxLayout()
layout.addWidget(w) layout.addWidget(w)

View File

@ -1,248 +0,0 @@
import logging
import numpy as np
from PySide6.QtCore import Qt, Signal, QSize
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QWidget, QLabel, QPushButton, QSizePolicy
from PySide6.QtWidgets import QGridLayout, QVBoxLayout
class SelectionControls(QWidget):
fwd = Signal(float)
back = Signal(float)
assignOne = Signal()
assignTwo = Signal()
assignOther = Signal()
accept = Signal()
unaccept = Signal()
delete = Signal()
revertall = Signal()
def __init__(self, parent = None,):
super().__init__(parent)
font = QFont()
font.setBold(True)
font.setPointSize(10)
fullstep = 1.0
halfstep = 0.5
quarterstep = 0.25
backBtn = QPushButton("|<<")
backBtn.setFont(font)
backBtn.setShortcut(Qt.Key.Key_Left)
backBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
backBtn.setToolTip(f"Go back to previous window ({backBtn.shortcut().toString()})")
backBtn.clicked.connect(lambda: self.on_Back(fullstep))
halfstepBackBtn = QPushButton("<<")
halfstepBackBtn.setFont(font)
halfstepBackBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
halfstepBackBtn.setShortcut(Qt.KeyboardModifier.AltModifier | Qt.Key.Key_Left)
halfstepBackBtn.setToolTip(f"Go back by half a window ({halfstepBackBtn.shortcut().toString()})")
halfstepBackBtn.clicked.connect(lambda: self.on_Back(halfstep))
quarterstepBackBtn = QPushButton("<")
quarterstepBackBtn.setFont(font)
quarterstepBackBtn.setShortcut(Qt.KeyboardModifier.ShiftModifier | Qt.Key.Key_Left)
quarterstepBackBtn.setToolTip(f"Go back by a quarter window ({quarterstepBackBtn.shortcut().toString()})")
quarterstepBackBtn.clicked.connect(lambda: self.on_Back(quarterstep))
quarterstepBackBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
fwdBtn = QPushButton(">>|")
fwdBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
fwdBtn.setShortcut(Qt.Key.Key_Right)
fwdBtn.setFont(font)
fwdBtn.setToolTip(f"Proceed to next window ({fwdBtn.shortcut().toString()})")
fwdBtn.clicked.connect(lambda: self.on_Fwd(fullstep))
halfstepFwdBtn = QPushButton(">>")
halfstepFwdBtn.setFont(font)
halfstepFwdBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
halfstepFwdBtn.setShortcut(Qt.KeyboardModifier.AltModifier | Qt.Key.Key_Right)
halfstepFwdBtn.setToolTip(f"Proceed by half a window ({halfstepFwdBtn.shortcut().toString()})")
halfstepFwdBtn.clicked.connect(lambda: self.on_Fwd(halfstep))
quarterstepFwdBtn = QPushButton(">")
quarterstepFwdBtn.setFont(font)
quarterstepFwdBtn.setShortcut(Qt.KeyboardModifier.ShiftModifier | Qt.Key.Key_Right)
quarterstepFwdBtn.setToolTip(f"Proceed by a quarter window ({quarterstepFwdBtn.shortcut().toString()})")
quarterstepFwdBtn.clicked.connect(lambda: self.on_Fwd(quarterstep))
quarterstepFwdBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
assignOneBtn = QPushButton("Track One")
assignOneBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
assignOneBtn.setStyleSheet("QPushButton { background-color: orange; }")
assignOneBtn.setShortcut("Ctrl+1")
assignOneBtn.setToolTip(f"Assign current selection to Track One ({assignOneBtn.shortcut().toString()})")
assignOneBtn.setFont(font)
assignOneBtn.clicked.connect(self.on_TrackOne)
assignTwoBtn = QPushButton("Track Two")
assignTwoBtn.setShortcut("Ctrl+2")
assignTwoBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
assignTwoBtn.setStyleSheet("QPushButton { background-color: green; }")
assignTwoBtn.setToolTip(f"Assign current selection to Track Two ({assignTwoBtn.shortcut().toString()})")
assignTwoBtn.setFont(font)
assignTwoBtn.clicked.connect(self.on_TrackTwo)
assignOtherBtn = QPushButton("Other")
assignOtherBtn.setShortcut("Ctrl+0")
assignOtherBtn.setFont(font)
assignOtherBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
# assignOtherBtn.setStyleSheet("QPushButton { background-color: gray; }")
assignOtherBtn.setToolTip(f"Assign current selection to Unassigned ({assignOtherBtn.shortcut().toString()})")
assignOtherBtn.clicked.connect(self.on_TrackOther)
acceptBtn = QPushButton("accept")
acceptBtn.setFont(font)
acceptBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
# acceptBtn.setStyleSheet("QPushButton { background-color: red; }")
acceptBtn.setToolTip(f"Accept assignments of current selection as TRUE")
acceptBtn.clicked.connect(self.on_Accept)
unacceptBtn = QPushButton("un-accept")
unacceptBtn.setFont(font)
unacceptBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
# acceptBtn.setStyleSheet("QPushButton { background-color: red; }")
unacceptBtn.setToolTip(f"Revoke current selection TRUE status")
unacceptBtn.clicked.connect(self.on_Unaccept)
deleteBtn = QPushButton("delete")
deleteBtn.setFont(font)
deleteBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
deleteBtn.setStyleSheet("QPushButton { background-color: red; }")
deleteBtn.setToolTip(f"DANGERZONE! Delete current selection of detections!")
deleteBtn.clicked.connect(self.on_Delete)
revertBtn = QPushButton("revert assignments")
revertBtn.setFont(font)
revertBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
revertBtn.setStyleSheet("QPushButton { background-color: red; }")
revertBtn.setToolTip(f"DANGERZONE! Remove ALL assignments!")
revertBtn.clicked.connect(self.on_RevertAll)
self.tone_selection = QLabel("0")
self.ttwo_selection = QLabel("0")
self.tother_selection = QLabel("0")
self.startframe = QLabel("0")
self.endframe = QLabel("0")
self._total = 0
grid = QGridLayout()
grid.addWidget(backBtn, 0, 0, 3, 2)
grid.addWidget(fwdBtn, 0, 6, 3, 2)
grid.addWidget(halfstepBackBtn, 3, 0, 2, 2)
grid.addWidget(halfstepFwdBtn, 3, 6, 2, 2)
grid.addWidget(quarterstepBackBtn, 5, 0, 2, 2)
grid.addWidget(quarterstepFwdBtn, 5, 6, 2, 2)
cwLabel = QLabel("Current window:")
cwLabel.setFont(font)
grid.addWidget(cwLabel, 0, 2, 1, 4)
grid.addWidget(QLabel("start:"), 1, 2, 1, 2)
grid.addWidget(self.startframe, 1, 4, 1, 2, Qt.AlignmentFlag.AlignRight)
grid.addWidget(QLabel("end:"), 2, 2, 1, 2)
grid.addWidget(self.endframe, 2, 4, 1, 2, Qt.AlignmentFlag.AlignRight)
csLabel = QLabel("Current selection:")
csLabel.setFont(font)
grid.addWidget(csLabel, 3, 2, 1, 4)
grid.addWidget(QLabel("track One:"), 4, 2, 1, 2)
grid.addWidget(self.tone_selection, 4, 4, 1, 2, Qt.AlignmentFlag.AlignRight)
grid.addWidget(QLabel("track Two:"), 5, 2, 1, 2)
grid.addWidget(self.ttwo_selection, 5, 4, 1, 2, Qt.AlignmentFlag.AlignRight)
grid.addWidget(QLabel("Unassigned:"), 6, 2, 1, 2)
grid.addWidget(self.tother_selection, 6, 4, 1, 2, Qt.AlignmentFlag.AlignRight)
grid.addWidget(assignOneBtn, 7, 0, 1, 3)
grid.addWidget(assignOtherBtn, 7, 3, 1, 2)
grid.addWidget(assignTwoBtn, 7, 5, 1, 3)
grid.addWidget(acceptBtn, 8, 0, 1, 4)
grid.addWidget(unacceptBtn, 8, 4, 1, 4)
grid.addWidget(deleteBtn, 9, 0, 1, 4)
grid.addWidget(revertBtn, 9, 4, 1, 4)
grid.setColumnStretch(0, 1)
grid.setColumnStretch(7, 1)
self.setLayout(grid)
self.setMaximumSize(QSize(400, 300))
def setWindow(self, start:int=0, end:int=0):
self.startframe.setText(f"{start:.0f}")
self.endframe.setText(f"{end:g}")
def _updateNumbers(self, track):
labels = {1: self.tone_selection, 2: self.ttwo_selection, 3: self.tother_selection}
for k in labels:
if k == track:
labels[k].setText(str(self._total))
else:
labels[k].setText("0")
def on_Fwd(self, stepsize):
logging.debug("SelectionControls: forward step by %.2f", stepsize)
self.fwd.emit(stepsize)
def on_Back(self, stepsize):
logging.debug("SelectionControls: backward step by %.2f", stepsize)
self.back.emit(stepsize)
def on_TrackOne(self):
logging.debug("SelectionControl: TrackONEBtn")
self.assignOne.emit()
self._updateNumbers(1)
def on_TrackTwo(self):
logging.debug("SelectionControl: TrackTWOBtn")
self.assignTwo.emit()
self._updateNumbers(2)
def on_TrackOther(self):
logging.debug("SelectionControl: TrackOtherBtn")
self.assignOther.emit()
self._updateNumbers(3)
def on_Accept(self):
logging.debug("SelectionControl: accept AssignmentBtn")
self.accept.emit()
def on_Unaccept(self):
logging.debug("SelectionControl: revoke user assignmentBtn")
self.unaccept.emit()
def on_RevertAll(self):
logging.debug("SelectionControl: revert Btn")
self.revertall.emit()
def on_Delete(self):
logging.debug("SelectionControl: delete Btn")
self.delete.emit()
def setSelectedTracks(self, tracks):
logging.debug("SelectionControl: setSelectedTracks")
if tracks is not None:
tone = np.sum(tracks == 1)
ttwo = np.sum(tracks == 2)
else:
tone = 0
ttwo = 0
self.tone_selection.setText(str(tone))
self.ttwo_selection.setText(str(ttwo))
self.tother_selection.setText(str(len(tracks) - tone - ttwo if tracks is not None else 0))
self._total = len(tracks) if tracks is not None else 0
def main():
from PySide6.QtWidgets import QApplication
logging.basicConfig(level=logging.DEBUG, force=True)
app = QApplication([])
window = QWidget()
window.setMinimumSize(200, 200)
layout = QVBoxLayout()
controls = SelectionControls()
layout.addWidget(controls)
window.setLayout(layout)
window.show()
app.exec()
if __name__ == "__main__":
main()

View File

@ -14,7 +14,166 @@ from fixtracks.widgets.detectionview import DetectionView, DetectionData
from fixtracks.widgets.detectiontimeline import DetectionTimeline from fixtracks.widgets.detectiontimeline import DetectionTimeline
from fixtracks.widgets.skeleton import SkeletonWidget from fixtracks.widgets.skeleton import SkeletonWidget
from fixtracks.widgets.classifier import ClassifierWidget from fixtracks.widgets.classifier import ClassifierWidget
from fixtracks.widgets.selection_control import SelectionControls
class SelectionControls(QWidget):
fwd = Signal(float)
back = Signal(float)
assignOne = Signal()
assignTwo = Signal()
assignOther = Signal()
def __init__(self, parent = None,):
super().__init__(parent)
font = QFont()
font.setBold(True)
font.setPointSize(10)
fullstep = 1.0
halfstep = 0.5
quarterstep = 0.25
backBtn = QPushButton("|<<")
backBtn.setFont(font)
backBtn.setShortcut(Qt.Key.Key_Left)
backBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
backBtn.setToolTip(f"Go back to previous window ({backBtn.shortcut().toString()})")
backBtn.clicked.connect(lambda: self.on_Back(fullstep))
halfstepBackBtn = QPushButton("<<")
halfstepBackBtn.setFont(font)
halfstepBackBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
halfstepBackBtn.setShortcut(Qt.KeyboardModifier.AltModifier | Qt.Key.Key_Left)
halfstepBackBtn.setToolTip(f"Go back by half a window ({halfstepBackBtn.shortcut().toString()})")
halfstepBackBtn.clicked.connect(lambda: self.on_Back(halfstep))
quarterstepBackBtn = QPushButton("<")
quarterstepBackBtn.setFont(font)
quarterstepBackBtn.setShortcut(Qt.KeyboardModifier.ShiftModifier | Qt.Key.Key_Left)
quarterstepBackBtn.setToolTip(f"Go back by a quarter window ({quarterstepBackBtn.shortcut().toString()})")
quarterstepBackBtn.clicked.connect(lambda: self.on_Back(quarterstep))
fwdBtn = QPushButton(">>|")
fwdBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
fwdBtn.setShortcut(Qt.Key.Key_Right)
fwdBtn.setFont(font)
fwdBtn.setToolTip(f"Proceed to next window ({fwdBtn.shortcut().toString()})")
fwdBtn.clicked.connect(lambda: self.on_Fwd(fullstep))
halfstepFwdBtn = QPushButton(">>")
halfstepFwdBtn.setFont(font)
halfstepFwdBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
halfstepFwdBtn.setShortcut(Qt.KeyboardModifier.AltModifier | Qt.Key.Key_Right)
halfstepFwdBtn.setToolTip(f"Proceed by half a window ({halfstepFwdBtn.shortcut().toString()})")
halfstepFwdBtn.clicked.connect(lambda: self.on_Fwd(halfstep))
quarterstepFwdBtn = QPushButton(">")
quarterstepFwdBtn.setFont(font)
quarterstepFwdBtn.setShortcut(Qt.KeyboardModifier.ShiftModifier | Qt.Key.Key_Right)
quarterstepFwdBtn.setToolTip(f"Proceed by a quarter window ({quarterstepFwdBtn.shortcut().toString()})")
quarterstepFwdBtn.clicked.connect(lambda: self.on_Fwd(quarterstep))
assignOneBtn = QPushButton("Track One")
assignOneBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
assignOneBtn.setStyleSheet("QPushButton { background-color: orange; }")
assignOneBtn.setShortcut("Ctrl+1")
assignOneBtn.setToolTip(f"Assign current selection to Track One ({assignOneBtn.shortcut().toString()})")
assignOneBtn.setFont(font)
assignOneBtn.clicked.connect(self.on_TrackOne)
assignTwoBtn = QPushButton("Track Two")
assignTwoBtn.setShortcut("Ctrl+2")
assignTwoBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
assignTwoBtn.setStyleSheet("QPushButton { background-color: green; }")
assignTwoBtn.setToolTip(f"Assign current selection to Track Two ({assignTwoBtn.shortcut().toString()})")
assignTwoBtn.setFont(font)
assignTwoBtn.clicked.connect(self.on_TrackTwo)
assignOtherBtn = QPushButton("Other")
assignOtherBtn.setShortcut("Ctrl+0")
assignOtherBtn.setFont(font)
assignOtherBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
assignOtherBtn.setStyleSheet("QPushButton { background-color: red; }")
assignOtherBtn.setToolTip(f"Assign current selection to Unassigned ({assignOtherBtn.shortcut().toString()})")
assignOtherBtn.clicked.connect(self.on_TrackOther)
self.tone_selection = QLabel("0")
self.ttwo_selection = QLabel("0")
self.tother_selection = QLabel("0")
self.startframe = QLabel("0")
self.endframe = QLabel("0")
self._total = 0
grid = QGridLayout()
grid.addWidget(backBtn, 0, 0, 3, 2)
grid.addWidget(halfstepBackBtn, 3, 0, 2, 2)
grid.addWidget(quarterstepBackBtn, 5, 0, 2, 2)
grid.addWidget(fwdBtn, 0, 6, 3, 2)
grid.addWidget(halfstepFwdBtn, 3, 6, 2, 2)
grid.addWidget(quarterstepFwdBtn, 5, 6, 2, 2)
grid.addWidget(QLabel("Current window:"), 0, 2, 1, 4)
grid.addWidget(QLabel("start:"), 1, 3, 1, 1)
grid.addWidget(self.startframe, 1, 4, 1, 2, Qt.AlignmentFlag.AlignRight)
grid.addWidget(QLabel("end:"), 2, 3, 1, 1)
grid.addWidget(self.endframe, 2, 4, 1, 2, Qt.AlignmentFlag.AlignRight)
grid.addWidget(QLabel("Current selection:"), 3, 2, 1, 4)
grid.addWidget(QLabel("Track One:"), 4, 3, 1, 2)
grid.addWidget(self.tone_selection, 4, 5, 1, 1, Qt.AlignmentFlag.AlignRight)
grid.addWidget(QLabel("Track Two:"), 5, 3, 1, 2)
grid.addWidget(self.ttwo_selection, 5, 5, 1, 1, Qt.AlignmentFlag.AlignRight)
grid.addWidget(QLabel("Unassigned:"), 6, 3, 1, 2)
grid.addWidget(self.tother_selection, 6, 5, 1, 1, Qt.AlignmentFlag.AlignRight)
grid.addWidget(assignOneBtn, 7, 0, 4, 3)
grid.addWidget(assignOtherBtn, 7, 3, 4, 2)
grid.addWidget(assignTwoBtn, 7, 5, 4, 3)
grid.setColumnStretch(0, 1)
grid.setColumnStretch(7, 1)
self.setLayout(grid)
self.setMaximumSize(QSize(400, 200))
def setWindow(self, start:int=0, end:int=0):
self.startframe.setText(f"{start:.0f}")
self.endframe.setText(f"{end:g}")
def _updateNumbers(self, track):
labels = {1: self.tone_selection, 2: self.ttwo_selection, 3: self.tother_selection}
for k in labels:
if k == track:
labels[k].setText(str(self._total))
else:
labels[k].setText("0")
def on_Fwd(self, stepsize):
logging.debug("SelectionControls: forward step by %.2f", stepsize)
self.fwd.emit(stepsize)
def on_Back(self, stepsize):
logging.debug("SelectionControls: backward step by %.2f", stepsize)
self.back.emit(stepsize)
def on_TrackOne(self):
self.assignOne.emit()
self._updateNumbers(1)
def on_TrackTwo(self):
self.assignTwo.emit()
self._updateNumbers(2)
def on_TrackOther(self):
self.assignOther.emit()
self._updateNumbers(3)
def setSelectedTracks(self, tracks):
logging.debug("SelectionControl: setSelectedTracks")
if tracks is not None:
tone = np.sum(tracks == 1)
ttwo = np.sum(tracks == 2)
else:
tone = 0
ttwo = 0
self.tone_selection.setText(str(tone))
self.ttwo_selection.setText(str(ttwo))
self.tother_selection.setText(str(len(tracks) - tone - ttwo if tracks is not None else 0))
self._total = len(tracks) if tracks is not None else 0
class FixTracks(QWidget): class FixTracks(QWidget):
back = Signal() back = Signal()
@ -80,10 +239,6 @@ class FixTracks(QWidget):
self._controls_widget.assignOther.connect(self.on_assignOther) self._controls_widget.assignOther.connect(self.on_assignOther)
self._controls_widget.fwd.connect(self.on_forward) self._controls_widget.fwd.connect(self.on_forward)
self._controls_widget.back.connect(self.on_backward) self._controls_widget.back.connect(self.on_backward)
self._controls_widget.accept.connect(self.on_setUserFlag)
self._controls_widget.unaccept.connect(self.on_unsetUserFlag)
self._controls_widget.delete.connect(self.on_deleteDetection)
self._controls_widget.revertall.connect(self.on_revertUserFlags)
self._saveBtn = QPushButton("Save") self._saveBtn = QPushButton("Save")
self._saveBtn.setShortcut("Ctrl+S") self._saveBtn.setShortcut("Ctrl+S")
@ -291,31 +446,12 @@ class FixTracks(QWidget):
def on_assignOther(self): def on_assignOther(self):
logging.debug("Assigning user selection to track Other") logging.debug("Assigning user selection to track Other")
self._data.assignUserSelection(self.trackother_id, False) self._data.assignUserSelection(self.trackother_id)
self._timeline.setDetectionData(self._data.data) self._timeline.setDetectionData(self._data.data)
self.update() self.update()
def on_setUserFlag(self):
self._data.setAssignmentStatus(True)
self.update()
def on_unsetUserFlag(self):
logging.debug("Tracks:unsetUserFlag")
self._data.setAssignmentStatus(False)
self.update()
def on_revertUserFlags(self):
logging.debug("Tracks:revert ALL UserFlags")
self._data.revertAssignmentStatus()
self.update()
def on_deleteDetection(self):
logging.debug("Tracks:delete detections")
# self._data.deleteDetections()
self.update()
def on_windowChanged(self): def on_windowChanged(self):
logging.debug("Tracks:Timeline reports window change ") logging.info("Timeline reports window change ")
self._currentWindowPos = np.round(self._timeline.rangeStart * self._maxframes) self._currentWindowPos = np.round(self._timeline.rangeStart * self._maxframes)
self.update() self.update()

View File

@ -11,7 +11,7 @@ from PySide6.QtGui import QIcon, QPalette
from fixtracks import fixtracks, info from fixtracks import fixtracks, info
logging.basicConfig(level=logging.INFO, force=True) logging.basicConfig(level=logging.DEBUG, force=True)
def is_dark_mode(app: QApplication) -> bool: def is_dark_mode(app: QApplication) -> bool: