class Config(SignalNode.Config): """Config widget displayed for LSLInput.""" def __init__(self, parent=None): super().__init__(parent=parent) self.signal_name = QLineEdit("Signal") self.signal_name.editingFinished.connect(self.updateModel) layout = QFormLayout() self.setLayout(layout) layout.addRow("Signal name", self.signal_name) def updateModel(self): n = self.node() if n is None: return n.setSignalName(self.signal_name.text()) def updateView(self): n = self.node() if n is None: return self.signal_name.blockSignals(True) self.signal_name.setText(n.signalName()) self.signal_name.blockSignals(False)
class Config(SignalNode.Config): """Config widget displayed for LSLInput.""" def __init__(self, parent=None): super().__init__(parent=parent) layout = QFormLayout() self.setLayout(layout) self.vector = QLineEdit() self.vector.setPlaceholderText("Fp1=1;Cz=-1;...") self.vector.editingFinished.connect(self.updateModel) self.vector_path = PathEdit() dialog = QFileDialog(self, "Open") dialog.setFileMode(dialog.AnyFile) self.vector_path.setDialog(dialog) self.vector_path.pathChanged.connect(self.updateModel) # Vector data can be contained in a file or inputted directly from a file self.vector_radio_button = QRadioButton("Filter vector") self.vector_radio_button.toggled.connect(self.vector.setEnabled) self.vector_radio_button.clicked.connect(self.updateModel) self.vector_path_radio_button = QRadioButton("Filter vector file") self.vector_path_radio_button.toggled.connect(self.vector_path.setEnabled) self.vector_path_radio_button.clicked.connect(self.updateModel) layout.addRow(self.vector_radio_button, self.vector) layout.addRow(self.vector_path_radio_button, self.vector_path) self.vector_radio_button.setChecked(True) self.vector_path.setEnabled(False) def updateModel(self): n = self.node() if n is None: return if self.vector.isEnabled(): n.setVector(self.vector.text()) else: n.setVectorPath(self.vector_path.text()) def updateView(self): n = self.node() if n is None: return self.vector.blockSignals(True) self.vector_path.blockSignals(True) if n.vector() is not None: self.vector.setText(n.vector()) self.vector_radio_button.setChecked(True) else: self.vector_path.setText(n.vectorPath()) self.vector_path_radio_button.setChecked(True) self.vector.blockSignals(False) self.vector_path.blockSignals(False)
class CutoffMenu(QWidget): """This class assembles the cutoff menu from the other classes in this module.""" slider_change = Signal() def __init__(self, parent=None, cutoff_value=0.01, limit_type="percent"): super().__init__(parent) self.cutoff_value = cutoff_value self.limit_type = limit_type locale = QLocale(QLocale.English, QLocale.UnitedStates) locale.setNumberOptions(QLocale.RejectGroupSeparator) self.validators = Types(QDoubleValidator(0.001, 100.0, 1, self), QIntValidator(0, 50, self)) self.validators.relative.setLocale(locale) self.validators.topx.setLocale(locale) self.buttons = Types(QRadioButton("Relative"), QRadioButton("Top #")) self.buttons.relative.setChecked(True) self.buttons.relative.setToolTip( "This cut-off type shows the selected top percentage of contributions (for example the \ top 10% contributors)") self.buttons.topx.setToolTip( "This cut-off type shows the selected top number of contributions (for example the top \ 5 contributors)") self.button_group = QButtonGroup() self.button_group.addButton(self.buttons.relative, 0) self.button_group.addButton(self.buttons.topx, 1) self.sliders = Types(LogarithmicSlider(self), QSlider(Qt.Horizontal, self)) self.sliders.relative.setToolTip( "This slider sets the selected percentage of contributions\ to be shown") self.sliders.topx.setToolTip( "This slider sets the selected number of contributions to be \ shown") self.units = Types("% of total", "top #") self.labels = Labels(QLabel(), QLabel(), QLabel()) self.cutoff_slider_line = QLineEdit() self.cutoff_slider_line.setToolTip( "This box can set a precise cut-off value for the \ contributions to be shown") self.cutoff_slider_line.setLocale(locale) self.cutoff_slider_lft_btn = QPushButton("<") self.cutoff_slider_lft_btn.setToolTip( "This button moves the cut-off value one increment") self.cutoff_slider_rght_btn = QPushButton(">") self.cutoff_slider_rght_btn.setToolTip( "This button moves the cut-off value one increment") self.make_layout() self.connect_signals() def connect_signals(self): """Connect the signals of the menu.""" # Cut-off types self.buttons.relative.toggled.connect(self.cutoff_type_check) self.cutoff_slider_lft_btn.clicked.connect( self.cutoff_increment_left_check) self.cutoff_slider_rght_btn.clicked.connect( self.cutoff_increment_right_check) # Cut-off log slider self.sliders.relative.valueChanged.connect( lambda: self.cutoff_slider_relative_check("sl")) self.cutoff_slider_line.textChanged.connect( lambda: self.cutoff_slider_relative_check("le")) # Cut-off slider self.sliders.topx.valueChanged.connect( lambda: self.cutoff_slider_topx_check("sl")) self.cutoff_slider_line.textChanged.connect( lambda: self.cutoff_slider_topx_check("le")) @property def is_relative(self) -> bool: """Check if relative button is checked.""" return self.buttons.relative.isChecked() @Slot(name="incrementLeftCheck") def cutoff_increment_left_check(self): """Move the slider 1 increment to left when left button is clicked.""" if self.is_relative: num = int(self.sliders.relative.value()) self.sliders.relative.setValue(num + 1) else: num = int(self.sliders.topx.value()) self.sliders.topx.setValue(num - 1) @Slot(name="incrementRightCheck") def cutoff_increment_right_check(self): """Move the slider 1 increment to right when right button is clicked.""" if self.is_relative: num = int(self.sliders.relative.value()) self.sliders.relative.setValue(num - 1) else: num = int(self.sliders.topx.value()) self.sliders.topx.setValue(num + 1) @Slot(bool, name="isRelativeToggled") def cutoff_type_check(self, toggled: bool) -> None: """Dependent on cutoff-type, set the right labels. Slot connected to the relative radiobutton, the state of that button determines: - which sliders are visible - the unit shown - minimum and maximum - limit_type """ self.sliders.topx.setVisible(not toggled) self.sliders.relative.setVisible(toggled) self.sliders.relative.blockSignals(True) self.sliders.topx.blockSignals(True) self.cutoff_slider_line.blockSignals(True) if toggled: self.labels.unit.setText(self.units.relative) self.labels.min.setText("100%") self.labels.max.setText("0.001%") self.limit_type = "percent" self.cutoff_slider_line.setValidator(self.validators.relative) else: self.labels.unit.setText(self.units.topx) self.labels.min.setText(str(self.sliders.topx.minimum())) self.labels.max.setText(str(self.sliders.topx.maximum())) self.limit_type = "number" self.cutoff_slider_line.setValidator(self.validators.topx) self.sliders.relative.blockSignals(False) self.sliders.topx.blockSignals(False) self.cutoff_slider_line.blockSignals(False) @Slot(str, name="sliderRelativeCheck") def cutoff_slider_relative_check(self, editor: str): """If 'relative' selected, change the plots and tables to reflect the slider/line-edit.""" if not self.is_relative: return cutoff = 0.01 # If called by slider if editor == "sl": self.cutoff_slider_line.blockSignals(True) cutoff = abs(self.sliders.relative.log_value) self.cutoff_slider_line.setText(str(cutoff)) self.cutoff_slider_line.blockSignals(False) # if called by line edit elif editor == "le": self.sliders.relative.blockSignals(True) if self.cutoff_slider_line.text() == '-': cutoff = 0.001 self.cutoff_slider_line.setText("0.001") elif self.cutoff_slider_line.text() == '': cutoff = 0.001 else: cutoff = abs(float(self.cutoff_slider_line.text())) if cutoff > 100: cutoff = 100 self.cutoff_slider_line.setText(str(cutoff)) self.sliders.relative.log_value = float(cutoff) self.sliders.relative.blockSignals(False) self.cutoff_value = (cutoff / 100) self.slider_change.emit() @Slot(str, name="sliderTopXCheck") def cutoff_slider_topx_check(self, editor: str): """If 'top #' selected, change the plots and tables to reflect the slider/line-edit.""" if self.is_relative: return cutoff = 2 # If called by slider if editor == "sl": self.cutoff_slider_line.blockSignals(True) cutoff = abs(int(self.sliders.topx.value())) self.cutoff_slider_line.setText(str(cutoff)) self.cutoff_slider_line.blockSignals(False) # if called by line edit elif editor == "le": self.sliders.topx.blockSignals(True) if self.cutoff_slider_line.text() == '-': cutoff = self.sliders.topx.minimum() self.cutoff_slider_line.setText( str(self.sliders.topx.minimum())) elif self.cutoff_slider_line.text() == '': cutoff = self.sliders.topx.minimum() else: cutoff = abs(int(self.cutoff_slider_line.text())) if cutoff > self.sliders.topx.maximum(): cutoff = self.sliders.topx.maximum() self.cutoff_slider_line.setText(str(cutoff)) self.sliders.topx.setValue(int(cutoff)) self.sliders.topx.blockSignals(False) self.cutoff_value = int(cutoff) self.slider_change.emit() def make_layout(self): """Assemble the layout of the cutoff menu. Construct the layout for the cutoff menu widget. The initial layout is set to 'relative'. """ layout = QHBoxLayout() # Cut-off types cutoff_type = QVBoxLayout() cutoff_type_label = QLabel("Cut-off type") # Cut-off slider cutoff_slider = QVBoxLayout() cutoff_slider_set = QVBoxLayout() cutoff_slider_label = QLabel("Cut-off level") self.sliders.relative.setInvertedAppearance(True) self.sliders.topx.setMinimum(1) self.sliders.topx.setMaximum(50) self.sliders.topx.setValue(self.cutoff_value) self.sliders.relative.log_value = self.cutoff_value cutoff_slider_minmax = QHBoxLayout() self.labels.min.setText("100%") self.labels.max.setText("0.001%") self.labels.unit.setText("% of total") cutoff_slider_ledit = QHBoxLayout() self.cutoff_slider_line.setValidator(self.validators.relative) self.cutoff_slider_lft_btn.setMaximumWidth(15) self.cutoff_slider_rght_btn.setMaximumWidth(15) # Assemble types cutoff_type.addWidget(cutoff_type_label) cutoff_type.addWidget(self.buttons.relative) cutoff_type.addWidget(self.buttons.topx) # Assemble slider set self.sliders.topx.setVisible(False) cutoff_slider_set.addWidget(cutoff_slider_label) cutoff_slider_minmax.addWidget(self.labels.min) cutoff_slider_minmax.addWidget(self.sliders.relative) cutoff_slider_minmax.addWidget(self.sliders.topx) cutoff_slider_minmax.addWidget(self.labels.max) cutoff_slider_set.addLayout(cutoff_slider_minmax) cutoff_slider_ledit.addWidget(self.cutoff_slider_line) cutoff_slider_ledit.addWidget(self.cutoff_slider_lft_btn) cutoff_slider_ledit.addWidget(self.cutoff_slider_rght_btn) cutoff_slider_ledit.addWidget(self.labels.unit) cutoff_slider_ledit.addStretch(1) cutoff_slider.addLayout(cutoff_slider_set) cutoff_slider.addLayout(cutoff_slider_ledit) # Assemble cut-off menu layout.addLayout(cutoff_type) layout.addWidget(vertical_line()) layout.addLayout(cutoff_slider) layout.addStretch() self.setLayout(layout)
class Converter(QWidget): def __init__(self): QWidget.__init__(self) self.c = CurrencyConverter(fallback_on_wrong_date=True) self.setWindowTitle('Converter') self.activefirstChoice = QLabel("", self) self.activelastChoice = QLabel("", self) self.firstValue = QLineEdit("0", self) self.lastValue = QLineEdit("0", self) self.firstChoice = QComboBox() self.lastChoice = QComboBox() layout = QHBoxLayout() layout.addWidget(self.firstChoice) layout.addWidget(self.firstValue) layout.addWidget(self.lastChoice) layout.addWidget(self.lastValue) self.setLayout(layout) for key in sorted(self.c.currencies): self.firstChoice.addItem(key) self.lastChoice.addItem(key) self.firstChoice.activated[str].connect(self.onchangefirstChoice) self.firstValue.textChanged[str].connect(self.onchangefirstValue) self.lastChoice.activated[str].connect(self.onchangelastChoice) self.lastValue.textChanged[str].connect(self.onchangelastValue) def onchangefirstChoice(self, text): self.activefirstChoice = text def onchangefirstValue(self, text): if text == "": self.firstValue.setText("0") else: self.lastValue.blockSignals(True) self.firstValue.setText(text) value = str( self.c.convert(float(text), str(self.firstChoice.currentText()), str(self.lastChoice.currentText()))) print(value) self.lastValue.setText(value) self.lastValue.blockSignals(False) self.lastValue.adjustSize() def onchangelastChoice(self, text): self.activelastChoice = text def onchangelastValue(self, text): if text != "": self.firstValue.blockSignals(True) self.lastValue.setText(text) value = str( self.c.convert(float(text), str(self.firstChoice.currentText()), str(self.lastChoice.currentText()))) print(value) self.firstValue.setText(value) self.firstValue.blockSignals(False) self.firstValue.adjustSize() else: self.lastValue.setText("0")
class Socket(QFrame): """One socket with label and text entry""" def __init__(self, master, letter, connect_plug, charset): """ :param master: Qt parent object :param letter: Letter to serve as the label :param connect_plug: calls parent to connect with the letter typed in the entry box :param charset: {str} Allowed letters """ super().__init__(master) # QT WINDOW SETTINGS =================================================== layout = QVBoxLayout(self) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # ATTRIBUTES =========================================================== self.connect_plug = connect_plug self.letter = letter self.connected_to = None self.marking = None self.charset = charset # ENTRY ================================================================ label = QLabel(letter) label.setStyleSheet("font-size: 30px; text-align: center;") self.entry = QLineEdit() self.entry.setMaxLength(1) self.entry.textChanged.connect(self.entry_event) self.entry.setFixedSize(40, 40) self.entry.setAlignment(Qt.AlignCenter) # SHOW WIDGETS layout.addWidget(label, alignment=Qt.AlignCenter) layout.addWidget(self.entry, alignment=Qt.AlignCenter) def pair(self): """Returns currently wired pair.""" if self.connected_to: return self.letter + self.connected_to return None def entry_event(self): """Responds to a event when something changes in the plug entry""" letter = self.entry.text().upper() if letter not in self.charset: self.set_text("", True) elif self.entry.isModified(): # Prevents recursive event calls if letter: self.connect_plug(self.letter, letter) else: self.connect_plug(self.letter, None) def set_text(self, letter, block_event=False, marking=None, uhr=False): """ Sets text to the plug entrybox and sets white (vacant) or black (occupied) background color :param letter: Sets text to the newly selected letter :param block_event: {bool} Starts blocking Qt signals if True :param marking: {str} Uhr marking (like 1a, 3b, ...) :param uhr: {bool} Colors sockets differently when True (when Uhr connected) """ stylesheet = ( "background-color: %s; color: %s; text-align: center; font-size: 30px;" ) if block_event: self.entry.blockSignals(True) self.setToolTip(None) if letter: color = ("black", "white") self.marking = marking else: color = ("white", "black") self.marking = None if uhr: if "a" in marking: color = ("red", "white") else: color = ("gray", "white") self.setToolTip(str(marking[0]) + marking[1]) self.entry.setStyleSheet(stylesheet % color) self.entry.setText(letter) self.connected_to = letter if block_event: self.entry.blockSignals(False)