class RadioButtons(WidgetBridge, Choices): _qttype = QGroupBox def customize(self, widget): assert self.choices, "RadioButtons: Cannot build widget bridge without choices" # We give the GroupBox a container so we can add stretch at the end. self.container = QWidget(self.parent) hbox = QHBoxLayout(self.container) self.buttongroup = QButtonGroup(self.parent) if "direction" in self.config and \ self.config["direction"].lower() == "vertical": box = QVBoxLayout() else: box = QHBoxLayout() ix = 1 for text in self.choicesdict().values(): rb = QRadioButton(text, self.parent) box.addWidget(rb) self.buttongroup.addButton(rb, ix) ix += 1 widget.setLayout(box) hbox.addWidget(widget) hbox.addStretch(1) hbox.setContentsMargins(QMargins(0, 0, 0, 0)) def apply(self, value): for b in self.buttongroup.buttons(): b.setChecked(False) b = self.buttongroup.button(self.index(value) + 1) if b: b.setChecked(True) def retrieve(self): ix = self.buttongroup.checkedId() return self.at(ix - 1) if ix > 0 else None
class ChoiceDialog(QDialog): def __init__(self, choices, help_texts=[], parent=None): super(ChoiceDialog, self).__init__(parent) title = "select one from choices" self.setWindowTitle(title) layout = QVBoxLayout(self) self.choiceButtonGroup = QButtonGroup(self) # it is not a visible UI self.choiceButtonGroup.setExclusive(True) if choices and len(choices) >= 1: if len(help_texts) < len(choices): help_texts = choices self.choices = choices for id, choice in enumerate(self.choices): rb = QRadioButton(choice) rb.setToolTip(help_texts[id]) self.choiceButtonGroup.addButton(rb) self.choiceButtonGroup.setId( rb, id) # negative id if not specified layout.addWidget(rb) if id == 0: rb.setChecked(True) self.choiceButtonGroup.buttonClicked.connect(self.choiceChanged) # OK and Cancel buttons buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons) self.setLayout(layout) def choice(self): return self.choices[self.choiceButtonGroup.checkedId()] def choiceId(self): return self.choiceButtonGroup.checkedId() def choiceChanged(self): #print(self.choiceButtonGroup.checkedId()) self.currentChoice = self.choices[self.choiceButtonGroup.checkedId()]
class PickerTypeDialog(QDialog): """ PickerTypeDialog """ def __init__(self, parent): super(PickerTypeDialog, self).__init__(parent) self.pickerType = None self.pickerTypes = [(SurfaceType, "Surface picker"), (TwoStepType, "Two step picker")] self.radioButtons = [] for picker in self.pickerTypes: self.radioButtons.append(QRadioButton(picker[1])) # self.radioButtons[0].setChecked(True) self.buttonGroup = QButtonGroup() ind = 0 for button in self.radioButtons: self.buttonGroup.addButton(button) self.buttonGroup.setId(button, ind) ind += 1 self.nextButton = QPushButton("Choose") self.nextButton.clicked.connect(self.choose) self.cancelButton = QPushButton("Cancel") self.cancelButton.clicked.connect(self.cancel) groupLayout = QVBoxLayout() for radioButton in self.radioButtons: groupLayout.addWidget(radioButton) self.groupBox = QGroupBox("Choose picker type:") self.groupBox.setLayout(groupLayout) self.setModal(True) layout = QGridLayout() layout.setAlignment(Qt.AlignTop) layout.addWidget(self.groupBox, 0, 0, 1, 2) layout.addWidget(self.cancelButton, 1, 0) layout.addWidget(self.nextButton, 1, 1) self.setLayout(layout) @Slot() def choose(self): selectedIndex = self.buttonGroup.checkedId() if selectedIndex >= 0: # load choosen picker type self.pickerType = self.pickerTypes[selectedIndex][0] self.accept() @Slot() def cancel(self): self.reject()
class ChoiceWidget(QWidget): def __init__(self, choices, help_texts=[], parent=None): super(ChoiceWidget, self).__init__(parent) title = "select one from choices" self.setWindowTitle(title) layout = QVBoxLayout(self) self.choiceButtonGroup = QButtonGroup(self) # it is not a visible UI self.choiceButtonGroup.setExclusive(True) if choices and len(choices) >= 1: if len(help_texts) < len(choices): help_texts = choices self.choices = choices for id, choice in enumerate(self.choices): rb = QRadioButton(choice) rb.setToolTip(help_texts[id]) self.choiceButtonGroup.addButton(rb) self.choiceButtonGroup.setId( rb, id) # negative id if not specified layout.addWidget(rb) if id == 0: rb.setChecked(True) self.choiceButtonGroup.buttonClicked.connect(self.choiceChanged) self.setLayout(layout) def choice(self): return self.choices[self.choiceButtonGroup.checkedId()] def setChoice(self, choice): for i, ch in enumerate(self.choices): if ch == choice: self.choiceButtonGroup.button(i).setChecked(True) def choiceId(self): return self.choiceButtonGroup.checkedId() def choiceChanged(self): #print(self.choiceButtonGroup.checkedId()) self.currentChoice = self.choices[self.choiceButtonGroup.checkedId()]
class AdvancedCameraControl(ScreenWithBackButton): def __init__(self, title, camera, mainScreen): self.camera = camera super(AdvancedCameraControl, self).__init__(title, mainScreen) def makeContent(self): layout = QHBoxLayout() # self.exposureControls = ExposureControl(self.camera) # layout.addWidget(self.exposureControls) whiteBalanceGrid = QGridLayout() wbTitle = QLabel("White Balance") wbTitle.setAlignment(Qt.AlignCenter) whiteBalanceGrid.addWidget(wbTitle, 0, 0, 1, 2) btnAuto = OptionButton() btnAuto.setText("Auto") _safelyConnect(btnAuto.clicked, self.camera.whiteBalanceAuto) whiteBalanceGrid.addWidget(btnAuto, 1, 0) btnIndoor = OptionButton() btnIndoor.setText("Indoor") _safelyConnect(btnIndoor.clicked, self.camera.whiteBalanceIndoor) whiteBalanceGrid.addWidget(btnIndoor, 2, 0) btnOutdoor = OptionButton() btnOutdoor.setText("Outdoor") _safelyConnect(btnOutdoor.clicked, self.camera.whiteBalanceOutdoor) whiteBalanceGrid.addWidget(btnOutdoor, 3, 0) btnOnePush = OptionButton() btnOnePush.setText("One Push") _safelyConnect(btnOnePush.clicked, self.camera.whiteBalanceOnePush) whiteBalanceGrid.addWidget(btnOnePush, 4, 0) btnOnePushTrigger = ExpandingButton() btnOnePushTrigger.setText("Set") _safelyConnect(btnOnePushTrigger.clicked, self.camera.whiteBalanceOnePushTrigger) btnOnePushTrigger.setEnabled(False) whiteBalanceGrid.addWidget(btnOnePushTrigger, 4, 1) self.wbOpts = QButtonGroup() self.wbOpts.addButton(btnAuto, 1) self.wbOpts.addButton(btnIndoor, 2) self.wbOpts.addButton(btnOutdoor, 3) self.wbOpts.addButton(btnOnePush, 4) self.wbOpts.buttonClicked.connect(lambda: btnOnePushTrigger.setEnabled(self.wbOpts.checkedId() == 4)) layout.addLayout(whiteBalanceGrid) return layout
class BlindsControl(ScreenWithBackButton): ''' Controls for the blinds. ''' def __init__(self, blindsDevice, mainWindow): self.blindsDevice = blindsDevice ScreenWithBackButton.__init__(self, "Blinds", mainWindow) def makeContent(self): layout = QGridLayout() self.blinds = QButtonGroup() for i in range(1, 7): btn = IDedButton(i) btn.setText(str(i)) layout.addWidget(btn, 0, i - 1) btn.setCheckable(True) self.blinds.addButton(btn, i) btnAll = IDedButton(0) btnAll.setText("All") layout.addWidget(btnAll, 0, 6) btnAll.setCheckable(True) btnAll.setChecked(True) self.blinds.addButton(btnAll, 0) btnRaise = SvgButton(":icons/go-up", 96, 96) btnRaise.setText("Raise") btnRaise.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnRaise, 1, 1, 1, 3) btnRaise.clicked.connect(self.raiseUp) btnLower = SvgButton(":icons/go-down", 96, 96) btnLower.setText("Lower") btnLower.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnLower, 2, 1, 1, 3) btnLower.clicked.connect(self.lowerDown) btnStop = SvgButton(":icons/process-stop", 96, 96) btnStop.setText("Stop") btnStop.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) layout.addWidget(btnStop, 1, 4, 2, 2) btnStop.clicked.connect(self.stop) return layout @handlePyroErrors def raiseUp(self): blindID = self.blinds.checkedId() self.blindsDevice.raiseUp(blindID) @handlePyroErrors def lowerDown(self): blindID = self.blinds.checkedId() self.blindsDevice.lower(blindID) @handlePyroErrors def stop(self): blindID = self.blinds.checkedId() self.blindsDevice.stop(blindID)
class VideoSwitcher(QWidget): def __init__(self, controller, mainWindow): super(VideoSwitcher, self).__init__() self.controller = controller self.mainWindow = mainWindow self.setupUi() def setupUi(self): gridlayout = QGridLayout() self.setLayout(gridlayout) ''' Buttons added to inputs should have a numeric ID set equal to their input number on the Aldates main switcher. ''' self.inputs = QButtonGroup() inputsGrid = QHBoxLayout() self.btnCamera1 = CameraSelectionButton(1) self.btnCamera1.setText("Camera 1") self.btnCamera1.setInput(VisualsSystem.camera1) inputsGrid.addWidget(self.btnCamera1) self.inputs.addButton(self.btnCamera1, 1) self.btnCamera1.setIcon(QIcon(":icons/camera-video")) self.btnCamera2 = CameraSelectionButton(2) self.btnCamera2.setText("Camera 2") self.btnCamera2.setInput(VisualsSystem.camera2) inputsGrid.addWidget(self.btnCamera2) self.inputs.addButton(self.btnCamera2, 2) self.btnCamera2.setIcon(QIcon(":icons/camera-video")) self.btnCamera3 = CameraSelectionButton(3) self.btnCamera3.setText("Camera 3") self.btnCamera3.setInput(VisualsSystem.camera3) inputsGrid.addWidget(self.btnCamera3) self.inputs.addButton(self.btnCamera3, 3) self.btnCamera3.setIcon(QIcon(":icons/camera-video")) self.btnDVD = InputButton() self.btnDVD.setText("DVD") self.btnDVD.setInput(VisualsSystem.dvd) inputsGrid.addWidget(self.btnDVD) self.inputs.addButton(self.btnDVD, 4) self.btnDVD.setIcon(QIcon(":icons/media-optical")) self.btnExtras = InputButton() self.btnExtras.setText("Extras") inputsGrid.addWidget(self.btnExtras) self.btnExtras.setIcon(QIcon(":icons/video-display")) self.inputs.addButton(self.btnExtras, 5) self.btnVisualsPC = InputButton() self.btnVisualsPC.setText("Visuals PC") self.btnVisualsPC.setInput(VisualsSystem.visualsPC) inputsGrid.addWidget(self.btnVisualsPC) self.inputs.addButton(self.btnVisualsPC, 6) self.btnVisualsPC.setIcon(QIcon(":icons/computer")) self.btnBlank = InputButton() self.btnBlank.setText("Blank") self.btnBlank.setInput(VisualsSystem.blank) inputsGrid.addWidget(self.btnBlank) self.inputs.addButton(self.btnBlank, 0) gridlayout.addLayout(inputsGrid, 0, 0, 1, 7) self.extrasSwitcher = ExtrasSwitcher(self.controller) self.extrasSwitcher.inputSelected.connect(self.handleExtrasSelect) self.btnExtras.setInput(ProxyInput(self.extrasSwitcher)) self.blank = QWidget(self) gridlayout.addWidget(self.blank, 1, 0, 1, 5) self.outputsGrid = OutputsGrid() gridlayout.addWidget(self.outputsGrid, 1, 5, 1, 2) gridlayout.setRowStretch(0, 1) gridlayout.setRowStretch(1, 5) QMetaObject.connectSlotsByName(self) self.setInputClickHandlers() self.setOutputClickHandlers(self.outputsGrid) self.configureInnerControlPanels() self.gridlayout = gridlayout def configureInnerControlPanels(self): self.panels = [ QWidget(), # Blank CameraControl(self.controller["Camera 1"]) if self.controller.hasDevice("Camera 1") else QLabel(StringConstants.noDevice), CameraControl(self.controller["Camera 2"]) if self.controller.hasDevice("Camera 2") else QLabel(StringConstants.noDevice), CameraControl(self.controller["Camera 3"]) if self.controller.hasDevice("Camera 3") else QLabel(StringConstants.noDevice), QLabel(StringConstants.noDevice), # DVD - no controls self.extrasSwitcher if self.controller.hasDevice("Extras") else QLabel(StringConstants.noDevice), # Extras EclipseControls(self.controller["Main Scan Converter"]) if self.controller.hasDevice("Main Scan Converter") else QLabel(StringConstants.noDevice), # Visuals PC ] self.advPanels = [ None, AdvancedCameraControl("Camera 1", self.controller["Camera 1"], self.mainWindow) if self.controller.hasDevice("Camera 1") else None, AdvancedCameraControl("Camera 2", self.controller["Camera 2"], self.mainWindow) if self.controller.hasDevice("Camera 1") else None, AdvancedCameraControl("Camera 3", self.controller["Camera 3"], self.mainWindow) if self.controller.hasDevice("Camera 1") else None, None, None, None ] def setInputClickHandlers(self): for btn in self.inputs.buttons(): btn.clicked.connect(self.handleInputSelect) btn.longpress.connect(self.showAdvPanel) def setOutputClickHandlers(self, outputsGrid): outputsGrid.connectMainOutputs(self.handleOutputSelect) ''' btnPCMix is a special case since that's on a different switcher ''' outputsGrid.connectPreviewOutputs(self.handlePCMixSelect) def keyPressEvent(self, e): if e.key() == Qt.Key_0: self.btnBlank.click() elif e.key() == Qt.Key_1: self.btnCamera1.click() elif e.key() == Qt.Key_2: self.btnCamera2.click() elif e.key() == Qt.Key_3: self.btnCamera3.click() elif e.key() == Qt.Key_4: self.btnDVD.click() elif e.key() == Qt.Key_5: self.btnExtras.click() elif e.key() == Qt.Key_6: self.btnVisualsPC.click() elif e.key() == Qt.Key_Space: self.outputsGrid.btnAll.click() else: self.panels[self.inputs.checkedId()].keyPressEvent(e) def keyReleaseEvent(self, e): self.panels[self.inputs.checkedId()].keyReleaseEvent(e) def handleInputSelect(self): inputID = self.inputs.checkedId() logging.debug("Input selected: " + str(inputID)) if inputID >= 0: myInput = self.inputs.checkedButton().input if myInput: myInput.preview(self.controller) self.gridlayout.removeWidget(self.gridlayout.itemAtPosition(1, 0).widget()) for p in self.panels: p.hide() chosenPanel = self.panels[inputID] self.gridlayout.addWidget(chosenPanel, 1, 0, 1, 5) chosenPanel.show() # Prevent certain options from being selectable if inputID == 6 or inputID == 0: self.outputsGrid.setEnabled(True) self.outputsGrid.btnPCMix.setEnabled(False) elif inputID == 5 and self.extrasSwitcher.currentInput() is None: self.outputsGrid.setEnabled(False) self.outputsGrid.btnPCMix.setEnabled(True) else: self.outputsGrid.setEnabled(True) self.outputsGrid.btnPCMix.setEnabled(True) def handleOutputSelect(self): outputChannel = self.sender().ID inputID = self.inputs.checkedId() checkedExtrasButton = self.extrasSwitcher.inputs.checkedButton() inputChannel = checkedExtrasButton.input if (inputID == 5 and checkedExtrasButton) else self.inputs.checkedButton().input if inputChannel: inputChannel.toMain(self.controller, outputChannel) def handlePCMixSelect(self): inputID = self.inputs.checkedId() checkedExtrasButton = self.extrasSwitcher.inputs.checkedButton() inputChannel = checkedExtrasButton.input if (inputID == 5 and checkedExtrasButton) else self.inputs.checkedButton().input if inputChannel: inputChannel.toPCMix(self.controller) @Slot(VisualsSystem.Input) def handleExtrasSelect(self, extrasInput): if extrasInput is not None: self.btnExtras.setText(extrasInput.name) self.outputsGrid.inputNames[5] = extrasInput.name self.outputsGrid.setEnabled(True) else: # Not sure under what circumstances, if any, this will arise self.btnExtras.setText("Extras") self.outputsGrid.inputNames[5] = "Extras" self.outputsGrid.setEnabled(False) def showAdvPanel(self): sender = self.sender() inputID = self.sender().ID if hasattr(sender, "ID") else None if inputID is not None and self.advPanels[inputID] is not None: self.mainWindow.showScreen(self.advPanels[inputID]) def updateOutputMappings(self, mapping): print mapping self.outputsGrid.updateOutputMappings(mapping)
class ProjectorScreensControl(ScreenWithBackButton): ''' Controls for the projector screens. ''' def __init__(self, controller, mainWindow): self.controller = controller ScreenWithBackButton.__init__(self, "Projector Screens", mainWindow) def makeContent(self): layout = QGridLayout() self.screens = QButtonGroup() btnLeft = IDedButton(1) btnLeft.setText("Left") layout.addWidget(btnLeft, 1, 0, 1, 2) btnLeft.setCheckable(True) self.screens.addButton(btnLeft, 1) btnAll = IDedButton(0) btnAll.setText("Both") layout.addWidget(btnAll, 1, 2, 1, 3) btnAll.setCheckable(True) btnAll.setChecked(True) self.screens.addButton(btnAll, 0) btnRight = IDedButton(2) btnRight.setText("Right") layout.addWidget(btnRight, 1, 5, 1, 2) btnRight.setCheckable(True) self.screens.addButton(btnRight, 2) iconSize = QSize(96, 96) btnRaise = ExpandingButton() btnRaise.setText("Raise") btnRaise.setIcon(QIcon("icons/go-up.svg")) btnRaise.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnRaise, 2, 1, 1, 3) btnRaise.setIconSize(iconSize) btnRaise.clicked.connect(self.raiseUp) btnLower = ExpandingButton() btnLower.setText("Lower") btnLower.setIcon(QIcon("icons/go-down.svg")) btnLower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnLower, 3, 1, 1, 3) btnLower.setIconSize(iconSize) btnLower.clicked.connect(self.lowerDown) btnStop = ExpandingButton() btnStop.setText("Stop") btnStop.setIcon(QIcon("icons/process-stop.svg")) btnStop.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnStop, 2, 4, 2, 2) btnStop.setIconSize(iconSize) btnStop.clicked.connect(self.stop) return layout def raiseUp(self): screenID = self.screens.checkedId() try: self.controller.raiseUp("Screens", screenID) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText) def lowerDown(self): screenID = self.screens.checkedId() try: self.controller.lower("Screens", screenID) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText) def stop(self): screenID = self.screens.checkedId() try: self.controller.stop("Screens", screenID) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText)
class MainWindow(object): ''' Contains the implementation for building and displaying the application's main window. ''' def __init__(self, model, alg): ''' Constructs the GUI and initializes internal parameters. ''' self._window = QMainWindow() self._window.setWindowTitle("Reverse A*") self._worldWidget = WorldWidget(model, alg) self._model = model self._alg = alg self._spdSetting = 0 self._timer = QTimer() #Every time the timer times out, invoke the _onStep method. self._timer.timeout.connect(self._onStep) self._buildGUI() self._window.show() def _buildGUI(self): ''' Construct the GUI widgets and layouts. ''' centerWidget = QWidget() self._window.setCentralWidget(centerWidget) worldLayout = QHBoxLayout() worldLayout.addWidget(self._worldWidget) grpBx = QGroupBox("2D World") grpBx.setLayout(worldLayout) grpBx.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) ctrlPan = self._buildControlPanel() layout = QHBoxLayout() layout.addWidget(ctrlPan) layout.addWidget(grpBx) layout.setAlignment(ctrlPan, Qt.AlignLeft | Qt.AlignTop) centerWidget.setLayout(layout) def _buildControlPanel(self): ''' Create all buttons, labels, etc for the application control elements ''' layout = QVBoxLayout() layout.addWidget(self._buildSetupPanel()) layout.addWidget(self._buildSpeedPanel()) layout.addWidget(self._buildResultsPanel()) layout.addWidget(self._buildRenderingOptions()) layout.setAlignment(Qt.AlignLeft | Qt.AlignTop) ctrlWidget = QWidget(self._window) ctrlWidget.setLayout(layout) ctrlWidget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) return ctrlWidget def _buildSetupPanel(self): ''' Creates the sub-panel containing control widgets for re-initializing the world on demand. ''' self._percentLbl = QLabel("%") self._setupBtn = QPushButton("Setup", self._window) self._setupBtn.clicked.connect(self._onSetup) self._percentObstacleSldr = QSlider(Qt.Horizontal, self._window) self._percentObstacleSldr.setTickPosition(QSlider.TickPosition.TicksBelow) self._percentObstacleSldr.setTickInterval(10) self._percentObstacleSldr.setMinimum(0) self._percentObstacleSldr.setMaximum(100) self._percentObstacleSldr.valueChanged.connect(self._onPercentSlideChange) self._percentObstacleSldr.setValue(33) layout = QGridLayout() layout.addWidget(self._setupBtn, 0, 0, 1, 2) layout.addWidget(QLabel("Percent Occupied:"), 1, 0) layout.addWidget(self._percentLbl, 1, 1) layout.addWidget(self._percentObstacleSldr, 2, 0, 1, 2) grpBx = QGroupBox("Setup Controls") grpBx.setLayout(layout) grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) return grpBx def _buildSpeedPanel(self): ''' Creates the sub-panel containing control widgets for controlling the speed of execution of the algorithm. ''' self._runBtn = QPushButton("Run", self._window) self._stepBtn = QPushButton("Step Once", self._window) self._runBtn.clicked.connect(self._onRun) self._stepBtn.clicked.connect(self._onStep) slowRadio = QRadioButton('Slow', self._window) medRadio = QRadioButton('Medium', self._window) fastRadio = QRadioButton('Fast', self._window) notVisRadio = QRadioButton('Not visible', self._window) slowRadio.setChecked(True) self._speedGroup = QButtonGroup(self._window) self._speedGroup.addButton(slowRadio, 0) self._speedGroup.addButton(medRadio, 1) self._speedGroup.addButton(fastRadio, 2) self._speedGroup.addButton(notVisRadio, 3) self._speedGroup.buttonClicked.connect(self._onSpeedChange) layout = QVBoxLayout() layout.addWidget(self._runBtn) layout.addWidget(self._stepBtn) layout.addWidget(slowRadio) layout.addWidget(medRadio) layout.addWidget(fastRadio) layout.addWidget(notVisRadio) grpBx = QGroupBox("Run Controls") grpBx.setLayout(layout) grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) return grpBx def _buildResultsPanel(self): ''' Creates the sub-panel containing displays widgets for informing the user on the results of running the algorithm. ''' self._doneLbl = QLabel("No", self._window) self._solvableLbl = QLabel("Yes", self._window) #_doneLbl is highlighted green upon successful algorithm completion pal = self._doneLbl.palette() pal.setColor(QPalette.Window, Qt.green) self._doneLbl.setPalette(pal) #_solvableLbl is highlighted red if the world model isn't solvable pal = self._solvableLbl.palette() pal.setColor(QPalette.Window, Qt.red) self._solvableLbl.setPalette(pal) layout = QGridLayout() layout.addWidget(QLabel("Path Found:"), 0, 0) layout.addWidget(self._doneLbl, 0, 1) layout.addWidget(QLabel("Is Solvable:"), 1, 0) layout.addWidget(self._solvableLbl, 1, 1) grpBx = QGroupBox("Results") grpBx.setLayout(layout) grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) return grpBx def _buildRenderingOptions(self): ''' Creates the sub-panel containing control widgets for setting options in how the world is rendered on the GUI. ''' self._openChk = QCheckBox("Active Cells") self._visitedChk = QCheckBox("Visited Cells") self._pathChk = QCheckBox("Draw Path") self._costChk = QCheckBox("Draw Estimated Costs") pal = self._openChk.palette() pal.setColor(QPalette.WindowText, Qt.green) self._openChk.setPalette(pal) pal = self._visitedChk.palette() pal.setColor(QPalette.WindowText, Qt.cyan) self._visitedChk.setPalette(pal) pal = self._pathChk.palette() pal.setColor(QPalette.WindowText, Qt.red) self._pathChk.setPalette(pal) self._visitedChk.setChecked(True) self._pathChk.setChecked(True) self._costChk.setChecked(True) self._openChk.stateChanged.connect(self._renderingOptionChanged) self._visitedChk.stateChanged.connect(self._renderingOptionChanged) self._pathChk.stateChanged.connect(self._renderingOptionChanged) self._costChk.stateChanged.connect(self._renderingOptionChanged) layout = QVBoxLayout() layout.addWidget(self._openChk) layout.addWidget(self._visitedChk) layout.addWidget(self._pathChk) layout.addWidget(self._costChk) grpBx = QGroupBox("Rendering Options") grpBx.setLayout(layout) grpBx.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) return grpBx @Slot() def _renderingOptionChanged(self, value): ''' When any rendering option is changed this method is invoked. It polls the GUI for the selected setting values and passes them to the 2D world widget. ''' self._worldWidget.setDrawActiveCells(self._openChk.isChecked()) self._worldWidget.setDrawVisitedCells(self._visitedChk.isChecked()) self._worldWidget.setDrawPath(self._pathChk.isChecked()) self._worldWidget.setDrawCosts(self._costChk.isChecked()) self._worldWidget.repaint() @Slot() def _onPercentSlideChange(self, value): ''' Invoked every time the percent slider is changed. Displays the percent value on the GUI. ''' #Add extra padding to the front of the string to help prevent #gui layout resizing if value < 10: self._percentLbl.setText(" " + str(value) + "%") elif value < 100: self._percentLbl.setText(" " + str(value) + "%") else: self._percentLbl.setText(str(value) + "%") @Slot() def _onSpeedChange(self, value): ''' Invoked every time one of the speed setting radio buttons are selected. Resets the algorithm iterating callback timer if it's currently running. ''' self._spdSetting = self._speedGroup.checkedId() if self._timer.isActive(): self._resetTimer() @Slot() def _onSetup(self): ''' Invoked when the setup button is pushed. Re-initializes the world model and the algorithm. ''' self._timer.stop() self._runBtn.setText('Run') self._model.reset(self._percentObstacleSldr.value() / 100.0) self._alg.reset() self._doneLbl.setText("No") self._solvableLbl.setText("Yes") self._doneLbl.setAutoFillBackground(False) self._solvableLbl.setAutoFillBackground(False) self._worldWidget.repaint() @Slot() def _onRun(self): ''' Invoked when the run button is pushed. Toggles the algorithm iterating timer on and off. ''' if self._timer.isActive(): self._timer.stop() self._runBtn.setText("Run") else: self._resetTimer() self._runBtn.setText("Stop") @Slot() def _onStep(self): ''' Invoked on every 'step once' call and on every timer timeout. Iterates one step of the algorithm and then checks for termination conditions such as the algorithm being done or solvable. ''' self._alg.step() self._worldWidget.repaint() if self._alg.isDone() or not self._alg.isSolvable(): self._timer.stop() self._runBtn.setText('Run') self._checkTerminalConditions() def _checkTerminalConditions(self): ''' Sets the 'results' labels based on the algorithm results. ''' if self._alg.isDone(): self._doneLbl.setText("Yes") self._doneLbl.setAutoFillBackground(True) if not self._alg.isSolvable(): self._solvableLbl.setAutoFillBackground(True) self._solvableLbl.setText("No") def _resetTimer(self): ''' When the algorithm run speed is modified by the user this resets the algorithm timer. ''' if self._spdSetting == 3: while not self._alg.isDone() and self._alg.isSolvable(): self._alg.step() self._worldWidget.repaint() self._timer.stop() self._runBtn.setText("Run") self._checkTerminalConditions() else: timeOut = 1 if self._spdSetting == 0: timeOut = 500 elif self._spdSetting == 1: timeOut = 250 elif self._spdSetting == 2: timeOut = 1 self._timer.start(timeOut)
class ProjectorScreensControl(ScreenWithBackButton): ''' Controls for the projector screens. ''' def __init__(self, screensDevice, mainWindow): self.screensDevice = screensDevice ScreenWithBackButton.__init__(self, "Projector Screens", mainWindow) def makeContent(self): layout = QGridLayout() self.screens = QButtonGroup() btnLeft = IDedButton(1) btnLeft.setText("Left") layout.addWidget(btnLeft, 1, 0, 1, 2) btnLeft.setCheckable(True) self.screens.addButton(btnLeft, 1) btnAll = IDedButton(0) btnAll.setText("Both") layout.addWidget(btnAll, 1, 2, 1, 3) btnAll.setCheckable(True) btnAll.setChecked(True) self.screens.addButton(btnAll, 0) btnRight = IDedButton(2) btnRight.setText("Right") layout.addWidget(btnRight, 1, 5, 1, 2) btnRight.setCheckable(True) self.screens.addButton(btnRight, 2) btnRaise = SvgButton(":icons/go-up", 96, 96) btnRaise.setText("Raise") btnRaise.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnRaise, 2, 1, 1, 3) btnRaise.clicked.connect(self.raiseUp) btnLower = SvgButton(":icons/go-down", 96, 96) btnLower.setText("Lower") btnLower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnLower, 3, 1, 1, 3) btnLower.clicked.connect(self.lowerDown) btnStop = SvgButton(":icons/process-stop", 96, 96) btnStop.setText("Stop") btnStop.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) layout.addWidget(btnStop, 2, 4, 2, 2) btnStop.clicked.connect(self.stop) return layout @handlePyroErrors def raiseUp(self): screenID = self.screens.checkedId() self.screensDevice.raiseUp(screenID) @handlePyroErrors def lowerDown(self): screenID = self.screens.checkedId() self.screensDevice.lower(screenID) @handlePyroErrors def stop(self): screenID = self.screens.checkedId() self.screensDevice.stop(screenID)
class CameraControl(QWidget): ''' GUI to control a camera. ''' def __init__(self, camera): super(CameraControl, self).__init__() self.camera = camera self.initUI() self.panSpeed = 12 self.tiltSpeed = 12 self.zoomSpeed = 6 def initUI(self): layout = QGridLayout() self.setLayout(layout) self.btnUp = CameraButton() layout.addWidget(self.btnUp, 0, 1, 2, 1) _safelyConnect(self.btnUp.pressed, lambda: self.camera.moveUp(self.panSpeed, self.tiltSpeed)) _safelyConnect(self.btnUp.released, self.camera.stop) _safelyConnect(self.btnUp.clicked, self.deselectPreset) self.btnUp.setIcon(QIcon(":icons/go-up")) self.btnLeft = CameraButton() layout.addWidget(self.btnLeft, 1, 0, 2, 1) _safelyConnect(self.btnLeft.pressed, lambda: self.camera.moveLeft(self.panSpeed, self.tiltSpeed)) _safelyConnect(self.btnLeft.released, self.camera.stop) _safelyConnect(self.btnLeft.clicked, self.deselectPreset) self.btnLeft.setIcon(QIcon(":icons/go-previous")) self.btnDown = CameraButton() layout.addWidget(self.btnDown, 2, 1, 2, 1) _safelyConnect(self.btnDown.pressed, lambda: self.camera.moveDown(self.panSpeed, self.tiltSpeed)) _safelyConnect(self.btnDown.released, self.camera.stop) _safelyConnect(self.btnDown.clicked, self.deselectPreset) self.btnDown.setIcon(QIcon(":icons/go-down")) self.btnRight = CameraButton() layout.addWidget(self.btnRight, 1, 2, 2, 1) _safelyConnect(self.btnRight.pressed, lambda: self.camera.moveRight(self.panSpeed, self.tiltSpeed)) _safelyConnect(self.btnRight.released, self.camera.stop) _safelyConnect(self.btnRight.clicked, self.deselectPreset) self.btnRight.setIcon(QIcon(":icons/go-next")) zoomInOut = PlusMinusButtons("Zoom") _safelyConnect(zoomInOut.upButton.pressed, lambda: self.camera.zoomIn(self.zoomSpeed)) _safelyConnect(zoomInOut.upButton.released, self.camera.zoomStop) _safelyConnect(zoomInOut.upButton.clicked, self.deselectPreset) _safelyConnect(zoomInOut.downButton.pressed, lambda: self.camera.zoomOut(self.zoomSpeed)) _safelyConnect(zoomInOut.downButton.released, self.camera.zoomStop) _safelyConnect(zoomInOut.downButton.clicked, self.deselectPreset) layout.addWidget(zoomInOut, 0, 3, 4, 1) focus = PlusMinusAutoButtons("Focus") _safelyConnect(focus.upButton.pressed, self.camera.focusFar) _safelyConnect(focus.upButton.released, self.camera.focusStop) _safelyConnect(focus.upButton.clicked, self.deselectPreset) _safelyConnect(focus.downButton.pressed, self.camera.focusNear) _safelyConnect(focus.downButton.released, self.camera.focusStop) _safelyConnect(focus.downButton.clicked, self.deselectPreset) def autoFocusAndDeselect(): self.camera.focusAuto() self.deselectPreset() _safelyConnect(focus.autoButton.clicked, autoFocusAndDeselect) layout.addWidget(focus, 0, 4, 4, 1) brightness = PlusMinusAutoButtons("Bright") _safelyConnect(brightness.upButton.clicked, self.camera.brighter) _safelyConnect(brightness.downButton.clicked, self.camera.darker) _safelyConnect(brightness.autoButton.clicked, self.camera.setAutoExposure) layout.addWidget(brightness, 0, 5, 4, 1) presets = QGridLayout() presets.setRowStretch(0, 2) presets.setRowStretch(1, 1) self.presetGroup = QButtonGroup() for i in range(1, 7): btnPresetRecall = CameraButton() presets.addWidget(btnPresetRecall, 0, i, 1, 1) btnPresetRecall.setText(str(i)) _safelyConnect(btnPresetRecall.clicked, lambda i=i: self.recallPreset(i)) btnPresetRecall.setCheckable(True) self.presetGroup.addButton(btnPresetRecall, i) btnPresetSet = CameraButton() presets.addWidget(btnPresetSet, 1, i, 1, 1) btnPresetSet.setText("Set") _safelyConnect(btnPresetSet.clicked, lambda i=i: self.storePreset(i)) layout.addLayout(presets, 4, 0, 3, 6) def keyPressEvent(self, e): if e.key() == Qt.Key_Left: self.btnLeft.pressed.emit() elif e.key() == Qt.Key_Right: self.btnRight.pressed.emit() elif e.key() == Qt.Key_Up: self.btnUp.pressed.emit() elif e.key() == Qt.Key_Down: self.btnDown.pressed.emit() def keyReleaseEvent(self, e): if e.key() == Qt.Key_Left: self.btnLeft.released.emit() elif e.key() == Qt.Key_Right: self.btnRight.released.emit() elif e.key() == Qt.Key_Up: self.btnUp.released.emit() elif e.key() == Qt.Key_Down: self.btnDown.released.emit() @handlePyroErrors def storePreset(self, index): print "Storing preset " + str(index) result = self.camera.storePreset(index) self.presetGroup.buttons()[index - 1].setChecked(True) return result @handlePyroErrors def recallPreset(self, index): print "Recalling preset " + str(index) return self.camera.recallPreset(index) def deselectPreset(self): if self.presetGroup.checkedId() >= 0: # Yuck. self.presetGroup.setExclusive(False) while (self.presetGroup.checkedId() >= 0): self.presetGroup.checkedButton().setChecked(False) self.presetGroup.setExclusive(True)
class CameraControl(QWidget): ''' GUI to control a camera. ''' def __init__(self, controller, cameraID): super(CameraControl, self).__init__() self.controller = controller self.cameraID = cameraID self.initUI() def initUI(self): layout = QGridLayout() self.setLayout(layout) self.btnUp = CameraButton(CameraMove.Up) layout.addWidget(self.btnUp, 0, 1, 2, 1) self.btnUp.pressed.connect(self.move) self.btnUp.released.connect(self.stop) self.btnUp.setIcon(QIcon("icons/go-up.svg")) self.btnLeft = CameraButton(CameraMove.Left) layout.addWidget(self.btnLeft, 1, 0, 2, 1) self.btnLeft.pressed.connect(self.move) self.btnLeft.released.connect(self.stop) self.btnLeft.setIcon(QIcon("icons/go-previous.svg")) self.btnDown = CameraButton(CameraMove.Down) layout.addWidget(self.btnDown, 2, 1, 2, 1) self.btnDown.pressed.connect(self.move) self.btnDown.released.connect(self.stop) self.btnDown.setIcon(QIcon("icons/go-down.svg")) self.btnRight = CameraButton(CameraMove.Right) layout.addWidget(self.btnRight, 1, 2, 2, 1) self.btnRight.pressed.connect(self.move) self.btnRight.released.connect(self.stop) self.btnRight.setIcon(QIcon("icons/go-next.svg")) zoomInOut = PlusMinusButtons("Zoom", CameraZoom.Tele, CameraZoom.Wide) zoomInOut.connectPressed(self.zoom) zoomInOut.connectReleased(self.stopZoom) layout.addWidget(zoomInOut, 0, 3, 4, 1) focus = PlusMinusAutoButtons("Focus", CameraFocus.Far, CameraFocus.Near, CameraFocus.Auto) focus.connectPressed(self.focus) focus.connectReleased(self.stopFocus) focus.autoButton.clicked.connect(self.focus) layout.addWidget(focus, 0, 4, 4, 1) brightness = PlusMinusButtons("Brightness", True, False) brightness.connectClicked(self.exposure) layout.addWidget(brightness, 0, 5, 4, 1) presets = QGridLayout() presets.setRowStretch(0, 2) presets.setRowStretch(1, 1) self.presetGroup = QButtonGroup() for i in range(0, 6): btnPresetRecall = CameraButton(i) presets.addWidget(btnPresetRecall, 0, i, 1, 1) btnPresetRecall.setText(str(i + 1)) btnPresetRecall.clicked.connect(self.recallPreset) btnPresetRecall.setCheckable(True) self.presetGroup.addButton(btnPresetRecall, i) btnPresetSet = CameraButton(i) presets.addWidget(btnPresetSet, 1, i, 1, 1) btnPresetSet.setText("Set") btnPresetSet.clicked.connect(self.storePreset) layout.addLayout(presets, 4, 0, 3, 6) def keyPressEvent(self, e): if e.key() == Qt.Key_Left: self.btnLeft.pressed.emit() elif e.key() == Qt.Key_Right: self.btnRight.pressed.emit() elif e.key() == Qt.Key_Up: self.btnUp.pressed.emit() elif e.key() == Qt.Key_Down: self.btnDown.pressed.emit() def keyReleaseEvent(self, e): if e.key() == Qt.Key_Left: self.btnLeft.released.emit() elif e.key() == Qt.Key_Right: self.btnRight.released.emit() elif e.key() == Qt.Key_Up: self.btnUp.released.emit() elif e.key() == Qt.Key_Down: self.btnDown.released.emit() def move(self): sender = self.sender() try: result = self.controller.move(self.cameraID, sender.cameraBinding) self.deselectPreset() return result except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def stop(self): try: self.controller.move(self.cameraID, CameraMove.Stop) except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def focus(self): sender = self.sender() try: result = self.controller.focus(self.cameraID, sender.cameraBinding) self.deselectPreset() return result except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def stopFocus(self): try: self.controller.focus(self.cameraID, CameraFocus.Stop) except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def zoom(self): sender = self.sender() try: result = self.controller.zoom(self.cameraID, sender.cameraBinding) self.deselectPreset() return result except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def stopZoom(self): try: self.controller.zoom(self.cameraID, CameraZoom.Stop) except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def exposure(self): sender = self.sender() try: result = self.controller.backlightComp(self.cameraID, sender.cameraBinding) self.deselectPreset() return result except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def storePreset(self): sender = self.sender() try: result = self.controller.savePreset(self.cameraID, sender.cameraBinding) self.presetGroup.buttons()[sender.cameraBinding].setChecked(True) return result except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def recallPreset(self): sender = self.sender() try: return self.controller.recallPreset(self.cameraID, sender.cameraBinding) except NamingError: self.errorBox(StringConstants.nameErrorText) except ProtocolError: self.errorBox(StringConstants.protocolErrorText) def deselectPreset(self): # Yuck. self.presetGroup.setExclusive(False) while (self.presetGroup.checkedId() >= 0): self.presetGroup.checkedButton().setChecked(False) self.presetGroup.setExclusive(True) def errorBox(self, text): msgBox = QMessageBox() msgBox.setText(text) msgBox.setIcon(QMessageBox.Critical) msgBox.exec_()
class ExposureControl(QWidget): class Mode(Enum): AUTO = 1 TV = 2 AV = 4 MANUAL = 8 def __or__(self, other): return self.value | other.value def __init__(self, camera): super(ExposureControl, self).__init__() self.camera = camera self.initUI() def initUI(self): layout = QGridLayout() title = QLabel("Exposure") title.setAlignment(Qt.AlignCenter) layout.addWidget(title, 0, 0, 1, 4) btnAuto = OptionButton() btnAuto.setText("Full Auto") _safelyConnect(btnAuto.clicked, self.camera.setAutoExposure) btnAuto.setChecked(True) layout.addWidget(btnAuto, 1, 0) btnTV = OptionButton() btnTV.setText("Tv") _safelyConnect(btnTV.clicked, self.camera.setShutterPriority) layout.addWidget(btnTV, 1, 1) btnAV = OptionButton() btnAV.setText("Av") _safelyConnect(btnAV.clicked, self.camera.setAperturePriority) layout.addWidget(btnAV, 1, 2) btnManual = OptionButton() btnManual.setText("M") _safelyConnect(btnManual.clicked, self.camera.setManualExposure) layout.addWidget(btnManual, 1, 3) layout.addWidget(QLabel("Aperture"), 2, 0) self.aperture = QComboBox(self) for a in list(Aperture): self.aperture.addItem(a.label, userData=a) self.aperture.currentIndexChanged.connect(self.setAperture) self.aperture.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.aperture.setEnabled(False) layout.addWidget(self.aperture, 2, 1, 1, 3) layout.addWidget(QLabel("Shutter"), 3, 0) self.shutter = QComboBox(self) for s in list(Shutter): self.shutter.addItem(s.label, userData=s) self.shutter.currentIndexChanged.connect(self.setShutter) self.shutter.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.shutter.setEnabled(False) layout.addWidget(self.shutter, 3, 1, 1, 3) layout.addWidget(QLabel("Gain"), 4, 0) self.gain = QComboBox(self) for g in list(Gain): self.gain.addItem(g.label, userData=g) self.gain.currentIndexChanged.connect(self.setGain) self.gain.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.gain.setEnabled(False) layout.addWidget(self.gain, 4, 1, 1, 3) self.exposureButtons = QButtonGroup() self.exposureButtons.addButton(btnAuto, self.Mode.AUTO.value) self.exposureButtons.addButton(btnTV, self.Mode.TV.value) self.exposureButtons.addButton(btnAV, self.Mode.AV.value) self.exposureButtons.addButton(btnManual, self.Mode.MANUAL.value) self.exposureButtons.buttonClicked.connect(self.onExposureMethodSelected) layout.setRowStretch(0, 0) layout.setRowStretch(1, 1) layout.setRowStretch(2, 1) layout.setRowStretch(3, 1) layout.setRowStretch(4, 1) self.setLayout(layout) def onExposureMethodSelected(self): checked = self.exposureButtons.checkedId() self.aperture.setEnabled(checked & (self.Mode.MANUAL | self.Mode.AV)) self.shutter.setEnabled(checked & (self.Mode.MANUAL | self.Mode.TV)) self.gain.setEnabled(checked & self.Mode.MANUAL.value) @handlePyroErrors def setAperture(self, idx): ap = self.aperture.itemData(idx) self.camera.setAperture(ap) @handlePyroErrors def setShutter(self, idx): sh = self.shutter.itemData(idx) self.camera.setShutter(sh) @handlePyroErrors def setGain(self, idx): g = self.gain.itemData(idx) self.camera.setGain(g)
class VideoSwitcher(QWidget): def __init__(self, controller, mainWindow): super(VideoSwitcher, self).__init__() self.controller = controller self.mainWindow = mainWindow self.setupUi() def setupUi(self): gridlayout = QGridLayout() self.setLayout(gridlayout) ''' Buttons added to inputs should have a numeric ID set equal to their input number on the Aldates main switcher. ''' self.inputs = QButtonGroup() inputsGrid = QHBoxLayout() self.btnCamera1 = CameraSelectionButton() self.btnCamera1.setText("Camera 1") inputsGrid.addWidget(self.btnCamera1) self.inputs.addButton(self.btnCamera1, 1) self.btnCamera1.setIcon(QIcon("icons/camera-video.svg")) self.btnCamera1.longpress.connect(lambda: self.showCameraAdvanced("Camera 1")) self.btnCamera2 = CameraSelectionButton() self.btnCamera2.setText("Camera 2") inputsGrid.addWidget(self.btnCamera2) self.inputs.addButton(self.btnCamera2, 2) self.btnCamera2.setIcon(QIcon("icons/camera-video.svg")) self.btnCamera2.longpress.connect(lambda: self.showCameraAdvanced("Camera 2")) self.btnCamera3 = CameraSelectionButton() self.btnCamera3.setText("Camera 3") inputsGrid.addWidget(self.btnCamera3) self.inputs.addButton(self.btnCamera3, 3) self.btnCamera3.setIcon(QIcon("icons/camera-video.svg")) self.btnCamera3.longpress.connect(lambda: self.showCameraAdvanced("Camera 3")) self.btnDVD = InputButton() self.btnDVD.setText("DVD") inputsGrid.addWidget(self.btnDVD) self.inputs.addButton(self.btnDVD, 4) self.btnDVD.setIcon(QIcon("icons/media-optical.svg")) self.btnExtras = InputButton() self.btnExtras.setText("Extras") inputsGrid.addWidget(self.btnExtras) self.btnExtras.setIcon(QIcon("icons/video-display.svg")) self.inputs.addButton(self.btnExtras, 5) self.btnVisualsPC = InputButton() self.btnVisualsPC.setText("Visuals PC") inputsGrid.addWidget(self.btnVisualsPC) self.inputs.addButton(self.btnVisualsPC, 6) self.btnVisualsPC.setIcon(QIcon("icons/computer.svg")) self.btnBlank = InputButton() self.btnBlank.setText("Blank") inputsGrid.addWidget(self.btnBlank) self.inputs.addButton(self.btnBlank, 0) gridlayout.addLayout(inputsGrid, 0, 0, 1, 7) self.extrasSwitcher = ExtrasSwitcher(self.controller) self.blank = QWidget(self) gridlayout.addWidget(self.blank, 1, 0, 1, 5) self.outputsGrid = OutputsGrid() gridlayout.addWidget(self.outputsGrid, 1, 5, 1, 2) gridlayout.setRowStretch(0, 1) gridlayout.setRowStretch(1, 5) QMetaObject.connectSlotsByName(self) self.setInputClickHandlers() self.setOutputClickHandlers(self.outputsGrid) self.configureInnerControlPanels() self.gridlayout = gridlayout def configureInnerControlPanels(self): self.panels = [ QWidget(), # Blank CameraControl(self.controller, "Camera 1") if self.controller.hasDevice("Camera 1") else QLabel(StringConstants.noDevice), CameraControl(self.controller, "Camera 2") if self.controller.hasDevice("Camera 2") else QLabel(StringConstants.noDevice), CameraControl(self.controller, "Camera 3") if self.controller.hasDevice("Camera 3") else QLabel(StringConstants.noDevice), QLabel(StringConstants.noDevice), # DVD - no controls self.extrasSwitcher if self.controller.hasDevice("Extras") else QLabel(StringConstants.noDevice), # Extras EclipseControls(self.controller, "Main Scan Converter") if self.controller.hasDevice("Main Scan Converter") else QLabel(StringConstants.noDevice), # Visuals PC ] def setInputClickHandlers(self): self.btnCamera1.clicked.connect(self.handleInputSelect) self.btnCamera2.clicked.connect(self.handleInputSelect) self.btnCamera3.clicked.connect(self.handleInputSelect) self.btnDVD.clicked.connect(self.handleInputSelect) self.btnExtras.clicked.connect(self.handleInputSelect) self.btnVisualsPC.clicked.connect(self.handleInputSelect) self.btnBlank.clicked.connect(self.handleInputSelect) def setOutputClickHandlers(self, outputsGrid): outputsGrid.connectMainOutputs(self.handleOutputSelect) ''' btnPCMix is a special case since that's on a different switcher ''' outputsGrid.connectPreviewOutputs(self.handlePCMixSelect) def keyPressEvent(self, e): if e.key() == Qt.Key_0: self.btnBlank.click() elif e.key() == Qt.Key_1: self.btnCamera1.click() elif e.key() == Qt.Key_2: self.btnCamera2.click() elif e.key() == Qt.Key_3: self.btnCamera3.click() elif e.key() == Qt.Key_4: self.btnDVD.click() elif e.key() == Qt.Key_5: self.btnExtras.click() elif e.key() == Qt.Key_6: self.btnVisualsPC.click() elif e.key() == Qt.Key_Space: self.outputsGrid.btnAll.click() else: self.panels[self.inputs.checkedId()].keyPressEvent(e) def keyReleaseEvent(self, e): self.panels[self.inputs.checkedId()].keyReleaseEvent(e) def handleInputSelect(self): inputID = self.inputs.checkedId() logging.debug("Input selected: " + str(inputID)) if inputID > 0: try: # HACK HACK HACK someone wired these up the wrong way around if inputID == 5: self.controller.switch("Preview", 6, 1) elif inputID == 6: self.controller.switch("Preview", 5, 1) else: self.controller.switch("Preview", inputID, 1) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText) self.gridlayout.removeWidget(self.gridlayout.itemAtPosition(1, 0).widget()) for p in self.panels: p.hide() chosenPanel = self.panels[inputID] self.gridlayout.addWidget(chosenPanel, 1, 0, 1, 5) chosenPanel.show() # Prevent certain options from being selectable if inputID == 6 or inputID == 0: self.outputsGrid.btnPCMix.setEnabled(False) else: self.outputsGrid.btnPCMix.setEnabled(True) def handleOutputSelect(self): outputChannel = self.sender().ID inputChannel = self.inputs.checkedId() if inputChannel == 5: self.extrasSwitcher.take() try: self.controller.switch("Main", inputChannel, outputChannel) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText) def handlePCMixSelect(self): outputChannel = self.sender().ID inputChannel = self.inputs.checkedId() if outputChannel != 2: raise RuntimeError("This isn't PC Mix...") try: if inputChannel == 5: self.extrasSwitcher.takePreview() # HACK HACK HACK someone wired these up the wrong way self.controller.switch("Preview", 6, outputChannel) elif inputChannel != 6: self.controller.switch("Preview", inputChannel, outputChannel) else: logging.error("Tried to send PC to PC Mix. Bad things would have happened!") except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText) def showCameraAdvanced(self, camDevice): ctls = AdvancedCameraControl(self.controller, camDevice, self.mainWindow) self.mainWindow.showScreen(ctls) def updateOutputMappings(self, mapping): self.outputsGrid.updateOutputMappings(mapping)
class BlindsControl(ScreenWithBackButton): ''' Controls for the blinds. ''' def __init__(self, controller, mainWindow): self.controller = controller ScreenWithBackButton.__init__(self, "Blinds", mainWindow) def makeContent(self): layout = QGridLayout() self.blinds = QButtonGroup() for i in range(1, 7): btn = IDedButton(i) btn.setText(str(i)) layout.addWidget(btn, 0, i - 1) btn.setCheckable(True) self.blinds.addButton(btn, i) btnAll = IDedButton(0) btnAll.setText("All") layout.addWidget(btnAll, 0, 6) btnAll.setCheckable(True) btnAll.setChecked(True) self.blinds.addButton(btnAll, 0) iconSize = QSize(96, 96) btnRaise = ExpandingButton() btnRaise.setText("Raise") btnRaise.setIcon(QIcon("icons/go-up.svg")) btnRaise.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnRaise, 1, 1, 1, 3) btnRaise.setIconSize(iconSize) btnRaise.clicked.connect(self.raiseUp) btnLower = ExpandingButton() btnLower.setText("Lower") btnLower.setIcon(QIcon("icons/go-down.svg")) btnLower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnLower, 2, 1, 1, 3) btnLower.setIconSize(iconSize) btnLower.clicked.connect(self.lowerDown) btnStop = ExpandingButton() btnStop.setText("Stop") btnStop.setIcon(QIcon("icons/process-stop.svg")) btnStop.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnStop, 1, 4, 2, 2) btnStop.setIconSize(iconSize) btnStop.clicked.connect(self.stop) return layout def raiseUp(self): blindID = self.blinds.checkedId() try: self.controller.raiseUp("Blinds", blindID) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText) def lowerDown(self): blindID = self.blinds.checkedId() try: self.controller.lower("Blinds", blindID) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText) def stop(self): blindID = self.blinds.checkedId() try: self.controller.stop("Blinds", blindID) except NamingError: self.mainWindow.errorBox(StringConstants.nameErrorText) except ProtocolError: self.mainWindow.errorBox(StringConstants.protocolErrorText)
class BlindsControl(ScreenWithBackButton): ''' Controls for the blinds. ''' def __init__(self, blindsDevice, mainWindow): self.blindsDevice = blindsDevice ScreenWithBackButton.__init__(self, "Blinds", mainWindow) def makeContent(self): layout = QGridLayout() self.blinds = QButtonGroup() for i in range(1, 7): btn = IDedButton(i) btn.setText(str(i)) layout.addWidget(btn, 0, i - 1) btn.setCheckable(True) self.blinds.addButton(btn, i) btnAll = IDedButton(0) btnAll.setText("All") layout.addWidget(btnAll, 0, 6) btnAll.setCheckable(True) btnAll.setChecked(True) self.blinds.addButton(btnAll, 0) btnRaise = SvgButton(":icons/go-up", 96, 96) btnRaise.setText("Raise") btnRaise.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnRaise, 1, 1, 1, 3) btnRaise.clicked.connect(self.raiseUp) btnLower = SvgButton(":icons/go-down", 96, 96) btnLower.setText("Lower") btnLower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) layout.addWidget(btnLower, 2, 1, 1, 3) btnLower.clicked.connect(self.lowerDown) btnStop = SvgButton(":icons/process-stop", 96, 96) btnStop.setText("Stop") btnStop.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon) layout.addWidget(btnStop, 1, 4, 2, 2) btnStop.clicked.connect(self.stop) return layout @handlePyroErrors def raiseUp(self): blindID = self.blinds.checkedId() self.blindsDevice.raiseUp(blindID) @handlePyroErrors def lowerDown(self): blindID = self.blinds.checkedId() self.blindsDevice.lower(blindID) @handlePyroErrors def stop(self): blindID = self.blinds.checkedId() self.blindsDevice.stop(blindID)
class AdvancedCameraControl(ScreenWithBackButton): def __init__(self, controller, cameraID, mainScreen): self.controller = controller self.cameraID = cameraID super(AdvancedCameraControl, self).__init__(cameraID, mainScreen) def makeContent(self): layout = QGridLayout() self.posDisplay = QGridLayout() self.posDisplay.addWidget(QLabel("Pan:"), 0, 0) self.posDisplay.addWidget(QLabel("Tilt:"), 1, 0) self.posDisplay.addWidget(QLabel("Zoom:"), 2, 0) self.posDisplay.addWidget(QLabel(), 0, 1) self.posDisplay.addWidget(QLabel(), 1, 1) self.posDisplay.addWidget(QLabel(), 2, 1) layout.addLayout(self.posDisplay, 1, 0) btnGetPos = ExpandingButton() btnGetPos.setText("Get Position") btnGetPos.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) layout.addWidget(btnGetPos, 2, 0) btnGetPos.clicked.connect(self.displayPosition) whiteBalanceGrid = QGridLayout() wbTitle = QLabel("White Balance") wbTitle.setAlignment(Qt.AlignCenter) whiteBalanceGrid.addWidget(wbTitle, 0, 0, 1, 2) btnAuto = OptionButton() btnAuto.setText("Auto") btnAuto.clicked.connect(lambda: self.controller.whiteBalance(self.cameraID, CameraWhiteBalance.Auto)) whiteBalanceGrid.addWidget(btnAuto, 1, 0) btnIndoor = OptionButton() btnIndoor.setText("Indoor") btnIndoor.clicked.connect(lambda: self.controller.whiteBalance(self.cameraID, CameraWhiteBalance.Indoor)) whiteBalanceGrid.addWidget(btnIndoor, 2, 0) btnOutdoor = OptionButton() btnOutdoor.setText("Outdoor") btnOutdoor.clicked.connect(lambda: self.controller.whiteBalance(self.cameraID, CameraWhiteBalance.Outdoor)) whiteBalanceGrid.addWidget(btnOutdoor, 3, 0) btnOnePush = OptionButton() btnOnePush.setText("One Push") btnOnePush.clicked.connect(lambda: self.controller.whiteBalance(self.cameraID, CameraWhiteBalance.OnePush)) whiteBalanceGrid.addWidget(btnOnePush, 4, 0) btnOnePushTrigger = ExpandingButton() btnOnePushTrigger.setText("Set") btnOnePushTrigger.clicked.connect(lambda: self.controller.whiteBalance(self.cameraID, CameraWhiteBalance.Trigger)) btnOnePushTrigger.setEnabled(False) whiteBalanceGrid.addWidget(btnOnePushTrigger, 4, 1) self.wbOpts = QButtonGroup() self.wbOpts.addButton(btnAuto, 1) self.wbOpts.addButton(btnIndoor, 2) self.wbOpts.addButton(btnOutdoor, 3) self.wbOpts.addButton(btnOnePush, 4) self.wbOpts.buttonClicked.connect(lambda: btnOnePushTrigger.setEnabled(self.wbOpts.checkedId() == 4)) layout.addLayout(whiteBalanceGrid, 1, 1, 2, 1) return layout def displayPosition(self): pos = self.controller.getPosition(self.cameraID) self.posDisplay.itemAtPosition(0, 1).widget().setText(str(pos.pan)) self.posDisplay.itemAtPosition(1, 1).widget().setText(str(pos.tilt)) self.posDisplay.itemAtPosition(2, 1).widget().setText(str(pos.zoom))