Example #1
0
    def init_reference_clock_setup_widget(self):
        """Initialize the reference clock selection stuff.

        This method initializes the reference clock selection radio buttons, and triggers the
        initialization of the manual reference clock setup stage.

        There are two choices at this level: synchronize and manual setup.
        """
        # Reference clock selection (synchronize vs manual setup).
        reference_clock_selection_widget = QGroupBox('Reference clock setup:')

        # Big text label showing the currently set up reference clock.
        self.reference_datetime_label = QLabel('PLACEHOLDER')
        self.reference_datetime_label.setAlignment(Qt.AlignCenter)
        font = self.reference_datetime_label.font()
        font.setPointSize(self.REFERENCE_CLOCK_POINT_SIZE)
        self.reference_datetime_label.setFont(font)

        # Chooser radio buttons and the button group.
        synchronize_radiobutton = QRadioButton('Synchronize')
        synchronize_radiobutton.setChecked(True)
        synchronize_button = QPushButton('Synchronize')
        manual_setup_radiobutton = QRadioButton('Manual setup')
        reference_clock_setup_button_group = QButtonGroup()
        reference_clock_setup_button_group.addButton(synchronize_radiobutton)
        reference_clock_setup_button_group.addButton(manual_setup_radiobutton)
        reference_clock_selection_row_widget = QWidget()
        reference_clock_selection_row_widget.setLayout(QHBoxLayout())
        reference_clock_selection_row_widget.layout().addWidget(synchronize_radiobutton)
        reference_clock_selection_row_widget.layout().addWidget(synchronize_button)
        reference_clock_selection_row_widget.layout().addWidget(manual_setup_radiobutton)

        reference_clock_selection_widget.setLayout(QVBoxLayout())
        reference_clock_selection_widget.layout().addWidget(self.reference_datetime_label)
        reference_clock_selection_widget.layout().addWidget(reference_clock_selection_row_widget)

        # The latter choice, that expands to more choices.
        reference_clock_manual_setup_widget = self.init_reference_clock_manual_setup_widget()

        # Top-level widgets.
        reference_clock_setup_widget = QWidget()
        reference_clock_setup_widget.setLayout(QVBoxLayout())
        reference_clock_setup_widget.layout().addWidget(reference_clock_selection_widget)
        reference_clock_setup_widget.layout().addWidget(reference_clock_manual_setup_widget)

        # Signals/slots plumbing.
        synchronize_radiobutton.toggled.connect(synchronize_button.setEnabled)
        manual_setup_radiobutton.toggled.connect(reference_clock_manual_setup_widget.setEnabled)
        synchronize_button.clicked.connect(self.time_synchronizer.show)
        self.time_synchronizer.clicked.connect(self.handle_time_synchronizer_done)

        # Set default state.
        synchronize_radiobutton.click()
        reference_clock_manual_setup_widget.setEnabled(False)

        return reference_clock_setup_widget
Example #2
0
 def _init_mode_picker(self, layout):
     image_button = QRadioButton('Images')
     video_button = QRadioButton('Video')
     self.mode_button_group.addButton(image_button)
     self.mode_button_group.addButton(video_button)
     image_button.clicked.connect(lambda: self.trigger_set_mode('images'))
     video_button.clicked.connect(lambda: self.trigger_set_mode('video'))
     layout.addWidget(image_button)
     layout.addWidget(video_button)
     image_button.click()
Example #3
0
class AxisSettings(QWidget):
    def __init__(self, unit=None, parent=None):
        super(AxisSettings, self).__init__(parent)

        self._auto_radiobutton = QRadioButton('Automatic', self)
        self._fix_radiobutton = QRadioButton('Fixed', self)
        self._button_group = QButtonGroup()
        self._button_group.addButton(self._auto_radiobutton)
        self._button_group.addButton(self._fix_radiobutton)
        self.upper_layout = QHBoxLayout()
        self.upper_layout.addWidget(self._auto_radiobutton)

        self._from_lineedit = QLineEdit()
        self._from_lineedit.setFixedWidth(_LINEEDIT_WIDTH)
        self._from_lineedit.setValidator(QDoubleValidator())
        self._from_lineedit.setAlignment(Qt.AlignRight)

        self._to_label = QLabel('to')
        self._to_lineedit = QLineEdit()
        self._to_lineedit.setFixedWidth(_LINEEDIT_WIDTH)
        self._to_lineedit.setValidator(QDoubleValidator())
        self._to_lineedit.setAlignment(Qt.AlignRight)

        self._unit_label = QLabel(unit) if unit else None

        self.lower_layout = QHBoxLayout()
        self.lower_layout.addWidget(self._fix_radiobutton)
        self.lower_layout.addWidget(self._from_lineedit)
        self.lower_layout.addWidget(self._to_label)
        self.lower_layout.addWidget(self._to_lineedit)
        if self._unit_label:
            self.lower_layout.addWidget(self._unit_label)

    def set_values(self, fix, from_value, to_value):
        self._from_lineedit.setText(str(from_value))
        self._to_lineedit.setText(str(to_value))
        if fix:
            self._fix_radiobutton.click()
        else:
            self._auto_radiobutton.click()

    @property
    def fix_enabled(self):
        return self._fix_radiobutton.isChecked()

    @property
    def from_value(self):
        return float(self._from_lineedit.text())

    @property
    def to_value(self):
        return float(self._to_lineedit.text())
Example #4
0
    def init_clock_selection_widget(self):
        """Initialize the clock selection stuff.

        This method initializes the clock selection radio buttons, and triggers the initialization
        of the reference clock selection stage.

        There are two choices at this level: wall clock and reference clocks.
        """
        # Clock selection (wall clock vs reference clock).
        clock_selection_widget = QGroupBox('Use clock:')

        # Chooser radio buttons and the button group.
        wall_clock_radiobutton = QRadioButton('Wall clock')
        self.reference_clock_radiobutton = QRadioButton('Reference clock')
        clock_source_button_group = QButtonGroup()
        clock_source_button_group.addButton(wall_clock_radiobutton)
        clock_source_button_group.addButton(self.reference_clock_radiobutton)
        clock_selection_widget.setLayout(QHBoxLayout())
        clock_selection_widget.layout().addWidget(wall_clock_radiobutton)
        clock_selection_widget.layout().addWidget(self.reference_clock_radiobutton)

        # The latter choice, that expands to more choices.
        reference_clock_setup_widget = self.init_reference_clock_setup_widget()

        # Top-level widgets.
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(clock_selection_widget)
        self.layout().addWidget(reference_clock_setup_widget)

        # Signals/slots plumbing.
        self.reference_clock_radiobutton.toggled.connect(reference_clock_setup_widget.setEnabled)
        self.reference_clock_radiobutton.toggled.connect(self.toggle_reference_clock_setup)

        # Set default state.
        wall_clock_radiobutton.click()
        reference_clock_setup_widget.setEnabled(False)
Example #5
0
class PlotTab(TraceDocks):
	## The constructor
	# @param parent parent for this widget
	def __init__(self,parent):
		super(PlotTab, self).__init__(parent,'Plot Tab')
		self.tabName = 'PlotTab'
		self.parent = parent
		self.logger.logEvent('Creating Tab now: '+ self.tabName)
		Globals.dockDict['dockStart'].createPlotButt.clicked.connect(self.createPlot)
		# Create necessary variables
		self.snifferConfig.configFilterState = 'Local'
		self.snifferConfig.configCurrentTheme = 'Dark'
		self.snifferConfig.parseConfigFromFile()
		
		self.writePayload = PayloadData()
		self.snifferPayload = PayloadData()
		self.singleShotTime = 0
		self.end_time = 0
		self.start_time = 0
		#self.snifferConfigData = self.parent.snifferConfigData
		#self.failCnt = self.parent.failCnt
		self.purge = 0
		#self.measurementIsRunning = self.parent.measurementIsRunning
	
	## Create Layout for this Tab
	def setPlotTabLayout(self):    
		# Create Plot Tab --------------------###    
		# Create Layouts
		self.VLayout = QVBoxLayout()
		self.H1layout = QHBoxLayout()
		self.H1layout.setSpacing(15)
		self.H11layout = QHBoxLayout()
		self.H2layout = QHBoxLayout()
		self.V11layout = QVBoxLayout()
		self.V12layout = QVBoxLayout()
		
		self.V21layout = QVBoxLayout()
		self.V23layout = QVBoxLayout()
		self.V22layout = QVBoxLayout()
		#------------------------------------
		 
		# Create Widgets for H1layout         
		# Create Browser
		self.plotter = SniffPlot(self.snifferConfig)
		self.rangeslider = QRangeSlider(self)
		
		self.filterGroup = QButtonGroup()
		self.localFilterRadio = QRadioButton('Local',self)
		self.globalFilterRadio = QRadioButton('Global', self)
		self.configureFilterButt = QPushButton('Configure Filter')
		self.createPlotButt = QPushButton('Create Plot')
		self.exportPlotButt = QPushButton('Export Plot')
		
		# We need to sync the UI before connecting any slots in order to prevent accidental stateChanges.
		self.syncUiToConfig() 
		
		self.configureFilterButt.clicked.connect(self.configureFilter)
		self.createPlotButt.clicked.connect(self.createPlot)
		self.exportPlotButt.clicked.connect(self.exportPlot)
		self.localFilterRadio.clicked.connect(self.localRadioSelected)
		self.globalFilterRadio.clicked.connect(self.globalRadioSelected)
		
		self.H11layout.addWidget(self.localFilterRadio)
		self.H11layout.addWidget(self.globalFilterRadio)
		self.H11layout.addWidget(self.createPlotButt)
		self.H11layout.addWidget(self.exportPlotButt)
		self.V12layout.addLayout(self.H11layout)
		self.V12layout.addWidget(self.configureFilterButt)
		
		self.H1layout.addLayout(self.V11layout)
		self.H1layout.addStretch()
		self.H1layout.addLayout(self.V12layout)
		
		self.plotWindowStart=QDoubleSpinBox(self)
		self.plotWindowEnd=QDoubleSpinBox(self)
		
		self.plotWindowResetStart=QPushButton(self)
		self.plotWindowResetEnd=QPushButton(self)
		
		self.plotWindowResetStart.pressed.connect(self.plotter.resetStart)
		self.plotWindowResetEnd.pressed.connect(self.plotter.resetEnd)
		
		self.plotWindowResetStart.setText("R")
		self.plotWindowResetEnd.setText("R")
		
		self.plotWindowStart.setSuffix("ms")
		self.plotWindowEnd.setSuffix("ms")
		
		self.plotWindowStartLabel=QLabel(self)
		self.plotWindowDurationLabel=QLabel(self)
		self.plotWindowEndLabel=QLabel(self)
		
		self.applyRange=QPushButton(None)
		self.applyRange.setText("Apply Range")
		
		self.H2layout.addLayout(self.V21layout)
		self.H2layout.addWidget(self.plotWindowResetStart)
		self.H2layout.addStretch()
		self.H2layout.addLayout(self.V22layout)
		self.H2layout.addStretch()
		self.H2layout.addWidget(self.plotWindowResetEnd)
		self.H2layout.addLayout(self.V23layout)
		
		
		self.V21layout.addWidget(self.plotWindowStart)
		self.V21layout.addWidget(self.plotWindowStartLabel)
		
		self.V22layout.addWidget(self.applyRange)
		self.V22layout.addWidget(self.plotWindowDurationLabel)
		
		self.V23layout.addWidget(self.plotWindowEnd)
		self.V23layout.addWidget(self.plotWindowEndLabel)
		
		#------------------------------------
		
		self.VLayout.addLayout(self.H1layout)
		
		self.VLayout.addWidget(self.plotter)
		self.VLayout.addWidget(self.rangeslider)
		self.VLayout.addLayout(self.H2layout)
		
		self.applyRange.pressed.connect(self.plotter.applyRange)
		
		self.plotter.setScrollbar(self.rangeslider)
		self.plotter.setWindowSpinner(self.plotWindowStart,self.plotWindowEnd)
		self.plotter.setRangeLabels(self.plotWindowStartLabel,self.plotWindowEndLabel,self.plotWindowDurationLabel)
		self.dockContents.setLayout(self.VLayout)
	
	## Get Task name from Task-ID
	def getTaskName(self,taskid):
		return "Task-"+str(taskid)
	
	### Export plot to PNG image
	def exportPlot(self):
		# Create dummy SniffPlot with light Theme
		self.plotterExport = SniffPlot(self.snifferConfig)
		self.plotterExport.setStyleSheet("background-color: rgb(255, 255, 255);")
		self.plotterExport.setOverrideStyle("Light")
		self.plotterExport.endTime=self.plotter.endTime
		self.plotterExport.endTime_=self.plotter.endTime_
		self.plotterExport.startTime=self.plotter.startTime
		self.plotterExport.startTime_=self.plotter.startTime_
		self.plotterExport.data=self.plotter.data
		self.plotterExport.ntask=self.plotter.ntask
		self.plotterExport.plotStart=self.plotter.plotStart
		self.plotterExport.plotEnd=self.plotter.plotEnd
		self.plotterExport.taskcols=self.plotter.taskcols
		self.plotterExport.resize(1050,750)
		
		# Create image to fit Plot
		pixmap=QtGui.QPixmap(self.plotterExport.size());
		# Render Widget to QPixMap and safe file
		self.plotterExport.render(pixmap)
		filename, ok = QFileDialog.getSaveFileName(self, 'Save Plot', 'Plot.png', 'PNG files (*.png)')
		if filename and ok:
			pixmap.save(filename);
		del self.plotterExport
		del pixmap
	
	## Generate actual plot
	def displayFunction(self,timerValueInMs_extern,payloadList):
		knownTasks={} #All known tasks which will be displayed in the plot
		readyTasks={} #Saves the ready-state of a task
		dataFrame=[]
		filteredPayloads = []
		eventWidth=1 #Width of an displayed Event in ms
		overflowCounter=0 #Counts how often the tickOverflowValue is surpassed
		tickOverflow = int(Globals.dockDict['dockConfig'].snifferConfig.configMaxTickCountVal) #value of tick-overflow in normal ticks
		timerValueInMs=1/timerValueInMs_extern
		previousElementTickCount=self.getTickCount(payloadList[0].payloadHead) #Reads the start Time
		previousElement=payloadList[0]
		print('I have Payloads len:' + str(len(payloadList)))
		
		print('I have filtered len:' + str(len(filteredPayloads)))
		
		self.task_state_changes=defaultdict(list)
		self.end_time=0
		self.start_time=None
		for element in payloadList: #for each element in the payload list
			if element.payloadHead.informationID is 148:
				continue

			if element.payloadHead.informationID is 149:
				continue

			if element.payloadHead.informationID is 150:
				continue

			if hasattr(element, 'payloadHead'):# and hasattr(element,"data1"):
				if previousElementTickCount-self.getTickCount(element.payloadHead)==int(Globals.dockDict['dockConfig'].snifferConfig.configMaxTickCountVal): #Checks for overflow
					overflowCounter = overflowCounter+1
				
				previousElementTickCount=self.getTickCount(element.payloadHead)
				previousElement=element #rememver previousElement
				
				if element.payloadHead.informationID is 44:
					continue
				
				#get Data from element
				infoid=Globals.tspDict[element.payloadHead.informationID][0]
				
				timestamp=self.getTickCount(element.payloadHead)+\
				overflowCounter*tickOverflow+\
				self.getTimerValue(element.payloadHead)*timerValueInMs
				
				#skip Ticks
				if infoid=='ID_TASK_INCREMENT_TICK':
					continue

				
				#Task state from InfoID
				state2str={
				'ID_TASK_SWITCHED_OUT': "waiting",
				'ID_MOVED_TASK_TO_READY_STATE': "ready",
				'ID_TASK_SWITCHED_IN': "running"
				}
				
				#update task state and timestamp
				
				if infoid in ['ID_TASK_SWITCHED_OUT',
				'ID_MOVED_TASK_TO_READY_STATE',
				'ID_TASK_SWITCHED_IN']:
					task_id=element.data1
					self.task_state_changes[task_id].append({"time":timestamp,"state":state2str[infoid]})
				else:
					self.task_state_changes[99999].append({"time":timestamp,"state":infoid})
				
				if timestamp>self.end_time:
					self.end_time=timestamp
				
				if self.start_time is None or timestamp<self.start_time:
					self.start_time=timestamp
		#save data and send to Plotter
		self.task_state_changes=dict(self.task_state_changes)
		self.plotter.update_data(self.task_state_changes,self.end_time,self.start_time)
	
	## Handler for "Create Plot" button
	def createPlot(self):
		if(len(Globals.payloadList) == 0):
			self.displayException('The PayloadList is empty. Run a measurement?')
			return
		self.displayFunction(timerValueInMs_extern = int(Globals.dockDict['dockConfig'].snifferConfig.configTickToMsLine),payloadList = Globals.payloadList)
		
	
	## Enable all buttons
	def disableButtons(self):
		self.saveMeasButt.setEnabled(False)
		self.openMeasButt.setEnabled(False)
		print('Disable TabStart Buttons')
	
	## Disable all buttons
	def enableButtons(self):
		self.saveMeasButt.setEnabled(True)
		self.openMeasButt.setEnabled(True)
		print('Enable TabStart Buttons')
	
	## Display status message
	def displayStatusMessage(self,myMessage):
		self.statusBox.setText('Message: ' + myMessage)    
	
	## Change waitForReset state
	def waitResetCheckChanged(self):
		self.snifferConfig.configWaitResetCheck ^= 1
		self.logger.logEvent('changed Wait for Reset Checkbox to - '+ str(self.snifferConfig.configWaitResetCheck))
	
	## Select local Filter
	def localRadioSelected(self):
		self.snifferConfig.configFilterState = 'Local'
		self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState))
	
	## Select global Filter
	def globalRadioSelected(self):
		self.snifferConfig.configFilterState = 'Global'
		self.logger.logEvent('changed Filter Radio to - '+ str(self.snifferConfig.configFilterState))
	
	## Get TickCount from Header
	def getTickCount(self,payloadHeader):
		return payloadHeader.tickCountHigh << 8 | payloadHeader.tickCountLow
	
	## Get TimerValue from Hader
	def getTimerValue(self,payloadHeader):
		if Globals.dockDict['dockConfig'].snifferConfig.configUpDownState == 'Up':
			return payloadHeader.timerByteHigh << 8 | payloadHeader.timerByteLow
		elif Globals.dockDict['dockConfig'].snifferConfig.configUpDownState == 'Down':
			return int(Globals.dockDict['dockConfig'].snifferConfig.configMaxTickCountVal) - (payloadHeader.timerByteHigh << 8 | payloadHeader.timerByteLow)
		else:
			self.logger.logEvent('Error in getTimerValue in PlotTab')
			return 0

	# --- MANDATORY UI FUNCTIONS --- #
	# -------------------------------# 
	
	## Read out all components of snifferConfig and set the UI elements according to
	#  the saved values.   		
	def syncUiToConfig(self):
		if self.snifferConfig.configFilterState == 'Local':
			self.localFilterRadio.click()
		elif self.snifferConfig.configFilterState == 'Global':
			self.globalFilterRadio.click()
		else:
			print('Error, neither local nor global in config')
			
	## Open the correct filter based on the radioButton. If the Global-filter is checked
	#  we assign its calledby variable in order to execute the right callback after the filter is saved. 
	def configureFilter(self):
		if self.localFilterRadio.isChecked():
			self.snifferFilter.show()
		elif self.globalFilterRadio.isChecked():
			print('stump implementation for global filter')
		else:
			print('neither radios checked. Error!')
			
	## CB: // Updates the UI-contents with after filtering has taken place.
	#  This function should not be called by the tab itself, but by the filter
	#  @param filteredIDs the IDs that are to be kept in the payloadList (obsolete)
	#  @param filteredPayloads the new payloadList, which only contains the payloads filtered by the SnifferFilter  			
	def filterUpdated(self, filteredIDs, filteredPayloads):
		print('we arrive from SnifferFilter')
		if(len(Globals.payloadList) == 0):
			self.displayException('The PayloadList is empty. Run a measurement?')
			return
		self.displayFunction(timerValueInMs_extern = int(Globals.dockDict['dockConfig'].snifferConfig.configTickToMsLine),payloadList = filteredPayloads)
