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 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 PeriodicTableWidget(QWidget): selectionChanged = Signal() def __init__(self, parent=None): QWidget.__init__(self, parent) # Widgets, layouts and signals self._group = QButtonGroup() layout = QGridLayout() layout.setSpacing(0) for i in range(18): layout.setColumnMinimumWidth(i, 40) layout.setColumnStretch(i, 0) for i in list(range(7)) + [8, 9]: layout.setRowMinimumHeight(i, 40) layout.setRowStretch(i, 0) ## Element for z, position in _ELEMENT_POSITIONS.items(): widget = ElementPushButton(z) widget.setCheckable(True) layout.addWidget(widget, *position) self._group.addButton(widget, z) ## Labels layout.addWidget(QLabel(''), 7, 0) # Dummy layout.addWidget(QLabel('*'), 5, 2, Qt.AlignCenter) layout.addWidget(QLabel('*'), 8, 2, Qt.AlignCenter) layout.addWidget(QLabel('**'), 6, 2, Qt.AlignCenter) layout.addWidget(QLabel('**'), 9, 2, Qt.AlignCenter) for row in [0, 1, 2, 3, 4, 5, 6, 8, 9]: layout.setRowStretch(row, 1) self.setLayout(layout) # Signals self._group.buttonClicked.connect(self.selectionChanged) # Default self.setColorFunction(_category_color_function) def setColorFunction(self, func): if not callable(func): raise ValueError('Not a function') self._color_function = func # Redraw for widget in self._group.buttons(): z = self._group.id(widget) bcolor = func(z) fcolor = 'white' if _calculate_brightness(bcolor) < 128 else 'black' sheet = 'background-color: %s; color: %s' % (bcolor.name(), fcolor) widget.setStyleSheet(sheet) def colorFunction(self): return self._color_function def setMultipleSelection(self, multiple): self._group.setExclusive(not multiple) def isMultipleSelection(self): return not self._group.exclusive() def setSelection(self, selection): def _uncheckedAll(): for widget in self._group.buttons(): widget.setChecked(False) if selection is None: _uncheckedAll() self.selectionChanged.emit() return if isinstance(selection, (int, six.string_types)): selection = [selection] if not self.isMultipleSelection() and len(selection) > 1: raise ValueError('Multiple selection mode is off. Cannot select more than one element') _uncheckedAll() for z in selection: if isinstance(z, six.string_types): z = ep.atomic_number(z.strip()) self._group.button(z).setChecked(True) self.selectionChanged.emit() # def selection(self): selection = set() for widget in self._group.buttons(): if widget.isChecked(): selection.add(self._group.id(widget)) if self.isMultipleSelection(): return frozenset(selection) else: if len(selection) > 0: return list(selection)[0] else: return None def selectionSymbol(self): selection = self.selection() if self.isMultipleSelection(): return frozenset(map(ep.symbol, selection)) else: if selection is None: return None else: return ep.symbol(selection)
class RecorderControl(ScreenWithBackButton): def __init__(self, hyperdeck, atem, state, mainWindow): self.hyperdeck = hyperdeck self.atem = atem self.state = state self.mainWindow = mainWindow super(RecorderControl, self).__init__("Recorder", mainWindow) self.state.transportChange.connect(self.updateState) if self.hyperdeck: self.updateState(state.transport) def makeContent(self): layout = QGridLayout() self.btnGroupSDCard = QButtonGroup() self.sdSlotMapper = QSignalMapper() for i in range(2): btn = ExpandingButton() btn.setCheckable(True) btn.setText("SD card {}".format(i + 1)) btn.clicked.connect(self.sdSlotMapper.map) self.sdSlotMapper.setMapping(btn, i + 1) self.btnGroupSDCard.addButton(btn, i) layout.addWidget(btn, 0, i) self.sdSlotMapper.mapped.connect(self.hyperdeck.selectSlot) self.btnSetPreview = ExpandingButton() self.btnSetPreview.setText("To preview") self.btnSetPreview.clicked.connect( lambda: self.atem.setPreview(VideoSource.INPUT_7)) layout.addWidget(self.btnSetPreview, 0, 4) btnClearPeaks = ExpandingButton() btnClearPeaks.setText("Clear VU peaks") btnClearPeaks.clicked.connect(self.atem.resetAudioMixerPeaks) layout.addWidget(btnClearPeaks, 0, 5) self.btnGroupTransportMode = QButtonGroup() self.btnPlaybackMode = ExpandingButton() self.btnPlaybackMode.setCheckable(True) self.btnPlaybackMode.setChecked(True) self.btnPlaybackMode.setText("Playback mode") self.btnGroupTransportMode.addButton(self.btnPlaybackMode) self.btnPlaybackMode.clicked.connect( lambda: self._setRecordMode(False)) layout.addWidget(self.btnPlaybackMode, 1, 1, 1, 2) self.btnRecordMode = ExpandingButton() self.btnRecordMode.setCheckable(True) self.btnRecordMode.setText("Record mode") self.btnGroupTransportMode.addButton(self.btnRecordMode) self.btnRecordMode.clicked.connect(lambda: self._setRecordMode(True)) layout.addWidget(self.btnRecordMode, 1, 3, 1, 2) self.btnSkipBack = _make_button("Back", ":icons/media-skip-backward", self.hyperdeck.prev) layout.addWidget(self.btnSkipBack, 2, 0) self.btngroup = QButtonGroup() self.btnPlay = _make_button("Play", ":icons/media-playback-start", self.hyperdeck.play) self.btnPlay.setCheckable(True) self.btngroup.addButton(self.btnPlay) layout.addWidget(self.btnPlay, 2, 1) self.btnLoopPlay = _make_button("Loop", ":icons/media-playback-loop", lambda: self.hyperdeck.play(loop=True)) layout.addWidget(self.btnLoopPlay, 2, 2) self.btnSkipForward = _make_button("Forward", ":icons/media-skip-forward", self.hyperdeck.next) layout.addWidget(self.btnSkipForward, 2, 3) self.btnStop = _make_button("Stop", ":icons/media-playback-stop", self.hyperdeck.stop) self.btnStop.setCheckable(True) self.btngroup.addButton(self.btnStop) layout.addWidget(self.btnStop, 2, 4) self.btnRecord = _make_button("Record", ":icons/media-record", self.hyperdeck.record) self.btnRecord.setCheckable(True) self.btnRecord.setEnabled(False) self.btngroup.addButton(self.btnRecord) layout.addWidget(self.btnRecord, 2, 5) self.clipSelectionScreen = RecorderClipSelectionScreen( self.hyperdeck, self.state, self.mainWindow) self.state.clipsListChange.connect( self.clipSelectionScreen.populateClipsList) self.state.transportChange.connect( self.clipSelectionScreen._updateClipSelectionFromState) self.btnChooseClip = ExpandingButton() self.btnChooseClip.setText("Select clip") self.btnChooseClip.clicked.connect(self._showClipSelection) layout.addWidget(self.btnChooseClip, 3, 1, 1, 2) layout.setRowStretch(0, 1) layout.setRowStretch(1, 1) layout.setRowStretch(2, 2) layout.setRowStretch(3, 1) return layout def updateState(self, state): if 'status' in state: self.btnRecord.setChecked(state['status'] == TransportState.RECORD) self.btnPlay.setChecked(state['status'] == TransportState.PLAYING) self.btnStop.setChecked( state['status'] != TransportState.RECORD and state['status'] != TransportState.PLAYING) currentSlot = state.get('active slot', 1) self.btnGroupSDCard.button(currentSlot - 1).setChecked(True) def _setRecordMode(self, isRecordMode): if isRecordMode: self.btnSkipBack.setEnabled(False) self.btnSkipForward.setEnabled(False) self.btnPlay.setEnabled(False) self.btnPlay.setChecked(False) self.btnLoopPlay.setEnabled(False) self.btnRecord.setEnabled(True) self.hyperdeck.setTransportMode(TransportMode.RECORD) else: self.btnSkipBack.setEnabled(True) self.btnSkipForward.setEnabled(True) self.btnPlay.setEnabled(True) self.btnLoopPlay.setEnabled(True) self.btnRecord.setEnabled(False) self.btnRecord.setChecked(False) self.hyperdeck.setTransportMode(TransportMode.PLAYBACK) def _showClipSelection(self): self.hyperdeck.broadcastClipsList() self.mainWindow.showScreen(self.clipSelectionScreen)
class RecorderControl(ScreenWithBackButton): def __init__(self, hyperdeck, atem, state, mainWindow): self.hyperdeck = hyperdeck self.atem = atem self.state = state self.mainWindow = mainWindow super(RecorderControl, self).__init__("Recorder", mainWindow) self.state.transportChange.connect(self.updateState) if self.hyperdeck: self.updateState(state.transport) def makeContent(self): layout = QGridLayout() self.btnGroupSDCard = QButtonGroup() self.sdSlotMapper = QSignalMapper() for i in range(2): btn = ExpandingButton() btn.setCheckable(True) btn.setText("SD card {}".format(i + 1)) btn.clicked.connect(self.sdSlotMapper.map) self.sdSlotMapper.setMapping(btn, i + 1) self.btnGroupSDCard.addButton(btn, i) layout.addWidget(btn, 0, i) self.sdSlotMapper.mapped.connect(self.hyperdeck.selectSlot) self.btnSetPreview = ExpandingButton() self.btnSetPreview.setText("To preview") self.btnSetPreview.clicked.connect(lambda: self.atem.setPreview(VideoSource.INPUT_7)) layout.addWidget(self.btnSetPreview, 0, 4) btnClearPeaks = ExpandingButton() btnClearPeaks.setText("Clear VU peaks") btnClearPeaks.clicked.connect(self.atem.resetAudioMixerPeaks) layout.addWidget(btnClearPeaks, 0, 5) self.btnGroupTransportMode = QButtonGroup() self.btnPlaybackMode = ExpandingButton() self.btnPlaybackMode.setCheckable(True) self.btnPlaybackMode.setChecked(True) self.btnPlaybackMode.setText("Playback mode") self.btnGroupTransportMode.addButton(self.btnPlaybackMode) self.btnPlaybackMode.clicked.connect(lambda: self._setRecordMode(False)) layout.addWidget(self.btnPlaybackMode, 1, 1, 1, 2) self.btnRecordMode = ExpandingButton() self.btnRecordMode.setCheckable(True) self.btnRecordMode.setText("Record mode") self.btnGroupTransportMode.addButton(self.btnRecordMode) self.btnRecordMode.clicked.connect(lambda: self._setRecordMode(True)) layout.addWidget(self.btnRecordMode, 1, 3, 1, 2) self.btnSkipBack = _make_button("Back", ":icons/media-skip-backward", self.hyperdeck.prev) layout.addWidget(self.btnSkipBack, 2, 0) self.btngroup = QButtonGroup() self.btnPlay = _make_button("Play", ":icons/media-playback-start", self.hyperdeck.play) self.btnPlay.setCheckable(True) self.btngroup.addButton(self.btnPlay) layout.addWidget(self.btnPlay, 2, 1) self.btnLoopPlay = _make_button("Loop", ":icons/media-playback-loop", lambda: self.hyperdeck.play(loop=True)) layout.addWidget(self.btnLoopPlay, 2, 2) self.btnSkipForward = _make_button("Forward", ":icons/media-skip-forward", self.hyperdeck.next) layout.addWidget(self.btnSkipForward, 2, 3) self.btnStop = _make_button("Stop", ":icons/media-playback-stop", self.hyperdeck.stop) self.btnStop.setCheckable(True) self.btngroup.addButton(self.btnStop) layout.addWidget(self.btnStop, 2, 4) self.btnRecord = _make_button("Record", ":icons/media-record", self.hyperdeck.record) self.btnRecord.setCheckable(True) self.btnRecord.setEnabled(False) self.btngroup.addButton(self.btnRecord) layout.addWidget(self.btnRecord, 2, 5) self.clipSelectionScreen = RecorderClipSelectionScreen(self.hyperdeck, self.state, self.mainWindow) self.state.clipsListChange.connect(self.clipSelectionScreen.populateClipsList) self.state.transportChange.connect(self.clipSelectionScreen._updateClipSelectionFromState) self.btnChooseClip = ExpandingButton() self.btnChooseClip.setText("Select clip") self.btnChooseClip.clicked.connect(self._showClipSelection) layout.addWidget(self.btnChooseClip, 3, 1, 1, 2) layout.setRowStretch(0, 1) layout.setRowStretch(1, 1) layout.setRowStretch(2, 2) layout.setRowStretch(3, 1) return layout def updateState(self, state): if 'status' in state: self.btnRecord.setChecked(state['status'] == TransportState.RECORD) self.btnPlay.setChecked(state['status'] == TransportState.PLAYING) self.btnStop.setChecked(state['status'] != TransportState.RECORD and state['status'] != TransportState.PLAYING) currentSlot = state.get('active slot', 1) self.btnGroupSDCard.button(currentSlot - 1).setChecked(True) def _setRecordMode(self, isRecordMode): if isRecordMode: self.btnSkipBack.setEnabled(False) self.btnSkipForward.setEnabled(False) self.btnPlay.setEnabled(False) self.btnPlay.setChecked(False) self.btnLoopPlay.setEnabled(False) self.btnRecord.setEnabled(True) self.hyperdeck.setTransportMode(TransportMode.RECORD) else: self.btnSkipBack.setEnabled(True) self.btnSkipForward.setEnabled(True) self.btnPlay.setEnabled(True) self.btnLoopPlay.setEnabled(True) self.btnRecord.setEnabled(False) self.btnRecord.setChecked(False) self.hyperdeck.setTransportMode(TransportMode.PLAYBACK) def _showClipSelection(self): self.hyperdeck.broadcastClipsList() self.mainWindow.showScreen(self.clipSelectionScreen)