class RequestsOperations(QWidget):
    def __init__(self, parent):
        super().__init__(parent)
        self.initUI()
        self.__ops = []

    def initUI(self):
        self.layout = QFormLayout()
        self.layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.layout.setLabelAlignment(Qt.AlignLeft)
        self.layout.setFormAlignment(Qt.AlignLeft | Qt.AlignTop)

        twoListsOfSets = QWidget()
        twoListsOfSets.setLayout(QHBoxLayout())
        twoListsOfSets.layout().setContentsMargins(5, 10, 5, 5)
        twoListsOfSets.layout().setSpacing(0)

        effect = QGraphicsDropShadowEffect()
        effect.setBlurRadius(10)
        effect.setColor(QColor(0, 0, 0, 160))
        effect.setOffset(0.0)

        self.requestList = QListView()
        self.requestList.setSpacing(3)
        self.requestList.setAutoFillBackground(True)
        self.requestList.setGraphicsEffect(effect)
        self.requestList.setFrameStyle(QFrame.NoFrame)
        self.requestList.viewport().setAutoFillBackground(False)
        self.requestList.setFlow(QListView.LeftToRight)
        self.requestList.setWrapping(True)
        self.requestList.setResizeMode(QListView.Adjust)
        self.requestList.setUniformItemSizes(True)
        self.requestsModel = QStandardItemModel()
        self.requestList.setModel(self.requestsModel)

        effect = QGraphicsDropShadowEffect()
        effect.setBlurRadius(10)
        effect.setColor(QColor(0, 0, 0, 160))
        effect.setOffset(0.0)

        self.requestList2 = QListView()
        self.requestList2.setSpacing(3)
        self.requestList2.setAutoFillBackground(True)
        self.requestList2.setGraphicsEffect(effect)
        self.requestList2.setFrameStyle(QFrame.NoFrame)
        self.requestList2.viewport().setAutoFillBackground(False)
        self.requestList2.setFlow(QListView.LeftToRight)
        self.requestList2.setWrapping(True)
        self.requestList2.setResizeMode(QListView.Adjust)
        self.requestList2.setUniformItemSizes(True)
        self.requestsModel2 = QStandardItemModel()
        self.requestList2.setModel(self.requestsModel2)

        twoListsOfSets.layout().addWidget(self.requestList)
        twoListsOfSets.layout().addWidget(self.requestList2)

        self.layout.addRow("SETS", twoListsOfSets)
        self.layout.addRow(HorizontalLine(self))

        self.operationSelection = QGroupBox()
        self.operationSelection.setFlat(True)
        self.operationSelection.setLayout(QVBoxLayout())

        self.buttonIntersection = QRadioButton("Intersection")
        self.operationSelection.layout().addWidget(self.buttonIntersection)
        self.buttonIntersection.clicked.connect(
            self.__disableSecondRequestList)
        self.buttonIntersection.click()

        self.buttonUnion = QRadioButton("Union")
        self.operationSelection.layout().addWidget(self.buttonUnion)
        self.buttonUnion.clicked.connect(self.__disableSecondRequestList)

        self.buttonDiff = QRadioButton("Difference")
        self.operationSelection.layout().addWidget(self.buttonDiff)
        self.buttonDiff.clicked.connect(self.__enableSecondRequestList)

        self.layout.addRow("OPERATION", self.operationSelection)

        self.buttonApplyWidget = QWidget()
        self.buttonApplyWidget.setSizePolicy(QSizePolicy.Expanding,
                                             QSizePolicy.Preferred)
        self.buttonApplyLayout = QHBoxLayout()
        self.buttonApplyLayout.setContentsMargins(0, 0, 0, 0)
        self.buttonApplyWidget.setLayout(self.buttonApplyLayout)
        self.buttonApply = QPushButton("Apply")
        self.buttonApply.clicked.connect(self.__applyOp)
        self.operationSelection.layout().addWidget(self.buttonApply)
        self.buttonApplyLayout.addWidget(self.buttonApply,
                                         alignment=Qt.AlignRight)
        self.layout.addRow("", self.buttonApplyWidget)
        self.layout.addRow(HorizontalLine(self))

        self.layout.addRow("RESULTS", None)

        self.resultingSets = QTableView()
        self.resultingSets.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.resultingSets.verticalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.resultingSets.setModel(OperationsTableModel())
        self.layout.addRow(self.resultingSets)
        self.layout.addRow(HorizontalLine(self))

        self.outputSetSelection = QComboBox()
        self.outputSetSelection.setSizePolicy(QSizePolicy.MinimumExpanding,
                                              QSizePolicy.Fixed)
        self.layout.addRow("OUTPUT SET", self.outputSetSelection)

        self.setLayout(self.layout)

    def outputSet(self):
        return self.outputSetSelection.currentText()

    def setOutputSet(self, outputSetName):
        self.outputSetSelection.setCurrentText(outputSetName)

    @property
    def ops(self):
        return copy.deepcopy(self.__ops)

    def __applyOp(self):
        includedSets = [
            self.requestsModel.item(i).text()
            for i in range(self.requestsModel.rowCount())
            if self.requestsModel.item(i).data(Qt.CheckStateRole) == QVariant(
                Qt.Checked)
        ]

        if self.buttonUnion.isChecked():
            if len(includedSets) > 1:
                opName = SetNameManagement.getUniqueSetName()
                self.addOp(OverpassUnion(opName), includedSets)
                logging.info("Union created.")
            else:
                logging.error("The union must have at least two sets.")
        elif self.buttonIntersection.isChecked():
            if len(includedSets) > 1:
                opName = SetNameManagement.getUniqueSetName()
                self.addOp(OverpassIntersection(opName), includedSets)
                logging.info("Intersection created.")
            else:
                logging.error("The intersection must have at least two sets.")
        elif self.buttonDiff.isChecked():
            excludedSets = [
                self.requestsModel2.item(i).text()
                for i in range(self.requestsModel2.rowCount())
                if self.requestsModel2.item(i).data(Qt.CheckStateRole) ==
                QVariant(Qt.Checked)
            ]

            if len(includedSets) == 1 and len(excludedSets) > 0:
                opName = SetNameManagement.getUniqueSetName()
                self.addOp(OverpassDiff(includedSets[0], opName), excludedSets)
                logging.info("Difference created.")
            else:
                logging.error(
                    "The difference must have only one set selected in the first list and at least one in the other."
                )
        logging.debug("LINE")

    def addOp(self, op, sets=None):
        SetNameManagement.assign(op.name)
        self.__ops.append(op)
        if sets is not None:
            op.addSets(sets)
        self.resultingSets.model().addOp(op.name, op)
        self.addRequest(op.name)
        self.cleanRequestList()

    def __enableSecondRequestList(self):
        self.requestList2.show()

    def __disableSecondRequestList(self):
        self.requestList2.hide()

    def addRequest(self, name):
        self.requestsModel.beginInsertRows(QModelIndex(),
                                           self.requestsModel.rowCount(),
                                           self.requestsModel.rowCount())
        item = QStandardItem(name)
        item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole)
        self.requestsModel.appendRow(item)
        self.requestsModel.endInsertRows()

        self.requestsModel2.beginInsertRows(QModelIndex(),
                                            self.requestsModel2.rowCount(),
                                            self.requestsModel2.rowCount())
        item = QStandardItem(name)
        item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        item.setData(QVariant(Qt.Unchecked), Qt.CheckStateRole)
        self.requestsModel2.appendRow(item)
        self.requestsModel2.endInsertRows()

        self.outputSetSelection.addItem(name)

    def removeSetAndDependencies(self, setName):
        removeList = [setName]

        for set in removeList:
            logging.info("Removing set '{}'.".format(set))
            removeList.extend(
                [i for i in self.__removeSet(set) if i not in removeList])
        logging.debug("LINE")

    def __removeSet(self, setName):
        dependencies = []
        for op in self.__ops:
            op.removeSet(setName)
            if not op.isValid():
                dependencies.append(op.name)

        for i in range(self.requestsModel.rowCount()):
            if self.requestsModel.item(i).text() == setName:
                self.requestsModel.beginRemoveRows(QModelIndex(), i, i)
                self.requestsModel.removeRow(i)
                self.requestsModel.endInsertRows()

                self.requestsModel2.beginRemoveRows(QModelIndex(), i, i)
                self.requestsModel2.removeRow(i)
                self.requestsModel2.endInsertRows()

                self.outputSetSelection.removeItem(i)
                break

        for op in self.__ops:
            if op.name == setName:
                self.resultingSets.model().removeOp(setName)
                self.__ops.remove(op)
                break

        SetNameManagement.releaseName(setName)

        return dependencies

    def reset(self):
        while len(self.ops) > 0:
            self.removeSetAndDependencies(self.ops[0].name)

    def cleanRequestList(self):
        for i in range(self.requestsModel.rowCount()):
            self.requestsModel.item(i).setData(QVariant(Qt.Unchecked),
                                               Qt.CheckStateRole)
            self.requestsModel2.item(i).setData(QVariant(Qt.Unchecked),
                                                Qt.CheckStateRole)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Backspace and self.resultingSets.hasFocus():

            advice = "Are you sure?\nAll sets containing this one will be deleted if they are no longer valid"
            reply = QMessageBox.question(self, "Remove request operation",
                                         advice)

            if reply == QMessageBox.Yes:
                select = self.resultingSets.selectionModel()
                while len(select.selectedRows()) > 0:
                    self.removeSetAndDependencies(
                        self.resultingSets.model().getOpByIndex(
                            select.selectedRows()[0].row()))

        event.accept()
Example #7
0
class MainWindow(QMainWindow):
    """
    Represents main window that extends QMainWindow and that is used for interaction with user.
    """
    def __init__(self, faces_number, draw_rectangles, parent=None):
        """Initializes main window.

        :param self: self
        :param faces_number: number of expected faces in frame
        :param draw_rectangles: indicator whether rectangles that bound detected faces should be drawn
        :param parent: parent of window
        """
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("FaceSnap")
        self.setWindowIcon(QIcon("stickers/icon.png"))
        self.faces_number = faces_number
        self.draw_rectangles = draw_rectangles
        self.file_name = ""
        self.chosen_filter = ""
        self.processing = False

        self.layout = QVBoxLayout()  # layout for the central widget
        widget = QWidget(self)  # central widget
        widget.setLayout(self.layout)
        self.setGeometry(0, 0, 650, 550)
        self.center_on_screen()

        self.existing_video_layout = QHBoxLayout()  # layout for existing video
        self.existing_video_widget = QWidget()
        self.existing_video_widget.setLayout(self.existing_video_layout)

        self.cam_video_layout = QHBoxLayout()  # layout for recorder video
        self.cam_video_widget = QWidget()
        self.cam_video_widget.setLayout(self.cam_video_layout)

        self.choice_group = QButtonGroup(
            widget)  # radio button group for input file choice
        self.filter_group = QButtonGroup(
            widget)  # radio button group for filter choice

        self.existing_video_radio = QRadioButton("Choose existing video")
        self.existing_video_button = QPushButton("Choose video file")

        self.cam_video_radio = QRadioButton("Capture video with camera")
        self.cam_video_button = QPushButton("Record video")

        self.mask_button = QRadioButton()
        self.cat_button = QRadioButton()
        self.ears_button = QRadioButton()
        self.flowers_button = QRadioButton()
        self.mustache_button = QRadioButton()
        self.glasses_button = QRadioButton()
        self.mouse_button = QRadioButton()
        self.pirate_button = QRadioButton()
        self.rainbow_button = QRadioButton()

        self.init_video_choice()
        self.init_filter_choice()

        self.process_button = QPushButton("Process video")
        self.process_button.clicked.connect(self.process_chosen_video)
        self.layout.addWidget(QWidget())
        self.layout.addWidget(QWidget())
        self.layout.addWidget(QWidget())
        self.layout.addWidget(self.process_button)
        self.layout.addWidget(QWidget())
        self.status = QStatusBar()
        self.layout.addWidget(self.status)
        self.setCentralWidget(widget)

    def center_on_screen(self):
        """Centers window on screen.

        :param self: self
        """
        resolution = QDesktopWidget().screenGeometry()
        self.move(
            (resolution.width() / 2) - (self.frameSize().width() / 2),
            (resolution.height() / 4 + 20) - (self.frameSize().height() / 2))

    def init_video_choice(self):
        """Initializes radio button group for video choice.

        :param self: self
        """
        self.cam_video_radio.clicked.connect(self.cam_video_chosen)
        self.choice_group.addButton(self.cam_video_radio)

        self.existing_video_radio.clicked.connect(self.existing_video_chosen)
        self.choice_group.addButton(self.existing_video_radio)

        self.existing_video_button.clicked.connect(self.open_file)
        self.existing_video_layout.addWidget(self.existing_video_radio)
        self.existing_video_layout.addWidget(self.existing_video_button)

        self.cam_video_button.clicked.connect(self.record_video)
        self.cam_video_layout.addWidget(self.cam_video_radio)
        self.cam_video_layout.addWidget(self.cam_video_button)

        self.layout.addWidget(self.existing_video_widget)
        self.layout.addWidget(self.cam_video_widget)

        self.existing_video_radio.click()

    def init_filter_choice(self):
        """Initializes radio button group for filter choice.

        :param self: self
        """
        self.layout.addWidget(QWidget())
        self.layout.addWidget(QWidget())

        sticker_rows = QVBoxLayout()
        first_row_layout = QHBoxLayout()
        first_row_widget = QWidget()
        first_row_widget.setLayout(first_row_layout)
        second_row_layout = QHBoxLayout()
        second_row_widget = QWidget()
        second_row_widget.setLayout(second_row_layout)
        third_row_layout = QHBoxLayout()
        third_row_widget = QWidget()
        third_row_widget.setLayout(third_row_layout)

        sticker_rows.addWidget(first_row_widget)
        sticker_rows.addWidget(second_row_widget)
        sticker_rows.addWidget(third_row_widget)
        filter_widget = QWidget()
        filter_widget.setLayout(sticker_rows)

        self.init_first_row_filters(first_row_layout)
        self.init_second_row_filters(second_row_layout)
        self.init_third_row_filters(third_row_layout)

        self.layout.addWidget(filter_widget)

    def init_first_row_filters(self, first_row_layout):
        """Initializes first row of radio button group for filter choice.

        :param self: self
        :param first_row_layout: layout for first row of filters
        """
        self.mask_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.mask_button)
        self.mask_button.setIcon(QIcon(stickers.mask_sticker()))
        first_row_layout.addWidget(self.mask_button)  # add mask to widget

        first_row_layout.addWidget(QWidget())  # add empty space

        self.cat_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.cat_button)
        self.cat_button.setIcon(QIcon(stickers.cat_sticker()))
        first_row_layout.addWidget(self.cat_button)  # add cat to widget

        first_row_layout.addWidget(QWidget())  # add empty space

        self.ears_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.ears_button)
        self.ears_button.setIcon(QIcon(stickers.ears_sticker()))
        first_row_layout.addWidget(self.ears_button)  # add ears to widget

    def init_second_row_filters(self, second_row_layout):
        """Initializes second row of radio button group for filter choice.

        :param self: self
        :param second_row_layout: layout for second row of filters
        """
        self.flowers_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.flowers_button)
        self.flowers_button.setIcon(QIcon(stickers.flowers_sticker()))
        second_row_layout.addWidget(
            self.flowers_button)  # add flowers to widget

        second_row_layout.addWidget(QWidget())  # add empty space

        self.mustache_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.mustache_button)
        self.mustache_button.setIcon(QIcon(stickers.mustache_sticker()))
        second_row_layout.addWidget(
            self.mustache_button)  # add mustache to widget

        second_row_layout.addWidget(QWidget())  # add empty space

        self.glasses_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.glasses_button)
        self.glasses_button.setIcon(QIcon(stickers.glasses_sticker()))
        second_row_layout.addWidget(
            self.glasses_button)  # add glasses to widget

    def init_third_row_filters(self, third_row_layout):
        """Initializes third row of radio button group for filter choice.

        :param self: self
        :param third_row_layout: layout for third row of filters
        """
        self.mouse_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.mouse_button)
        self.mouse_button.setIcon(QIcon(stickers.mouse_sticker()))
        third_row_layout.addWidget(self.mouse_button)  # add mouse to wiget

        third_row_layout.addWidget(QWidget())  # add empty space

        self.pirate_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.pirate_button)
        self.pirate_button.setIcon(QIcon(stickers.pirate_sticker()))
        third_row_layout.addWidget(self.pirate_button)  # add pirate to widget

        third_row_layout.addWidget(QWidget())  # add empty space

        self.rainbow_button.clicked.connect(self.filter_chosen)
        self.filter_group.addButton(self.rainbow_button)
        self.rainbow_button.setIcon(QIcon(stickers.rainbow_sticker()))
        third_row_layout.addWidget(
            self.rainbow_button)  # add rainbow to widget

    def filter_chosen(self):
        """Detects which filter is chosen.

        :param self: self
        """
        if self.mask_button.isChecked():
            self.chosen_filter = "mask"
        elif self.cat_button.isChecked():
            self.chosen_filter = "cat"
        elif self.ears_button.isChecked():
            self.chosen_filter = "ears"
        elif self.flowers_button.isChecked():
            self.chosen_filter = "flowers"
        elif self.mustache_button.isChecked():
            self.chosen_filter = "mustache"
        elif self.glasses_button.isChecked():
            self.chosen_filter = "glasses"
        elif self.mouse_button.isChecked():
            self.chosen_filter = "mouse"
        elif self.pirate_button.isChecked():
            self.chosen_filter = "pirate"
        elif self.rainbow_button.isChecked():
            self.chosen_filter = "rainbow"
        else:
            self.chosen_filter = ""

    def process_chosen_video(self):
        """Starts processing chosen video and informs user about process success.

        :param self: self
        """
        if self.file_name == "":
            print("Video for processing is not chosen!")
            self.status.showMessage("Video for processing is not chosen!")
        else:
            if self.processing:
                self.status.showMessage("Processing video in progress!")
            else:
                self.processing = True
                self.status.showMessage("Processing video in progress!")
                if process_video(self.file_name, self.faces_number,
                                 self.draw_rectangles, self.chosen_filter,
                                 self):
                    self.status.showMessage("Processing video is successful!")
                    self.processing = False
                else:
                    self.status.showMessage("Error opening video!")
                    self.processing = False

    def existing_video_chosen(self):
        """Disables cam video button and enables existing video button.

        :param self: self
        """
        self.cam_video_button.setEnabled(False)
        self.existing_video_button.setEnabled(True)

    def cam_video_chosen(self):
        """Enables cam video button and disables existing video button.

        :param self: self
        """
        self.cam_video_button.setEnabled(True)
        self.existing_video_button.setEnabled(False)

    def open_file(self):
        """Opens dialog for file choice.

        :param self: self
        """
        self.file_name, _ = QFileDialog.getOpenFileName(
            self, "Open Video", QDir.homePath())
        if self.file_name != "":
            print(self.file_name)
            self.status.showMessage("Video successfully chosen!")

    def record_video(self):
        """Opens dialog for directory choice where file is saved.

        :param self: self
        """
        self.file_name = str(
            QFileDialog.getExistingDirectory(
                self, "Select Directory Where Video Will Be Saved",
                QDir.homePath()))
        if self.file_name != '':
            self.file_name += "/output_video.avi"
            print(self.file_name)
            self.file_name = record_from_camera(self.file_name, self)
            self.status.showMessage("Video successfully recorded!")
Example #8
0
    def __types_block(self, name):
        """
        Makes block for twilight data selection:
            [radio buttons: {none, scrape, import}]
            [browse button (for import), path (for import)]
        Label not included (combo box contains)
        :param name: of type of data
        :return: widget of block, button group of radio buttons, line edit of path
        """
        layout = QVBoxLayout()

        top_row_layout = QHBoxLayout()

        button_group = QButtonGroup()  # radio buttons
        button_group.setExclusive(True)

        none_button = QRadioButton("None")
        scrape_button = QRadioButton("Scrape")
        import_button = QRadioButton("Import")

        button_group.addButton(none_button,
                               1)  # need 1-index because 0 means not found
        button_group.addButton(scrape_button, 2)
        button_group.addButton(import_button, 3)
        top_row_layout.addWidget(none_button)
        top_row_layout.addWidget(scrape_button)
        top_row_layout.addWidget(import_button)
        top_row_layout.addStretch()

        button_group.buttonClicked.connect(
            lambda current: self.update_combo_label_clicked(current))

        self.combo_box.setCurrentIndex(self.types.index(name))
        if name in {"Sun", "Moon", "Nautical"
                    }:  # default setting for Paul Revere Battalion slides
            scrape_button.setChecked(True)
            scrape_button.click()
        else:
            none_button.setChecked(True)
            none_button.click()

        top_row = QWidget()
        top_row.setLayout(top_row_layout)

        bottom_row_layout = QHBoxLayout()

        button = QPushButton("Browse")  # browse button
        abbrev_path = QLineEdit()  # line for import path
        full_path = MutableString("")
        bottom_row_layout.addWidget(button)
        bottom_row_layout.addWidget(abbrev_path)
        button.clicked.connect(lambda: self.set_path(abbrev_path, full_path))
        abbrev_path.textEdited.connect(
            lambda: self.set_path(abbrev_path, full_path, abbrev_path.text()))

        bottom_row = QWidget()
        bottom_row.setLayout(bottom_row_layout)

        layout.addWidget(top_row)
        layout.addWidget(bottom_row)

        out = QWidget()
        out.setLayout(layout)

        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        top_row_layout.setContentsMargins(0, 0, 5, 0)
        bottom_row_layout.setContentsMargins(0, 0, 0, 0)
        bottom_row_layout.setSpacing(5)

        return out, button, button_group, abbrev_path, full_path
Example #9
0
class LayoutPlugin(MainWindowPlugin):
    def __init__(self, main_window, announces, api):
        super().__init__(main_window, announces, api)
        self.topology_ratio = QRadioButton('拓扑布局', main_window)
        self.physical_ratio = QRadioButton('物理布局', main_window)

        self.group_box = QButtonGroup(main_window)
        self.group_box.addButton(self.topology_ratio)
        self.group_box.addButton(self.physical_ratio)
        self.group_box.buttonClicked.connect(self.buttonClickedSlot)

        tool_bar = QToolBar(main_window)
        tool_bar.setWindowTitle('位置工具栏')
        tool_bar.addWidget(self.topology_ratio)
        tool_bar.addWidget(self.physical_ratio)
        main_window.addToolBar(Qt.TopToolBarArea, tool_bar)

        self.topology_layout = None
        self.last_clicked_ratio = None
        self.pixmap = QPixmap(BACKGROUND_MAP_IMAGE)
        announces['playSteps'].append(self.playSteps)
        announces['sceneNodeMoved'].append(self.sceneNodeMoved)

    def playSteps(self, steps):
        if self.group_box.checkedButton() is None:  # 设置默认模式
            self.topology_layout = self._getTopologyLayout()
            self.topology_ratio.click(
            )  # 导致 self.buttonClickedSlot(self.topology_ratio)
        elif self.group_box.checkedButton() is self.physical_ratio:  # 物理位置图
            self.buttonClickedSlot(self.physical_ratio)  # 重新加载位置图, 以更新位置信息

    def buttonClickedSlot(self, ratio):
        if (ratio is self.topology_ratio) and (ratio is
                                               self.last_clicked_ratio):
            self.topology_layout = self._getTopologyLayout()  # 多次点击, 重新计算位置

        self.api['Scene.setBackgroundPixmap'](self.getBackgroundPixmap())
        self.api['Scene.setLayout'](self.getLayout())
        self.last_clicked_ratio = ratio

    def sceneNodeMoved(self, node_id, pos):
        if self.group_box.checkedButton() is self.topology_ratio:
            self.topology_layout[node_id] = pos  # 拓扑图模式下修改缓存的位置信息
        elif self.group_box.checkedButton() is self.physical_ratio:
            icn_node = self.api['Sim.node'](node_id)
            icn_node.pos = pos  # 物理图模式下修改节点实际位置
            self.announces['playSteps'](0)
        else:  # 没有模式被设置
            pass

    # -------------------------------------------------------------------------
    def getLayout(self):
        if self.group_box.checkedButton() is self.topology_ratio:
            return self.topology_layout
        elif self.group_box.checkedButton() is self.physical_ratio:
            return self._getPhysicalLayout()
        else:  # 没有模式被设置
            pass

    def getBackgroundPixmap(self):
        if self.group_box.checkedButton() is self.topology_ratio:
            return None
        elif self.group_box.checkedButton() is self.physical_ratio:
            return self.pixmap
        else:  # 没有模式被设置
            pass

    # -------------------------------------------------------------------------
    def _getPhysicalLayout(self) -> dict:
        graph = self.api['Sim.graph']()
        layout = {}
        for node_id in graph:
            icn_node = self.api['Sim.node'](node_id)
            layout[node_id] = getattr(icn_node, 'pos', (0, 0))
        return layout

    def _getTopologyLayout(self) -> dict:
        graph = self.api['Sim.graph']()
        layout = networkx.spring_layout(graph, scale=300,
                                        iterations=50)  # scale 单位pix
        # FIXME spring_layout 中, 利用已有pos迭代, 会出现扭曲. 参数: pos= self.topology_layout
        return layout
Example #10
0
class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        QMainWindow.__init__(self, *args, **kwargs)

        self.extension = '.jpg'

        self.image_width, self.image_height = 1280, 720
        # self.image_width, self.image_height = 640, 360

        # Widget de Imagen.
        self.image_widget = ImageWidget(self.image_width, self.image_height)

        # Widget de seleccion de tracker.
        self.tracker_combobox = ComboBoxWidget('./config/tracker_list.txt')
        self.tracker_groupBox = self.create_groupBox_from_widget('Tracker', self.tracker_combobox)

        # Widget de seleccion de clase.
        self.class_list = ListWidget('./config/class_list.txt')
        self.class_groupBox = self.create_groupBox_from_widget('Classes', self.class_list)

        # Botones de acciones.
        self.radio_track = QRadioButton(utils.MODE_DICT[utils.MODE_TRACK])
        self.radio_rtrack = QRadioButton(utils.MODE_DICT[utils.MODE_RTRACK])
        self.radio_copy = QRadioButton(utils.MODE_DICT[utils.MODE_COPYBBOX])
        self.radio_empty = QRadioButton(utils.MODE_DICT[utils.MODE_EMPTY])
        self.radio_nothing = QRadioButton(utils.MODE_DICT[utils.MODE_NOTHING])
        self.group_box = self.create_button_group()

        # Botones de ejecucion.
        self.button_prev = QPushButton('Prev')
        self.button_next = QPushButton('Next')
        self.button_run = QPushButton('Run')
        self.button_stop = QPushButton('Stop')

        # Folder reader.
        self.folder_reader = FolderReader()
        # Exportar txt a xml.
        self.xml_creator = XMLCreator('./imagen', self.extension)

        # Main controller.
        self.controller = Controller(self, self.extension)
        self.controller.set_classes(self.class_list.get_items())

        # Shortcuts.
        self.shortcut_next = QShortcut(QKeySequence('D'), self)
        self.shortcut_prev = QShortcut(QKeySequence('A'), self)
        self.shortcut_1 = QShortcut(QKeySequence('1'), self)
        self.shortcut_2 = QShortcut(QKeySequence('2'), self)
        self.shortcut_3 = QShortcut(QKeySequence('3'), self)
        self.shortcut_4 = QShortcut(QKeySequence('4'), self)
        self.shortcut_5 = QShortcut(QKeySequence('5'), self)
        self.shortcut_6 = QShortcut(QKeySequence('6'), self)
        self.shortcut_7 = QShortcut(QKeySequence('7'), self)
        self.shortcut_8 = QShortcut(QKeySequence('8'), self)
        self.shortcut_9 = QShortcut(QKeySequence('9'), self)

        self.setup_ui()

        self.setup_signals()

    def setup_signals(self):
        # Mode signals.
        self.radio_track.clicked.connect(self.controller.update_mode_to_track)
        self.radio_rtrack.clicked.connect(self.controller.update_mode_to_rtrack)
        self.radio_copy.clicked.connect(self.controller.update_mode_to_copybbox)
        self.radio_empty.clicked.connect(self.controller.update_mode_to_empty)
        self.radio_nothing.clicked.connect(self.controller.update_mode_to_nothing)

        # Class selection signals.
        self.class_list.currentTextChanged.connect(self.controller.set_current_class)
        self.controller.change_color_index.connect(self.image_widget.update_current_color_index)

        # Tracker selection signals.
        self.tracker_combobox.currentTextChanged.connect(self.controller.set_tracker_name)

        # Get BBoxes.
        self.button_next.clicked.connect(self.controller.request_next)
        self.button_prev.clicked.connect(self.controller.request_prev)
        self.button_run.clicked.connect(self.controller.run_tracking)
        self.button_stop.clicked.connect(self.controller.stop_tracking)
        self.controller.request_bboxes.connect(self.image_widget.emit_rectangles)
        self.controller.request_and_init_bboxes.connect(self.image_widget.emit_rectangles_and_init)
        self.image_widget.rectangles_signal.connect(self.controller.process_rectangles)

        # Update image.
        self.controller.update_filename.connect(self.image_widget.set_image_file)

        # Update bboxes.
        self.controller.rectangles_signal.connect(self.image_widget.receive_rectangles)

        # Remove bbox.
        self.controller.remove_rectangle_signal.connect(self.image_widget.remove_rectangle_slot)
        self.image_widget.rectangle_removed_signal.connect(self.controller.remove_rectangle_slot)

        # Run button timer
        self.controller.run_timer.timeout.connect(self.controller.request_next)

        # Folder change
        self.controller.update_image_folder.connect(self.select_folder)

        # Shortcuts
        self.shortcut_next.activated.connect(self.controller.request_next)
        self.shortcut_prev.activated.connect(self.controller.request_prev)
        self.shortcut_1.activated.connect(self.class_list.set_row_1)
        self.shortcut_2.activated.connect(self.class_list.set_row_2)
        self.shortcut_3.activated.connect(self.class_list.set_row_3)
        self.shortcut_4.activated.connect(self.class_list.set_row_4)
        self.shortcut_5.activated.connect(self.class_list.set_row_5)
        self.shortcut_6.activated.connect(self.class_list.set_row_6)
        self.shortcut_7.activated.connect(self.class_list.set_row_7)
        self.shortcut_8.activated.connect(self.class_list.set_row_8)
        self.shortcut_9.activated.connect(self.class_list.set_row_9)

        # Set mode
        self.radio_track.click()
        # Set current class
        self.controller.set_current_class(self.class_list.currentItem().text())
        # Initialize first image
        self.image_widget.set_image_file(self.controller.get_current_frame())
        # Update bbox if saved
        self.controller.send_saved_bboxes()
        # Update tracker name
        self.controller.set_tracker_name(self.tracker_combobox.currentText())

    def setup_ui(self):
        main_widget = QWidget()
        self.setCentralWidget(main_widget)

        main_layout = QHBoxLayout()

        option_widget_layout = QVBoxLayout()

        option_widget_layout.addWidget(self.group_box)
        option_widget_layout.addWidget(self.tracker_groupBox)
        option_widget_layout.addWidget(self.class_groupBox)

        grid_button_layout = QGridLayout()
        grid_button_layout.addWidget(self.button_prev, 0, 0)
        grid_button_layout.addWidget(self.button_next, 0, 1)
        grid_button_layout.addWidget(self.button_run, 1, 0)
        grid_button_layout.addWidget(self.button_stop, 1, 1)
        option_widget_layout.addLayout(grid_button_layout)

        main_layout.addWidget(self.image_widget)
        main_layout.addLayout(option_widget_layout)

        self.centralWidget().setLayout(main_layout)

        # Menubar
        folder_action = QAction('Select Folder', self)
        folder_action.triggered.connect(self.controller.select_folder)
        export_action = QAction('Export', self)
        export_action.triggered.connect(self.xml_creator.export_txt_to_xml)

        menubar = self.menuBar()
        file_menu = menubar.addMenu('&File')
        file_menu.addAction(folder_action)
        file_menu.addAction(export_action)

        self.statusBar().showMessage('')

    def create_button_group(self):
        group_box = QGroupBox('Modo')
        self.radio_track.setChecked(True)
        vbox = QVBoxLayout()
        vbox.addWidget(self.radio_track)
        vbox.addWidget(self.radio_rtrack)
        vbox.addWidget(self.radio_copy)
        vbox.addWidget(self.radio_empty)
        vbox.addWidget(self.radio_nothing)
        vbox.addStretch(1)
        group_box.setLayout(vbox)
        return group_box

    def create_groupBox_from_widget(self, name, widget):
        group_box = QGroupBox(name)
        vbox = QVBoxLayout()
        vbox.addWidget(widget)
        group_box.setLayout(vbox)
        return group_box


    @pyqtSlot(str)
    def select_folder(self, folder):
        self.xml_creator.set_folder_path(folder)
Example #11
0
class Button_Node(Node):
    def __init__(self,
                 main_obg,
                 parametrs=[
                     '0', 'Вкл', '50', '50', '1', '1', '0', '1', 'выкл', '1',
                     'Кнопка', 'None', '0'
                 ]):
        super().__init__(main_obg, parametrs[10], int(parametrs[2]),
                         int(parametrs[3]))

        self.main_window_obg = main_obg

        self.index_comand = parametrs[4]
        self.first_comand = parametrs[5]  # Первая команда
        self.second_comand = parametrs[6]  # Вторая команда
        self.btn_flag = True  # Отправка первой или второй команды
        self.parametr_btn = False  # наличие второй команды
        self.btn_name = parametrs[1]
        self.two_btn_name = parametrs[8]
        self.size_big_btn = float(parametrs[7])
        self.mode = int(
            parametrs[9]
        )  # тип кнопки 1 - одна команда 2 - две попеременно 3 - две "нажал отпустил"
        self.key_state = bool(int(parametrs[12]))
        self.key_btn = int(parametrs[11]) if parametrs[11] != 'None' else None
        self.key_flag = False

        # |--------------------------------------------| обьявление виджетов
        self.big_btn = QPushButton(self.btn_name, self.main_window_obg)
        self.big_btn.clicked.connect(self.enter_comand)
        self.big_btn.pressed.connect(self.enter_comand_for_3_mode)

        self.text_set2 = QLabel(self.main_window_obg)
        self.text_set2.setText('Имя кнопки 1:')
        self.input_line2 = QLineEdit(self.btn_name, self.main_window_obg)
        self.input_line2.textChanged.connect(self.change_btn_name_1)
        self.input_line2.resize(60, 23)

        self.text_set3 = QLabel(self.main_window_obg)
        self.text_set3.setText('Индекс:')
        self.input_line3 = QLineEdit(self.index_comand, self.main_window_obg)
        self.input_line3.textChanged.connect(self.change_index)
        self.input_line3.resize(60, 23)

        self.text_set4 = QLabel(self.main_window_obg)
        self.text_set4.setText('Команда 1:')
        self.input_line4 = QLineEdit(self.first_comand, self.main_window_obg)
        self.input_line4.textChanged.connect(self.change_first_parametr)
        self.input_line4.resize(60, 23)

        self.text_set5 = QLabel(self.main_window_obg)
        self.text_set5.setText('Размер:')
        self.input_line5 = QLineEdit(str(self.size_big_btn),
                                     self.main_window_obg)
        self.input_line5.editingFinished.connect(self.change_size_big_btn)
        self.input_line5.resize(60, 23)

        self.rb_group = QButtonGroup(self.main_window_obg)
        self.rb1 = QRadioButton("Один сигнал", self.main_window_obg)
        self.rb1.move(50, 50)
        if self.mode == 1:
            self.rb1.click()
        self.rb1.clicked.connect(self.update_type)
        self.rb2 = QRadioButton("Два сигнала попеременно",
                                self.main_window_obg)
        self.rb2.move(80, 50)
        if self.mode == 2:
            self.rb2.click()
        self.rb2.clicked.connect(self.update_type)
        self.rb3 = QRadioButton('Два сигнала "нажал-отпустил"',
                                self.main_window_obg)
        self.rb3.move(120, 50)
        if self.mode == 3:
            self.rb3.click()
        self.rb3.clicked.connect(self.update_type)
        self.rb_group.addButton(self.rb1)
        self.rb_group.addButton(self.rb2)
        self.rb_group.addButton(self.rb3)

        self.text_set7 = QLabel(self.main_window_obg)
        self.text_set7.setText('Команда 2:')
        self.input_line7 = QLineEdit(self.second_comand, self.main_window_obg)
        self.input_line7.textChanged.connect(self.change_second_parametr)
        self.input_line7.resize(60, 23)

        self.text_set8 = QLabel(self.main_window_obg)
        self.text_set8.setText('Имя кнопки 2:')
        self.input_line8 = QLineEdit(self.two_btn_name, self.main_window_obg)
        self.input_line8.textChanged.connect(self.change_btn_name_2)
        self.input_line8.resize(60, 23)

        self.key_chekBox = QCheckBox('Использовать клавиши',
                                     self.main_window_obg)
        self.key_chekBox.stateChanged.connect(self.change_key_state)
        if self.key_state:
            self.key_chekBox.click()

        self.lit = QLabel(self.main_window_obg)
        if self.key_btn != None:
            self.lit.setText(chr(self.key_btn))
        #  |--------------------------------------------|
        #  Список всех виджетов нода и их относительных координат
        self.arr_of_elem.extend([(self.big_btn, 0, 21),
                                 (self.text_set2, 0, 78),
                                 (self.input_line2, 84, 76),
                                 (self.text_set3, 0, 102),
                                 (self.input_line3, 46, 100),
                                 (self.text_set4, 0, 128),
                                 (self.input_line4, 66, 125),
                                 (self.text_set5, 0, 152),
                                 (self.input_line5, 50, 150),
                                 (self.rb1, 0, 170), (self.rb2, 0, 190),
                                 (self.rb3, 0, 210), (self.text_set7, 0, 232),
                                 (self.input_line7, 66, 230),
                                 (self.text_set8, 0, 257),
                                 (self.input_line8, 84, 255),
                                 (self.key_chekBox, 0, 280),
                                 (self.lit, 0, 50)])
        #  Список всех виджетов настроек
        self.elems_of_settings = [
            self.text_set1, self.input_line1, self.text_set2, self.input_line2,
            self.input_line3, self.text_set3, self.text_set4, self.input_line4,
            self.text_set5, self.input_line5, self.rb1, self.rb2, self.rb3,
            self.text_set7, self.input_line7, self.text_set8, self.input_line8,
            self.key_chekBox, self.delete_btn, self.copy_btn
        ]
        #  Список дополнительных настроек
        self.additional_widgets = [
            self.text_set7, self.input_line7, self.text_set8, self.input_line8
        ]
        for elem in self.elems_of_settings:
            elem.hide()
        self.big_btn.resize(int(100 * self.size_big_btn),
                            int(30 * self.size_big_btn))
        self.ubdate_cord(self.x, self.y)
        self.update_type()
        for elem in self.additional_widgets:
            elem.hide()
        self.change_key_state(None, self.key_btn)

    def del_widgets(self):
        if self.delete:
            for elem in self.arr_of_elem:
                elem[0].deleteLater()
            self.delete = False

    def parametrs_return(self):
        return [
            '0', self.btn_name,
            str(self.x),
            str(self.y), self.index_comand, self.first_comand,
            self.second_comand,
            str(self.size_big_btn), self.two_btn_name,
            str(self.mode), self.name,
            str(self.key_btn),
            str(int(self.key_state))
        ]

    def enter_comand(self):
        global ser
        if self.mode == 2:
            comand = self.left_com + self.index_comand + \
                     self.middle_com + self.first_comand + self.right_com if self.btn_flag else \
                self.left_com + self.index_comand + \
                self.middle_com + self.second_comand + self.right_com
            print('2', comand)
            if self.btn_flag:
                ser.write(comand.encode())
                self.big_btn.setText(self.btn_name)
                self.btn_flag = False
            else:
                ser.write(comand.encode())
                self.big_btn.setText(self.two_btn_name)
                self.btn_flag = True
        elif self.mode == 1:
            comand = self.left_com + self.index_comand + \
                     self.middle_com + self.first_comand + self.right_com
            self.big_btn.setText(self.btn_name)
            ser.write(comand.encode())
            print(comand)
        elif self.mode == 3:
            comand = self.left_com + self.index_comand + \
                     self.middle_com + self.first_comand + self.right_com
            self.big_btn.setText(self.btn_name)
            ser.write(comand.encode())
            print(comand)

    def enter_comand_for_3_mode(self):
        global ser
        if self.mode == 3:
            comand = self.left_com + self.index_comand + \
                     self.middle_com + self.second_comand + self.right_com
            self.big_btn.setText(self.two_btn_name)
            ser.write(comand.encode())
            print(comand)

    def change_btn_name_1(self):
        self.big_btn.setText(self.input_line2.text())
        self.btn_name = self.input_line2.text()
        self.big_btn.resize(self.big_btn.sizeHint())

    def change_btn_name_2(self):
        self.two_btn_name = self.input_line8.text()

    def change_index(self):
        self.index_comand = self.input_line3.text()

    def change_parametr_btn(self):
        self.parametr_btn = not self.parametr_btn
        if self.parametr_btn:
            for elem in [self.text_set2]:
                elem.show()
        else:
            for elem in [self.text_set2]:
                elem.hide()

    def change_first_parametr(self):
        self.first_comand = self.input_line4.text()

    def change_second_parametr(self):
        self.second_comand = self.input_line7.text()

    def change_size_big_btn(self):
        self.size_big_btn = float(self.input_line5.text())
        self.big_btn.resize(int(100 * self.size_big_btn),
                            int(30 * self.size_big_btn))

    def change_key_state(self, data, key=None, released=False):
        # self.key_state = not self.key_state
        try:
            if self.key_chekBox.isChecked() and key == None:
                self.key_state = True
                self.key_flag = True
                self.key_chekBox.setText('Нажмите на клавишу')
            elif key != None and self.key_flag:
                self.key_chekBox.setText('Нажата клавиша:' + chr(key))
                self.lit.setText(chr(key))
                #self.lit.resize(self.lit.sizeHint())
                self.btn_flag = True
                self.key_btn = key
                self.key_flag = False
            elif self.key_btn == key and data != None:
                if self.mode == 3 and released:
                    self.enter_comand()
                elif self.mode == 3 and not released:
                    self.enter_comand_for_3_mode()
                elif not released:
                    self.big_btn.click()
            elif not self.key_chekBox.isChecked():
                self.key_btn = key
                self.lit.setText('')
                self.key_state = False
                self.key_chekBox.setText('Использовать клавиши')
        except Exception:
            pass

    def update_type(self):
        if self.rb1.isChecked():
            self.mode = 1
            self.big_btn.setCheckable(False)
            for elem in self.additional_widgets:
                elem.hide()
        elif self.rb2.isChecked():
            self.mode = 2
            self.big_btn.setCheckable(True)
            for elem in self.additional_widgets:
                elem.show()
        elif self.rb3.isChecked():
            self.mode = 3
            self.big_btn.setCheckable(False)
            for elem in self.additional_widgets:
                elem.show()

    def open_setings(self):
        if self.flag:
            self.settings_btn.setText('▼')
            self.flag = False
            for elem in self.elems_of_settings:
                elem.show()
            if self.mode == 1:
                for elem in self.additional_widgets:
                    elem.hide()
            self.big_btn.resize(100, 30)
            self.lit.hide()
        else:
            self.settings_btn.setText('▲')
            self.flag = True
            for elem in self.elems_of_settings:
                elem.hide()
            self.big_btn.resize(int(100 * self.size_big_btn),
                                int(30 * self.size_big_btn))
            self.lit.show()

    def is_keyword(self):
        return True if self.key_state else False
Example #12
0
class ReferenceClock(QWidget):
    """Race Info Setup

    This widget allows the user to name the race, and jot down various notes about the race.
    """

    REFERENCE_CLOCK_POINT_SIZE = 24

    def __init__(self, modeldb, parent=None):
        """Initialize the ReferenceClock instance."""
        super().__init__(parent=parent)

        self.modeldb = modeldb

        # Cache this. We use it so often.
        self.race_table_model = self.modeldb.race_table_model

        # Time selection/synchronization modal window, shown when synchronize_button is clicked.
        self.time_synchronizer = TimeSynchronizer()
        self.time_synchronizer.setWindowModality(Qt.ApplicationModal)

        # There are some widgets we want to access outside of initialization, so we save them off
        # into "self". However, pylint is getting confused and thinks some of them are possibly
        # never initialized. Therefore, initialize every widget that we want to save to "None" here.
        # (Initialization will take care of giving them proper values after this.)
        self.reference_clock_radiobutton = None
        self.reference_datetime_label = None
        self.datetime_datetimeedit = None

        # Initialize our whole hierarchical mess of widgets.
        self.init_clock_selection_widget()

        # Force update widget contents.
        self.dataChanged(QModelIndex(), QModelIndex(), [Qt.DisplayRole])

        # Signals/slots plumbing.
        self.race_table_model.dataChanged.connect(self.dataChanged)

    def init_clock_selection_widget(self):
        """Initialize the clock selection stuff.

        This method initializes the clock selection radio buttons, and triggers the initialization
        of the reference clock selection stage.

        There are two choices at this level: wall clock and reference clocks.
        """
        # Clock selection (wall clock vs reference clock).
        clock_selection_widget = QGroupBox('Use clock:')

        # Chooser radio buttons and the button group.
        wall_clock_radiobutton = QRadioButton('Wall clock')
        self.reference_clock_radiobutton = QRadioButton('Reference clock')
        clock_source_button_group = QButtonGroup()
        clock_source_button_group.addButton(wall_clock_radiobutton)
        clock_source_button_group.addButton(self.reference_clock_radiobutton)
        clock_selection_widget.setLayout(QHBoxLayout())
        clock_selection_widget.layout().addWidget(wall_clock_radiobutton)
        clock_selection_widget.layout().addWidget(self.reference_clock_radiobutton)

        # The latter choice, that expands to more choices.
        reference_clock_setup_widget = self.init_reference_clock_setup_widget()

        # Top-level widgets.
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(clock_selection_widget)
        self.layout().addWidget(reference_clock_setup_widget)

        # Signals/slots plumbing.
        self.reference_clock_radiobutton.toggled.connect(reference_clock_setup_widget.setEnabled)
        self.reference_clock_radiobutton.toggled.connect(self.toggle_reference_clock_setup)

        # Set default state.
        wall_clock_radiobutton.click()
        reference_clock_setup_widget.setEnabled(False)

    def init_reference_clock_setup_widget(self):
        """Initialize the reference clock selection stuff.

        This method initializes the reference clock selection radio buttons, and triggers the
        initialization of the manual reference clock setup stage.

        There are two choices at this level: synchronize and manual setup.
        """
        # Reference clock selection (synchronize vs manual setup).
        reference_clock_selection_widget = QGroupBox('Reference clock setup:')

        # Big text label showing the currently set up reference clock.
        self.reference_datetime_label = QLabel('PLACEHOLDER')
        self.reference_datetime_label.setAlignment(Qt.AlignCenter)
        font = self.reference_datetime_label.font()
        font.setPointSize(self.REFERENCE_CLOCK_POINT_SIZE)
        self.reference_datetime_label.setFont(font)

        # Chooser radio buttons and the button group.
        synchronize_radiobutton = QRadioButton('Synchronize')
        synchronize_radiobutton.setChecked(True)
        synchronize_button = QPushButton('Synchronize')
        manual_setup_radiobutton = QRadioButton('Manual setup')
        reference_clock_setup_button_group = QButtonGroup()
        reference_clock_setup_button_group.addButton(synchronize_radiobutton)
        reference_clock_setup_button_group.addButton(manual_setup_radiobutton)
        reference_clock_selection_row_widget = QWidget()
        reference_clock_selection_row_widget.setLayout(QHBoxLayout())
        reference_clock_selection_row_widget.layout().addWidget(synchronize_radiobutton)
        reference_clock_selection_row_widget.layout().addWidget(synchronize_button)
        reference_clock_selection_row_widget.layout().addWidget(manual_setup_radiobutton)

        reference_clock_selection_widget.setLayout(QVBoxLayout())
        reference_clock_selection_widget.layout().addWidget(self.reference_datetime_label)
        reference_clock_selection_widget.layout().addWidget(reference_clock_selection_row_widget)

        # The latter choice, that expands to more choices.
        reference_clock_manual_setup_widget = self.init_reference_clock_manual_setup_widget()

        # Top-level widgets.
        reference_clock_setup_widget = QWidget()
        reference_clock_setup_widget.setLayout(QVBoxLayout())
        reference_clock_setup_widget.layout().addWidget(reference_clock_selection_widget)
        reference_clock_setup_widget.layout().addWidget(reference_clock_manual_setup_widget)

        # Signals/slots plumbing.
        synchronize_radiobutton.toggled.connect(synchronize_button.setEnabled)
        manual_setup_radiobutton.toggled.connect(reference_clock_manual_setup_widget.setEnabled)
        synchronize_button.clicked.connect(self.time_synchronizer.show)
        self.time_synchronizer.clicked.connect(self.handle_time_synchronizer_done)

        # Set default state.
        synchronize_radiobutton.click()
        reference_clock_manual_setup_widget.setEnabled(False)

        return reference_clock_setup_widget

    def init_reference_clock_manual_setup_widget(self):
        """Initialize the manual reference clock setup stuff.

        This method initializes the manual reference clock setup stuff.
        """
        # Reference clock manual setup widget.
        reference_clock_maual_selection_widget = QGroupBox('Reference clock manual setup:')

        self.datetime_datetimeedit = QDateTimeEdit()
        self.datetime_datetimeedit.setDisplayFormat('yyyy-MM-dd @ h:mm:ss.zzz')
        self.datetime_datetimeedit.setCalendarPopup(True)
        date_today_button = QPushButton('Today')

        date_selection_widget = QWidget()
        date_selection_widget.setLayout(QHBoxLayout())
        date_selection_widget.layout().addWidget(self.datetime_datetimeedit)
        date_selection_widget.layout().addWidget(date_today_button)

        set_reference_clock_button = QPushButton('Set Reference Clock')

        # Top-level widgets.
        reference_clock_maual_selection_widget.setLayout(QVBoxLayout())
        reference_clock_maual_selection_widget.layout().addWidget(date_selection_widget)
        reference_clock_maual_selection_widget.layout().addWidget(set_reference_clock_button)

        # Signals/slots plumbing.
        date_today_button.clicked.connect(
            lambda: self.datetime_datetimeedit.setDateTime(QDateTime(QDate.currentDate())))
        set_reference_clock_button.clicked.connect(self.handle_manual_reference_clock_setup_done)

        return reference_clock_maual_selection_widget

    def dataChanged(self, top_left, bottom_right, roles): #pylint: disable=invalid-name
        """Respond to a RaceTableModel data change by updating input widgets with current values."""
        del top_left, bottom_right, roles

        if self.race_table_model.reference_clock_is_enabled():
            self.reference_clock_radiobutton.click()

        # If there's a reference datetime set up, populate the controls with it.
        if self.race_table_model.reference_clock_has_datetime():
            reference_datetime = self.race_table_model.get_reference_clock_datetime()

            # Make our own combined string, because I haven't found a QDateTime format that I like.
            # Guess I'll keep looking...this looks really hokey.
            datetime_string = reference_datetime.toString(defaults.REFERENCE_CLOCK_DATETIME_FORMAT)

            self.reference_datetime_label.setText(datetime_string)
        else: # Otherwise, just use the race day's date, time zero.
            reference_datetime = QDateTime(QDate.currentDate())

            self.reference_datetime_label.setText('Reference clock not set up')

        self.datetime_datetimeedit.setDateTime(reference_datetime)

    def toggle_reference_clock_setup(self, enable):
        """Toggle reference clock enable/disable.

        Not relevant if there is no reference clock datetime set up.
        """
        if not self.race_table_model.reference_clock_has_datetime():
            return

        old_reference_datetime = self.race_table_model.get_reference_clock_datetime()

        if enable:
            self.race_table_model.enable_reference_clock()
        else:
            self.race_table_model.disable_reference_clock()

        new_reference_datetime = self.race_table_model.get_reference_clock_datetime()
        self.change_reference_datetime(old_reference_datetime, new_reference_datetime)

    def handle_time_synchronizer_done(self, time):
        """Commit the time selection to the model."""
        self.time_synchronizer.hide()

        # When synchronizing, use the current date as the date.
        date = QDate.currentDate()

        old_reference_datetime = self.race_table_model.get_reference_clock_datetime()

        self.race_table_model.set_reference_clock_datetime(QDateTime(date, time))
        self.race_table_model.enable_reference_clock()

        new_reference_datetime = self.race_table_model.get_reference_clock_datetime()
        self.change_reference_datetime(old_reference_datetime, new_reference_datetime)

    def handle_manual_reference_clock_setup_done(self):
        """Commit the reference datetime in the database."""
        old_reference_datetime = self.race_table_model.get_reference_clock_datetime()

        self.race_table_model.set_reference_clock_datetime(self.datetime_datetimeedit.dateTime())
        self.race_table_model.enable_reference_clock()

        new_reference_datetime = self.race_table_model.get_reference_clock_datetime()
        self.change_reference_datetime(old_reference_datetime, new_reference_datetime)

    def change_reference_datetime(self, old_datetime, new_datetime):
        """Applies the new datetime as the reference datetime.

        Note that we also need the old datetime in order to adjust all existing time deltas to
        the new datetime.
        """
        if old_datetime == new_datetime:
            return

        self.race_table_model.change_reference_clock_datetime(old_datetime, new_datetime)
Example #13
0
class Palette(QLabel):
    recolor_signal = pyqtSignal(object, object)

    def __init__(self, parent, main):
        QLabel.__init__(self)
        self.parent = parent
        self.main = main
        self.all_values = {}
        pixmap = QPixmap('images/red-blue.png')
        self.setPixmap(pixmap)

        self.settings_widget = QWidget(flags=Qt.WindowStaysOnTopHint)
        self.settings_widget.setWindowIcon(QIcon('images/logo.ico'))
        self.settings_widget.setFixedSize(350, 150)
        self.min = None
        self.max = None
        self.settings_widget.setWindowTitle(_('Palette settings'))
        self.layout = QGridLayout(self.settings_widget)
        self.auto_radiobtn = QRadioButton(
            _('Auto palette for all visible tracks'))
        self.auto_state = True
        self.fixed_radiobtn = QRadioButton(
            _('Fixed palette for all visible tracks'))
        self.max_label = QLabel(_('Max'))
        self.min_label = QLabel(_('Min'))
        self.max_value = QLineEdit()
        self.min_value = QLineEdit()
        self.update_border_btn = QPushButton(_('Update'))
        self.line = QFrame()
        self.line.setFrameShape(QFrame.HLine)

        self.auto_label = QLabel(_('Auto'))
        self.all_visible_label = QLabel(_('(all visible)'))

        self.ok_btn = QPushButton('Ok')
        self.cancel_btn = QPushButton(_('Cancel'))
        self.apply_btn = QPushButton(_('Apply'))

        self.layout.addWidget(self.auto_radiobtn, 0, 0, 1, 4)
        self.layout.addWidget(self.fixed_radiobtn, 1, 0, 1, 4)
        self.layout.addWidget(self.min_label, 2, 0, 1, 1)
        self.layout.addWidget(self.min_value, 2, 1, 1, 1)
        self.layout.addWidget(self.max_label, 2, 2, 1, 1)
        self.layout.addWidget(self.max_value, 2, 3, 1, 1)
        self.layout.addWidget(self.update_border_btn, 2, 4, 1, 1)
        self.layout.addWidget(self.ok_btn, 3, 1, 1, 2, alignment=Qt.AlignRight)
        self.layout.addWidget(self.cancel_btn, 3, 3, 1, 1)
        self.layout.addWidget(self.apply_btn, 3, 4, 1, 1)

        self.min_value.textChanged.connect(
            lambda val: self.min_value_changed(val))
        self.max_value.textChanged.connect(
            lambda val: self.max_value_changed(val))
        self.update_border_btn.clicked.connect(lambda: self.define_borders())
        self.auto_radiobtn.clicked.connect(lambda: self.auto_state_changed(1))
        self.fixed_radiobtn.clicked.connect(lambda: self.auto_state_changed(0))
        self.auto_radiobtn.click()
        self.ok_btn.clicked.connect(lambda: self.ok_clicked())
        self.cancel_btn.clicked.connect(lambda: self.cancel_clicked())
        self.apply_btn.clicked.connect(lambda: self.apply_clicked())
        self.main.signal_language_changed.connect(lambda: self.retranslate())

    def retranslate(self):
        self.settings_widget.setWindowTitle(_('Palette settings'))
        self.max_label.setText(_('Max'))
        self.min_label.setText(_('Min'))
        self.update_border_btn.setText(_('Update'))
        self.auto_label.setText(_('Auto'))
        self.all_visible_label.setText(_('(all visible)'))
        self.ok_btn.setText('Ok')
        self.cancel_btn.setText(_('Cancel'))
        self.apply_btn.setText(_('Apply'))

    def set_values(self, arr=None, min=None, max=None):
        if arr is None:
            arr = np.array(())
            for value in self.all_values.values():
                arr = np.hstack((arr, value))

        if len(arr) == 0:
            for i in range(6):
                grad_tic = QLabel('')
                grad_tic.setStyleSheet(
                    'QLabel { background-color : rgb(127, 127, 127); color: white}'
                )
                self.parent.layout.addWidget(grad_tic, i + 1, 1, 1, 1)
            return

        if not min and not max:
            gradient_tick_lst = [
                np.percentile(arr, 100),
                np.percentile(arr, 80),
                np.percentile(arr, 60),
                np.percentile(arr, 40),
                np.percentile(arr, 20),
                np.percentile(arr, 0)
            ]

            self.min = np.amin(arr)
            self.max = np.amax(arr)
        else:
            gradient_tick_lst = np.ogrid[max:min:6j]
            self.min = min
            self.max = max

        for i, g in enumerate(gradient_tick_lst):
            grad_tic = QLabel('{}'.format(int(g)))
            if i == 0:
                grad_tic.setAlignment(Qt.AlignTop)
            elif i == 5:
                grad_tic.setAlignment(Qt.AlignBottom)

            grad_tic.setStyleSheet(
                'QLabel { background-color : rgb(127, 127, 127); color: white}'
            )
            self.parent.layout.addWidget(grad_tic, i + 1, 1, 1, 1)

    def mouseDoubleClickEvent(self, event):
        if self.parent.three_d_plot.cut_widget.isVisible():
            self.parent.three_d_plot.cut_widget.activateWindow()
            return
        pos = event.globalPos()
        self.settings_widget.setGeometry(pos.x(), pos.y(), 300, 150)
        self.settings_widget.show()

    def min_value_changed(self, val):
        try:
            self.min = float(val.replace(',', '.'))
        except ValueError:
            pass

    def max_value_changed(self, val):
        try:
            self.max = float(val.replace(',', '.'))
        except ValueError:
            pass

    def define_borders(self):
        arr = np.array(())
        for value in self.all_values.values():
            arr = np.hstack((arr, value))

        if len(arr) == 0:
            show_info(_('Border info'), _('No borders'))
            return
        self.min_value.setText(str(int(np.amin(arr))))
        self.max_value.setText(str(int(np.amax(arr)) + 1))
        self.min = np.amin(arr)
        self.max = np.amax(arr)

    def auto_state_changed(self, id):
        if id == 1:
            self.max_label.setEnabled(False)
            self.min_label.setEnabled(False)
            self.max_value.setEnabled(False)
            self.min_value.setEnabled(False)
            self.update_border_btn.setEnabled(False)
        else:
            self.max_label.setEnabled(True)
            self.min_label.setEnabled(True)
            self.max_value.setEnabled(True)
            self.min_value.setEnabled(True)
            self.update_border_btn.setEnabled(True)

    def ok_clicked(self):
        self.apply_clicked()
        self.settings_widget.close()

    def cancel_clicked(self):
        if self.auto_state:
            self.auto_radiobtn.click()
        else:
            self.fixed_radiobtn.click()
        self.settings_widget.close()

    def apply_clicked(self):
        self.auto_state = True if self.auto_radiobtn.isChecked() else False
        if self.auto_state:
            self.set_values()
            self.recolor_signal.emit(self.min, self.max)
        else:
            if len(self.min_value.text()) == 0 or len(
                    self.max_value.text()) == 0:
                show_error(_('Border error'),
                           _('Please fill Max, Min values or\nchoose Auto.'))
                return
            if float(self.min_value.text()) > float(self.max_value.text()):
                show_error(_('Border error'), _('Max must be more than Min'))
                return
            self.set_values(min=float(self.min_value.text()),
                            max=float(self.max_value.text()))
            self.recolor_signal.emit(self.min, self.max)
Example #14
0
 def _select(self, radio_button: W.QRadioButton):
     radio_button.click()
Example #15
0
class Slider_Node(Node):
    def __init__(
            self,
            main_obg,
            parametrs=['1', 'Слайдер', '50', '50', '10', 1, 1, '', '0',
                       '100']):
        super().__init__(main_obg, parametrs[1], int(parametrs[2]),
                         int(parametrs[3]))

        self.index_comand = parametrs[4]
        self.size_slider = float(parametrs[5])
        self.mode = int(parametrs[6])  # тип слайдера
        self.value_sld = 0
        self.binding = int(parametrs[7]) if parametrs[7] != '' else ''
        self.min = int(parametrs[8])
        self.max = int(parametrs[9])

        # |--------------------------------------------| обьявление виджетов
        self.sld = QSlider(Qt.Horizontal, self.main_window_obg)
        self.sld.setFocusPolicy(Qt.NoFocus)
        self.sld.setGeometry(30, 40, 100, 30)
        self.sld.valueChanged[int].connect(self.changeValue)
        self.sld.sliderReleased.connect(self.enter_comand)
        self.sld.setMinimum(self.min)
        self.sld.setMaximum(self.max)
        self.sld.resize(int(100 * self.size_slider), 30)

        self.text_set2 = QLabel(self.main_window_obg)
        self.text_set2.setText('None')

        self.text_set3 = QLabel(self.main_window_obg)
        self.text_set3.setText('Индекс:')
        self.input_line3 = QLineEdit(self.index_comand, self.main_window_obg)
        self.input_line3.textChanged.connect(self.change_index)
        self.input_line3.resize(60, 23)

        self.text_set5 = QLabel(self.main_window_obg)
        self.text_set5.setText('Размер:')
        self.input_line5 = QLineEdit(str(self.size_slider),
                                     self.main_window_obg)
        self.input_line5.editingFinished.connect(self.change_size_sld)
        self.input_line5.resize(60, 23)

        self.text_set4 = QLabel(self.main_window_obg)
        self.text_set4.setText('Минимум:')
        self.input_line4 = QLineEdit(str(self.min), self.main_window_obg)
        self.input_line4.textChanged.connect(self.change_minimum)
        self.input_line4.resize(60, 23)

        self.text_set6 = QLabel(self.main_window_obg)
        self.text_set6.setText('Максимум:')
        self.input_line6 = QLineEdit(str(self.max), self.main_window_obg)
        self.input_line6.textChanged.connect(self.change_maximum)
        self.input_line6.resize(60, 23)

        self.text_set7 = QLabel(self.main_window_obg)
        self.text_set7.setText('Привязка:')
        self.input_line7 = QLineEdit(str(self.binding), self.main_window_obg)
        self.input_line7.textChanged.connect(self.change_binding)
        self.input_line7.resize(60, 23)

        self.rb_group = QButtonGroup(self.main_window_obg)
        self.rb1 = QRadioButton("Отправка при отпуске", self.main_window_obg)
        self.rb1.move(50, 50)
        if self.mode == 1:
            self.rb1.click()
        self.rb1.clicked.connect(self.update_type)
        self.rb2 = QRadioButton("Отправка при изменении", self.main_window_obg)
        self.rb2.move(80, 50)
        if self.mode == 2:
            self.rb2.click()
        self.rb2.clicked.connect(self.update_type)
        self.rb_group.addButton(self.rb1)
        self.rb_group.addButton(self.rb2)

        #  |--------------------------------------------|
        #  Список всех виджетов нода и их относительных координат
        self.arr_of_elem.extend([(self.text_set2, 0, 50), (self.sld, 0, 21),
                                 (self.text_set3, 0, 76),
                                 (self.input_line3, 46, 75),
                                 (self.text_set4, 0, 102),
                                 (self.input_line4, 63, 100),
                                 (self.text_set6, 0, 127),
                                 (self.input_line6, 63, 125),
                                 (self.text_set5, 0, 152),
                                 (self.input_line5, 50, 150),
                                 (self.text_set7, 0, 177),
                                 (self.input_line7, 63, 175),
                                 (self.rb1, 0, 195), (self.rb2, 0, 215)])
        #  Список всех виджетов настроек
        self.elems_of_settings = [
            self.text_set1, self.input_line1, self.input_line3, self.text_set3,
            self.text_set5, self.input_line5, self.rb1, self.rb2,
            self.text_set4, self.text_set6, self.input_line4, self.input_line6,
            self.text_set7, self.input_line7, self.delete_btn, self.copy_btn
        ]
        #  Список дополнительных настроек
        for elem in self.elems_of_settings:
            elem.hide()
        # self.big_btn.resize(int(100 * self.size_big_btn), int(30 * self.size_big_btn))
        self.ubdate_cord(self.x, self.y)

    def del_widgets(self):
        if self.delete:
            for elem in self.arr_of_elem:
                elem[0].deleteLater()
            self.delete = False

    def parametrs_return(self):
        return [
            '1', self.name,
            str(self.x),
            str(self.y), self.index_comand,
            str(self.size_slider),
            str(self.mode),
            str(self.binding),
            str(self.min),
            str(self.max)
        ]

    def enter_comand(self):
        if self.mode == 1:
            global ser
            comand = self.left_com + self.index_comand + \
                     self.middle_com + str(self.value_sld) + self.right_com
            ser.write(comand.encode())
        if self.binding != '':
            try:
                self.sld.setValue(int(self.binding))
                comand = self.left_com + self.index_comand + \
                         self.middle_com + str(self.value_sld) + self.right_com
                ser.write(comand.encode())
            except ValueError:
                pass

    def change_index(self):
        self.index_comand = self.input_line3.text()

    def change_size_sld(self):
        try:
            self.size_slider = float(self.input_line5.text())
            self.sld.resize(int(100 * self.size_slider), 30)
        except ValueError:
            pass

    def change_binding(self):
        self.binding = self.input_line7.text()

    def changeValue(self, value='X_X'):
        global ser
        self.value_sld = value
        self.text_set2.setText(str(value))
        self.text_set2.resize(self.text_set2.sizeHint())
        if self.mode == 2:
            comand = self.left_com + self.index_comand + \
                     self.middle_com + str(self.value_sld) + self.right_com
            ser.write(comand.encode())

    def change_maximum(self):
        try:
            self.max = int(self.input_line6.text())
            self.sld.setMaximum(self.max)
        except ValueError:
            pass

    def change_minimum(self):
        try:
            self.min = int(self.input_line6.text())
            self.sld.setMinimum(self.min)
        except ValueError:
            pass

    def update_type(self):
        if self.rb1.isChecked():
            self.mode = 1
        elif self.rb2.isChecked():
            self.mode = 2

    def open_setings(self):
        if self.flag:
            self.settings_btn.setText('▼')
            self.flag = False
            for elem in self.elems_of_settings:
                elem.show()
            self.text_set2.hide()
        else:
            self.settings_btn.setText('▲')
            self.flag = True
            for elem in self.elems_of_settings:
                elem.hide()
            self.text_set2.show()

    def is_keyword(self):
        return False
Example #16
0
class MyWindow(QWidget):

	def __init__(self):

		super().__init__()

		Fixed = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
		#...
		self.updateButton = QPushButton('Set')
		self.updateButton.clicked.connect(self.OnUpdate)	#Связываем сигнал со слотом;
		self.updateButton.setEnabled(False)
		#...
		self.insertButton = QPushButton('Add')
		self.insertButton.clicked.connect(self.OnInsert)
		#...
		self.deleteButton = QPushButton('Del')
		self.deleteButton.clicked.connect(self.OnDelete)
		#...
		self.spinRowID = QSpinBox()
		self.spinRowID.lineEdit().setReadOnly(True)
		self.spinRowID.valueChanged.connect(self.OnRowChanged)
		self.spinRowID.setSizePolicy(Fixed)
		#...
		self.editName = QLineEdit()
		#...
		self.vbox = QVBoxLayout()
		self.is_female = QRadioButton('FEMALE');
		self.is_male = QRadioButton('MALE');
		self.is_male.click()
		self.vbox.addWidget(self.is_female)
		self.vbox.addWidget(self.is_male)
		self.vbox.setDirection(QVBoxLayout.LeftToRight) #Задаем направление компоновки;
		self.chckSex = QGroupBox()
		self.chckSex.setLayout(self.vbox)
		#...
		self.listAge = QComboBox()
		self.listAge.setSizePolicy(Fixed) #Устанавливаем фиксированный размер виджета;
		for i in range(16, 31): self.listAge.addItem(str(i), i)
		#...
		self.editCity = QLineEdit()
		#...
		self.view = View(self)
		self.view.clicked.connect(self.OnViewClicked)
		self.view.sortByColumn(0, Qt.AscendingOrder)

		#Используем компоновщики для позиционирования виджетов:
		self.lay2 = QGridLayout()
		self.lay2.addWidget(self.updateButton, 0, 0)
		self.lay2.addWidget(self.insertButton, 1, 0)
		self.lay2.addWidget(self.deleteButton, 2, 0)
		self.lay2.addWidget(self.spinRowID, 0, 1)
		self.lay2.addWidget(self.editName, 0, 2)
		self.lay2.addWidget(self.listAge, 0, 3)
		self.lay2.addWidget(self.chckSex, 0, 4)
		self.lay2.addWidget(self.editCity, 0, 5)
		#...
		self.lay1 = QGridLayout(self)
		self.lay1.addLayout(self.lay2, 0, 0)
		self.lay1.addWidget(self.view, 1, 0)

		self.setGeometry(0, 0, 800, 500)
		self.setWindowTitle('Test Application')
		self.show()

	def update(self):
		temp = self.view.getDataByID(self.spinRowID.value())
		if not temp:
			self.updateButton.setEnabled(False)
			return
		self.updateButton.setEnabled(True)
		self.editName.setText(temp[1])
		if temp[2] == 'F':
			self.is_female.click()
		else:
			self.is_male.click()
		self.listAge.setCurrentText(str(temp[3]))
		self.editCity.setText(temp[4])
		self.repaint()

	def record(self):
		rec = [self.editName.text()]
		rec.append(1 if self.is_male.isChecked() else 0)
		rec.append(int(self.listAge.currentText()))
		rec.append(self.editCity.text())
		return tuple(rec)

	def OnViewClicked(self, index):
		temp = self.view.getRowData(index.row())
		self.spinRowID.setValue(temp[0])

	def OnRowChanged(self, rowid):
		self.update()

	def OnUpdate(self):
		rec = self.record()
		self.view.updateRow(self.spinRowID.value(), rec)
		self.update()

	def OnInsert(self):
		rec = self.record()
		self.view.insertRow(rec)
		self.update()

	def OnDelete(self):
		self.view.removeRow(self.spinRowID.value())
		self.update()
Example #17
0
class ConfigTab(TraceDocks):
    
    ## The constructor
    #  initialize the super-class, assign a name and first configItems       
    def __init__(self,parent):
        super(ConfigTab, self).__init__(parent,'ConfigTab')
        self.tabName = 'ConfigTab'
        self.logger.logEvent('Creating Tab now: '+ self.tabName)
        
        # Set a couple of default-values, in case the configParser does not work
        self.snifferConfig.configBaud = 1000000
        self.snifferConfig.configCom = 'COM4'
        self.snifferConfig.configMode = 'Singleshot'
        self.snifferConfig.configParity = 'None'
        self.snifferConfig.configStopBits = 0
        self.snifferConfig.configTimeBytes = 2
        self.snifferConfig.configTrigger = 'Start'
        self.snifferConfig.configLogCheck = 0
        self.snifferConfig.configIncTimeCheck = 0
        self.snifferConfig.configTickToMsLine = 1000
        self.snifferConfig.configSingleDurLine = 3000
        self.snifferConfig.configMaxTickCountVal = 65536
        self.snifferConfig.configUpDownState = 'Up'
        self.snifferConfig.configCurrentTheme = 'Dark'
                
        # By parsing the config now, we assure that we re-load everything
        # the way we left it
        self.snifferConfig.parseConfigFromFile()
        
        # Create necessary Lists
        self.COMList = OsSniffer.OS_SerialPortList()
        self.BAUDList = ['110','300','600','1200','2400','4800','9600','14400','19200','38400','57600','115200','128000','256000','921600','1000000','2000000']
        self.STOPList = ['0','1','2']
        self.PARITYList = ['None','Even','Odd']
        self.MODEList = ['Singleshot','Continuous','Trigger']
        self.TRIGGERList = []
        for triggers in Globals.tspDict.items():
            self.TRIGGERList.append(triggers[1][0])
            
        self.INACTIVEList = ['INACTIVE']
        # We need a list for the items and one for the actual Values
        
        
    ## Create the visible UI            
    def setConfigTabLayout(self):
        
        # Create Configurations Tab --------------------###    
        # Create Layouts
        self.Vlayout = QVBoxLayout()
        self.H1layout = QHBoxLayout()
        self.H1layout.setSpacing(10)
        self.H1SubV1Layout = QVBoxLayout()
        self.H1SubV1H1Layout = QHBoxLayout()
        self.H1SubV1H2Layout = QHBoxLayout()
        self.H1SubV1H3Layout = QHBoxLayout()
        self.H1SubV1H4Layout = QHBoxLayout()
        self.H1SubV1H5Layout = QHBoxLayout()
        self.H1SubV2Layout = QVBoxLayout()
        self.H1SubV2H1Layout = QHBoxLayout()
        self.H1SubV2H2Layout = QHBoxLayout()
        self.H1SubV2H3Layout = QHBoxLayout()
        self.H1SubV2H4Layout = QHBoxLayout()
        self.H1SubV2H5Layout = QHBoxLayout()
        self.H1SubV2H6Layout = QHBoxLayout()
        self.H1SubV2H7Layout = QHBoxLayout()
        self.H1SubV2H8Layout = QHBoxLayout()
            
        #------------------------------------
        
        # Create Widgets TextBox
        #------------------------------------
        
        # First Buttons
        self.saveLogButt = QPushButton('Save Logfile')
        self.saveConfigButt = QPushButton('Save Configuration')
        self.toggleThemeButt = QPushButton('Toggle Theme')
        self.refreshComButt = QPushButton('Refresh COM')
        
        # Then Checkbox and Comboboxes
        self.saveLogCheck = QCheckBox('Activate Logging')
        self.saveIncTimeCheck = QCheckBox('Save Inc_Tick Data')
        
        self.labelSerial = QLabel('Serial Configuration')
        self.labelCOM = QLabel('COM-PORT')
        self.labelBAUD = QLabel('BAUD-RATE')
        self.labelSTOP= QLabel('STOP-BITS')
        self.labelPARITY= QLabel('PARITY')
        self.labelMeasure = QLabel('Measurement Configuration')
        self.labelMODE = QLabel('MEASUREMENT MODE')
        self.labelSINGLETIME = QLabel('MEASUREMENT TIME')
        self.labelTRIGGER = QLabel('TRIGGER TYPE')
        self.labelRATIO = QLabel('TICK TO MS RATIO')
        self.labelMaxTickCount = QLabel('MAX TICKOUT VAL')
        self.labelUpDownCount = QLabel('SELECT UP OR DOWN COUNTER')
        
        self.inputSingleDurBox = QLineEdit()
        self.inputSingleDurBox.setText('Duration(ticks)')
        #self.inputSingleDurBox.setMaximumWidth(20)
        
        self.inputTickToMsBox = QLineEdit()
        self.inputTickToMsBox.setText('Set Ticks to Ms Ratio')
        #self.inputTickToMsBox.setMaximumWidth(200)

        self.inputMaxTickCount = QLineEdit()
        self.inputMaxTickCount.setText('Set Maximum Tickcount Val')
        
        self.comboMODE = QComboBox()
        self.comboMODE.addItems(self.MODEList)  
        self.comboCOM = QComboBox()
        self.comboCOM.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self.comboCOM.addItems(self.COMList)   
        self.comboBAUD = QComboBox()
        self.comboBAUD.addItems(self.BAUDList)
        self.comboBAUD.setEditable(True)
        self.comboSTOP = QComboBox()
        self.comboSTOP.addItems(self.STOPList)    
        self.comboPARITY = QComboBox()
        self.comboPARITY.addItems(self.PARITYList)      
        self.comboTRIGGER = QComboBox()
        self.comboTRIGGER.addItems(self.TRIGGERList)     

        self.upCountRadio = QRadioButton('Up',self)
        self.downCountRadio = QRadioButton('Down', self)
        
        # We need to sync the UI before connecting any slots in order to prevent accidental stateChanges.
        self.syncUiToConfig() 
        
        #--- SIGNAL/SLOT CONNECTIONS ---#
        # Button Signal/Slot connections
        self.saveLogButt.clicked.connect(self.saveLog)
        for keys, values in dockDict.items(): # We need to connect EVERY tab in order to save the ConfigurationData
            self.saveConfigButt.clicked.connect(values.snifferConfig.saveConfigToFile)  
        self.saveConfigButt.clicked.connect(self.snifferConfig.saveConfigToFile)
        self.toggleThemeButt.clicked.connect(self.toggleTheme)
        self.refreshComButt.clicked.connect(self.refreshCom)
        
        # Checkbox Signal/Slot connections
        self.saveLogCheck.stateChanged.connect(self.checkSaveLogChanged)
        self.saveIncTimeCheck.stateChanged.connect(self.checkSaveInctimeChanged)
        
        # Lineedit Signal/Slot connections
        self.inputSingleDurBox.textChanged.connect(self.lineSingleDurChanged)
        self.inputTickToMsBox.textChanged.connect(self.lineTickToMsChanged)
        self.inputMaxTickCount.textChanged.connect(self.lineMaxTickCountChanged)
        
        # Combobox Signal/Slot connections
        self.comboMODE.currentIndexChanged[int].connect(self.comboModeChanged)     
        self.comboCOM.currentIndexChanged[int].connect(self.comboComChanged)
        self.comboBAUD.currentIndexChanged[int].connect(self.comboBaudChanged) 
        self.comboBAUD.currentTextChanged.connect(self.comboBaudChanged)
        self.comboSTOP.currentIndexChanged[int].connect(self.comboStopBitsChanged)
        self.comboPARITY.currentIndexChanged[int].connect(self.comboParityChanged) 
        self.comboTRIGGER.currentIndexChanged[int].connect(self.comboTriggerChanged)

        # Radio button connections
        self.upCountRadio.clicked.connect(self.upCountRadioSelected)
        self.downCountRadio.clicked.connect(self.downCountRadioSelected)
                
        # Add the Widgets to the corresponding Layouts
        self.H1SubV1H1Layout.addWidget(self.labelCOM)
        self.H1SubV1H1Layout.addWidget(self.refreshComButt)
        self.H1SubV1H1Layout.addWidget(self.comboCOM)
        self.H1SubV1H2Layout.addWidget(self.labelBAUD)
        self.H1SubV1H2Layout.addWidget(self.comboBAUD)
        self.H1SubV1H3Layout.addWidget(self.labelSTOP)
        self.H1SubV1H3Layout.addWidget(self.comboSTOP)
        self.H1SubV1H4Layout.addWidget(self.labelPARITY)
        self.H1SubV1H4Layout.addWidget(self.comboPARITY)
        
        self.H1SubV1Layout.addWidget(self.labelSerial)
        self.H1SubV1Layout.addLayout(self.H1SubV1H1Layout)
        self.H1SubV1Layout.addLayout(self.H1SubV1H2Layout)
        self.H1SubV1Layout.addLayout(self.H1SubV1H3Layout)
        self.H1SubV1Layout.addLayout(self.H1SubV1H4Layout)
        self.H1SubV1Layout.addStretch()
        
        self.H1SubV2H1Layout.addWidget(self.labelMODE)
        self.H1SubV2H1Layout.addWidget(self.comboMODE)
        self.H1SubV2H2Layout.addWidget(self.labelSINGLETIME)
        self.H1SubV2H2Layout.addWidget(self.inputSingleDurBox)
        self.H1SubV2H3Layout.addWidget(self.labelTRIGGER)
        self.H1SubV2H3Layout.addWidget(self.comboTRIGGER)
        self.H1SubV2H5Layout.addWidget(self.saveIncTimeCheck)
        self.H1SubV2H5Layout.addWidget(self.saveLogCheck)
        self.H1SubV2H5Layout.addWidget(self.saveLogButt)
        self.H1SubV2H5Layout.addWidget(self.toggleThemeButt)
        self.H1SubV2H6Layout.addWidget(self.labelRATIO)
        self.H1SubV2H6Layout.addWidget(self.inputTickToMsBox)
        self.H1SubV2H7Layout.addWidget(self.labelMaxTickCount)
        self.H1SubV2H7Layout.addWidget(self.inputMaxTickCount)
        self.H1SubV2H8Layout.addWidget(self.labelUpDownCount)
        self.H1SubV2H8Layout.addWidget(self.upCountRadio)
        self.H1SubV2H8Layout.addWidget(self.downCountRadio)
        
        self.H1SubV2Layout.addWidget(self.labelMeasure)
        self.H1SubV2Layout.addLayout(self.H1SubV2H1Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H2Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H3Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H4Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H5Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H6Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H7Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H8Layout)
        self.H1SubV2Layout.addStretch()
        
        self.H1layout.addLayout(self.H1SubV1Layout)
        self.H1layout.addStretch()
        self.H1layout.addLayout(self.H1SubV2Layout)
        self.Vlayout.addLayout(self.H1layout)
        self.Vlayout.addStretch()
        self.Vlayout.addWidget(self.saveConfigButt)
        self.dockContents.setLayout(self.Vlayout)  
    
    # -- ! We need callbacks to update the actual Values ! --#
    
    #---CREATE COMBOBOX Callbacks---#
    ## CB: comboCOM // Serial COM-Port
    def comboComChanged(self):
        self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()]
        self.logger.logEvent('changed COM-Port to - '+ self.snifferConfig.configCom)  
    ## CB: comboBAUD // Serial BAUD-Rate  
    def comboBaudChanged(self):
        self.snifferConfig.configBaud = self.comboBAUD.currentText()
        self.logger.logEvent('changed BAUD-Rate to - '+ self.snifferConfig.configBaud)
    ## CB: comboSTOP // Serial STOP-bit count
    def comboStopBitsChanged(self):
        self.snifferConfig.configStopBits = self.STOPList[self.comboSTOP.currentIndex()]
        self.logger.logEvent('changed STOP-Bits to - '+ self.snifferConfig.configStopBits) 
    ## CB: comboPARTIY // Serial Parity-bit (odd/even/none)   
    def comboParityChanged(self):
        self.snifferConfig.configParity = self.PARITYList[self.comboPARITY.currentIndex()]
        self.logger.logEvent('changed PARITY to - '+ self.snifferConfig.configParity)   
    ## CB: comboMODE // Measurement mode
    def comboModeChanged(self):
        # Check which box is checked in order to show the user the necessary info
        self.snifferConfig.configMode = self.MODEList[self.comboMODE.currentIndex()]
        if self.snifferConfig.configMode == self.MODEList[0]:
            self.inputSingleDurBox.show()
            self.labelSINGLETIME.show()
            self.comboTRIGGER.hide()
            self.labelTRIGGER.hide()
        if self.snifferConfig.configMode == self.MODEList[1]:
            self.inputSingleDurBox.hide()
            self.labelSINGLETIME.hide()
            self.comboTRIGGER.hide()
            self.labelTRIGGER.hide()
        if self.snifferConfig.configMode == self.MODEList[2]:
            self.inputSingleDurBox.show()
            self.labelSINGLETIME.show()
            self.comboTRIGGER.show()
            self.labelTRIGGER.show()
        self.logger.logEvent('changed Measurement-mode to - '+ self.snifferConfig.configMode)
    ## CB: comboTRIGGER // the Trigger the measurement waits for (only in TRIGGER-measmode)
    def comboTriggerChanged(self):
        self.snifferConfig.configTrigger = self.TRIGGERList[self.comboTRIGGER.currentIndex()]
        self.logger.logEvent('changed TriggerType to - '+ self.snifferConfig.configTrigger)
    
    #---CREATE THEME Callbacks---#    
    ## CB: Toggles the theme between dark and light mode
    #  @details This happens by calling the appropriate function of the parent (QMainwindow), so that the theme
    #  is changed globally
    def toggleTheme(self):
        if(self.snifferConfig.configCurrentTheme == 'Light'):
            self.parent.loadTheme('Dark')
            #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: #31363b; border-radius:100px}')
        else:
            self.parent.loadTheme('Light')
            #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: white; border-radius:100px}')
        #self.parent.setStartStopButtonStyle()   
    
    #---CREATE CHECKBOX Callbacks---#   
    ## CB: Handle the SaveLog checkbox event (Toggle)
    def checkSaveLogChanged(self):
        self.snifferConfig.configLogCheck ^= 1  
        if(self.snifferConfig.configLogCheck == 1):   
            self.logger.enableLogs()   
        else:
            self.logger.disableLogs()
        self.logger.logEvent('changed LogCheckbox to - '+ str(self.snifferConfig.configLogCheck))
        
    ## CB: Handle the SaveInctime checkbox event (Toggle)         
    def checkSaveInctimeChanged(self):
        self.snifferConfig.configIncTimeCheck ^= 1 
        self.logger.logEvent('changed Save Time-Increment Checkbox to - '+ str(self.snifferConfig.configIncTimeCheck))

    #---CREATE LINEEDIT Callbacks---#
    ## CB: Handle the SingleDur lineedit callback (adjust singleshot duration)        
    def lineSingleDurChanged(self):
        self.snifferConfig.configSingleDurLine = self.inputSingleDurBox.text()
        self.logger.logEvent('changed Singleshot Duration to - '+ str(self.snifferConfig.configSingleDurLine))
        
    ## CB: Handle the TickToMs lineedit callback (adjust ticks per ms)       
    def lineTickToMsChanged(self):
        self.snifferConfig.configTickToMsLine = self.inputTickToMsBox.text()
        self.logger.logEvent('changed Tick To Ms Ratio to - '+ str(self.snifferConfig.configTickToMsLine))

    ## CB: Handle the MaxTickCount lineedit callback (adjust maximum tickcount value)
    def lineMaxTickCountChanged(self):
        self.snifferConfig.configMaxTickCountVal = self.inputMaxTickCount.text()
        self.logger.logEvent('changed Max Tickcount Value to - '+ str(self.snifferConfig.configTickToMsLine))
    
    #---CREATE PUSHBUTTON Callbacks---#    
    ## CB: Handle the refreshCOM pushbutton callback (refresh all com-ports)      
    def refreshCom(self):
        self.COMList = OsSniffer.OS_SerialPortList()
        self.comboCOM.clear()
        self.comboCOM.addItems(self.COMList)
        self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()]

    #---CREATE RADIO Callbacks---#
    ## Select upCount
    def upCountRadioSelected(self):
        self.snifferConfig.configUpDownState = 'Up'
        self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState))
    
    ## Select downCount
    def downCountRadioSelected(self):
        self.snifferConfig.configUpDownState = 'Down'
        self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState))
      
    #---CONTENT FUNCTIONS---#
    ## CB: Saves all logs saved in the logList to a output-file
    def saveLog(self):
        print('Trying to save logs')
        if(len(snifferLogList) == 0):
            self.displayException('Global Logging List empty. Did you enable the checkbox?')
        else:
            self.saveLogDirectory, self.purge = QFileDialog.getSaveFileName(self, 'Save File', '', 'Logfile (*.slog)')
            print(self.saveLogDirectory)
            self.logFile = open(self.saveLogDirectory,'a+')
            for logTuple in snifferLogList:
                self.logFile.write(str(logTuple[0])+', '+str(logTuple[1])+'\n')
            self.logFile.close()
            
    # --- MANDATORY UI FUNCTIONS --- #
    # -------------------------------#
    ## Read out all components of snifferConfig and set the UI elements according to
    #  the saved values.           
    def syncUiToConfig(self):
        self.inputSingleDurBox.setText(str(self.snifferConfig.configSingleDurLine))
        self.inputTickToMsBox.setText(str(self.snifferConfig.configTickToMsLine))
        self.inputMaxTickCount.setText(str(self.snifferConfig.configMaxTickCountVal))
        
        self.saveLogCheck.setChecked(self.snifferConfig.configLogCheck)
        self.saveIncTimeCheck.setChecked(self.snifferConfig.configIncTimeCheck)

        if self.snifferConfig.configUpDownState == 'Up':
            self.upCountRadio.click()
        elif self.snifferConfig.configUpDownState == 'Down':
            self.downCountRadio.click()
        else:
            print('Error, neither up nor down in config')

        try:
            self.comboCOM.setCurrentIndex(self.COMList.index(self.snifferConfig.configCom))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboCOM - snifferConfig Error')
            self.comboCOM.setCurrentIndex(0)
        try:
            self.comboMODE.setCurrentIndex(self.MODEList.index(self.snifferConfig.configMode))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboMODE - snifferConfig Error')
            self.comboMODE.setCurrentIndex(0)
        try:
            self.comboBAUD.setCurrentIndex(self.BAUDList.index(str(self.snifferConfig.configBaud)))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboBAUD - snifferConfig Error')
            self.comboBAUD.setCurrentIndex(0)
        try:
            self.comboPARITY.setCurrentIndex(self.PARITYList.index(self.snifferConfig.configParity))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboPARITY - snifferConfig Error')
            self.comboPARITY.setCurrentIndex(0)
        try:
            self.comboSTOP.setCurrentIndex(self.STOPList.index(str(self.snifferConfig.configStopBits)))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboSTOP - snifferConfig Error')
            self.comboSTOP.setCurrentIndex(0)
        try:
            self.comboTRIGGER.setCurrentIndex(self.TRIGGERList.index(self.snifferConfig.configTrigger.upper()))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboTRIGGER - snifferConfig Error')
            self.comboTRIGGER.setCurrentIndex(0)