class CheckBox(Widget): changed_signal = Signal() def __init__(self, parent, text="", check=False): # self._widget = QCheckBox(text, parent.get_container()) super().__init__(parent, QCheckBox(text, QParent(parent))) self.changed = SignalWrapper(self, "changed") # self.init_widget(parent) if check: self.setChecked(True) # self._widget.stateChanged.connect(self.__state_changed) self._qwidget.stateChanged.connect(self.__state_changed) def __state_changed(self): if not self.changed.inhibit: self.on_changed() def checked(self): return self._qwidget.isChecked() def check(self, checked=True): self.set_checked(checked) # FIXME: Rename: on_change? def on_changed(self): self.changed.emit() def set_checked(self, checked): self._qwidget.setChecked(checked) def uncheck(self): self.set_checked(False)
class CheckBox(QCheckBox, WidgetMixin): changed_signal = Signal() def __init__(self, parent, text="", check=False): # self._widget = QCheckBox(text, parent.get_container()) QCheckBox.__init__(self, text, parent.get_container()) self.changed = SignalWrapper(self, "changed") self.init_widget(parent) if check: self.setChecked(True) # self._widget.stateChanged.connect(self.__state_changed) self.stateChanged.connect(self.__state_changed) def __state_changed(self): if not self.changed.inhibit: self.on_changed() def is_checked(self): return self.isChecked() def check(self, checked=True): self.setChecked(checked) def on_changed(self): self.changed.emit()
def __init__( self, parent, text="", read_only=False, placeholder="", clearbutton=False, passwordMode=False, ): super().__init__(parent, QLineEdit(text, QParent(parent))) # Widget.__init__(self, parent) # self.init_widget(parent) self._qwidget.setReadOnly(read_only) self._has_text = text != "" self.update_color() # noinspection PyUnresolvedReferences self._qwidget.textChanged.connect(self.__on_text_changed) # noinspection PyUnresolvedReferences self._qwidget.returnPressed.connect(self.__on_return_pressed) self.changed = SignalWrapper(self, "changed") self.activated = SignalWrapper(self, "activated") if passwordMode: self._qwidget.setEchoMode(QLineEdit.Password) if placeholder: self._qwidget.setPlaceholderText(placeholder) if clearbutton: self._qwidget.setClearButtonEnabled(True) self.update_style()
def __init__(self, parent, min_value, max_value, initial_value): super().__init__() self.set_widget(QSpinBox(QParent(parent))) self._widget.setRange(min_value, max_value) self._widget.setValue(initial_value) self._widget.valueChanged.connect(self.__value_changed) self.changed = SignalWrapper(self, "changed")
class SpinCtrl(Widget): changed_signal = Signal() def __init__(self, parent, min_value, max_value, initial_value): super().__init__(parent, QSpinBox(QParent(parent))) self._widget.setRange(min_value, max_value) self._widget.setValue(initial_value) self._widget.valueChanged.connect(self.__value_changed) # FIXME: What did this to, again? self.changed = SignalWrapper(self, "changed") self.update_style() def update_style(self): theme = get_theme(self) padding = theme.textfield_padding() if not padding: # Indicates that we do not want custom styling return # There seems to be an issue with specifying padding-top and # padding-bottom for a QSpinBox. fontmetrics = QFontMetrics(self._widget.font()) fontheight = fontmetrics.height() print(fontheight) border = 4 min_height = fontheight + padding.top + padding.bottom + border self.set_min_height(min_height) print("MINHEIGHT (SPINCTRL)", min_height) # FIXME: This widget seems to have some margin error, the border is # drawn so that the widget height is two less than it should be. May # need to draw own border in order to get this right! (Sigh) self._widget.setStyleSheet( f""" QSpinBox {{ /* border: 0; margin: 0px; */ /* padding-top: 2px; padding-bottom: 2px; */ padding-right: {padding.right}px; padding-left: {padding.left}px; }} """ ) def get_value(self): return self._widget.value() def set_value(self, value): self._widget.setValue(value) def __value_changed(self, _): if not self.changed.inhibit: self.on_changed() def on_change(self): self.changed.emit()
def __init__(self, parent, min_value, max_value, initial_value): super().__init__(parent, QSpinBox(QParent(parent))) self._widget.setRange(min_value, max_value) self._widget.setValue(initial_value) self._widget.valueChanged.connect(self.__value_changed) # FIXME: What did this to, again? self.changed = SignalWrapper(self, "changed") self.update_style()
def __init__(self, parent, text="", check=False): # self._widget = QCheckBox(text, parent.get_container()) super().__init__(parent, QCheckBox(text, QParent(parent))) self.changed = SignalWrapper(self, "changed") # self.init_widget(parent) if check: self.setChecked(True) # self._widget.stateChanged.connect(self.__state_changed) self._qwidget.stateChanged.connect(self.__state_changed)
def __init__(self, parent, text="", read_only=False): QLineEdit.__init__(self, text, parent.get_container()) # Widget.__init__(self, parent) self.init_widget(parent) self.setReadOnly(read_only) # noinspection PyUnresolvedReferences self.textChanged.connect(self.__text_changed) # noinspection PyUnresolvedReferences self.returnPressed.connect(self.__return_pressed) self.changed = SignalWrapper(self, "changed") self.activated = SignalWrapper(self, "activated")
def __init__(self, parent, items=None, cursor_keys=True): if items is None: items = [] super().__init__(parent, QComboBox(QParent(parent))) self.inhibit_change_event = False self.cursor_keys = cursor_keys for i, item in enumerate(items): self._qwidget.insertItem(i, item) if len(items) > 0: self.set_index(0) self._qwidget.currentIndexChanged.connect( self.__on_current_index_changed) self.changed = SignalWrapper(self, "changed") self.update_style()
def __init__(self, parent, items=None): if items is None: items = [] QComboBox.__init__(self, parent.get_container()) # Widget.__init__(self, parent) self.init_widget(parent) self.inhibit_change_event = False for i, item in enumerate(items): self.insertItem(i, item) if len(items) > 0: self.set_index(0) self.currentIndexChanged.connect(self.__current_index_changed) self.changed = SignalWrapper(self, "changed")
def __init__(self, parent, text="", check=False): # self._widget = QCheckBox(text, parent.get_container()) QCheckBox.__init__(self, text, parent.get_container()) self.changed = SignalWrapper(self, "changed") self.init_widget(parent) if check: self.setChecked(True) # self._widget.stateChanged.connect(self.__state_changed) self.stateChanged.connect(self.__state_changed)
class TextField(QLineEdit, WidgetMixin): changed_signal = Signal() activated_signal = Signal() def __init__(self, parent, text="", read_only=False): QLineEdit.__init__(self, text, parent.get_container()) # Widget.__init__(self, parent) self.init_widget(parent) self.setReadOnly(read_only) # noinspection PyUnresolvedReferences self.textChanged.connect(self.__text_changed) # noinspection PyUnresolvedReferences self.returnPressed.connect(self.__return_pressed) self.changed = SignalWrapper(self, "changed") self.activated = SignalWrapper(self, "activated") def get_text(self): return self.text() def set_text(self, text): self.setText(text) def set_cursor_position(self, position): self.setCursorPosition(position) def on_changed(self): pass def __text_changed(self, _): self.changed.emit() self.on_changed() def select_all(self): self.selectAll() def __return_pressed(self): self.activated.emit()
class SpinCtrl(Widget): changed_signal = Signal() def __init__(self, parent, min_value, max_value, initial_value): super().__init__() self.set_widget(QSpinBox(QParent(parent))) self._widget.setRange(min_value, max_value) self._widget.setValue(initial_value) self._widget.valueChanged.connect(self.__value_changed) self.changed = SignalWrapper(self, "changed") def get_value(self): return self._widget.value() def set_value(self, value): self._widget.setValue(value) def __value_changed(self, _): if not self.changed.inhibit: self.on_changed() def on_change(self): self.changed.emit()
class TextField(Widget): changed_signal = Signal() activated_signal = Signal() # FIXME: Insert * after parent def __init__( self, parent, text="", read_only=False, placeholder="", clearbutton=False, passwordMode=False, ): super().__init__(parent, QLineEdit(text, QParent(parent))) # Widget.__init__(self, parent) # self.init_widget(parent) self._qwidget.setReadOnly(read_only) self._has_text = text != "" self.update_color() # noinspection PyUnresolvedReferences self._qwidget.textChanged.connect(self.__on_text_changed) # noinspection PyUnresolvedReferences self._qwidget.returnPressed.connect(self.__on_return_pressed) self.changed = SignalWrapper(self, "changed") self.activated = SignalWrapper(self, "activated") if passwordMode: self._qwidget.setEchoMode(QLineEdit.Password) if placeholder: self._qwidget.setPlaceholderText(placeholder) if clearbutton: self._qwidget.setClearButtonEnabled(True) self.update_style() def update_style(self): # There seems to be an issue with specifying padding-top and # padding-bottom for a QSpinBox. theme = get_theme(self) padding = theme.textfield_padding() if not padding: # Indicates that we do not want custom styling return fontmetrics = QFontMetrics(self._qwidget.font()) fontheight = fontmetrics.height() print(fontheight) border = 4 min_height = fontheight + padding.top + padding.bottom + border self.set_min_height(min_height) print("MINHEIGHT (TEXTFIELD)", min_height) has_text = self.text() != "" self._qwidget.setStyleSheet(f""" QLineEdit {{ color: {"#000000" if has_text else "#666666"}; padding-right: {padding.right}px; padding-left: {padding.left}px; }} """) def update_color(self): has_text = self.text() != "" if has_text != self._has_text: self._has_text = has_text self.update_style() # self.setStyleSheet(f""" # QLineEdit[text=""] {{ # color: {"#000000" if has_text else "#666666"}; # }} # """ # ) @deprecated def value(self): return self.text() @deprecated def get_text(self): return self.text() def on_changed(self): pass def __on_return_pressed(self): self.activated.emit() def __on_text_changed(self, _): self.update_color() self.changed.emit() self.on_changed() def select_all(self): self._qwidget.selectAll() def set_cursor_position(self, position): self._qwidget.setCursorPosition(position) def set_text(self, text): self._qwidget.setText(text) def text(self): return self._qwidget.text()
class Choice(Widget): changed_signal = Signal() item_selected = Signal(int) ITEM_SEPARATOR = "---" def __init__(self, parent, items=None, cursor_keys=True): if items is None: items = [] super().__init__(parent, QComboBox(QParent(parent))) self.inhibit_change_event = False self.cursor_keys = cursor_keys for i, item in enumerate(items): self._qwidget.insertItem(i, item) if len(items) > 0: self.set_index(0) self._qwidget.currentIndexChanged.connect( self.__on_current_index_changed) self.changed = SignalWrapper(self, "changed") self.update_style() # FIXME: This needs to be fixed def keyPressEvent(self, event): if not self.cursor_keys: print("cursor keys is false", event.key(), Qt.Key_Up) if event.key() == Qt.Key_Up or event.key() == Qt.Key_Down: print("ignoring") return super().keyPressEvent(event) # @contextmanager # def inhibit_signal(self, name): # attr = "_inhibit_" + name # old = getattr(self, attr, False) # print("setattr", self, attr, True) # setattr(self, attr, True) # yield # print("setattr", self, attr, old) # setattr(self, attr, old) def add_item(self, label, icon=None): # item = QStandardItem(label) # if icon: # item.setIcon(icon.qicon) # item.setSizeHint(QSize(-1, 24)) if label == self.ITEM_SEPARATOR: self._qwidget.insertSeparator(self.count()) elif icon is not None: self._qwidget.addItem(icon.qicon, label) else: self._qwidget.addItem(label) return self.count() - 1 def clear(self): return self._qwidget.clear() def count(self): return self._qwidget.count() def index(self): return self._qwidget.currentIndex() def on_changed(self): pass def __on_current_index_changed(self): # print("__current_index_changed", self.currentIndex(), # "inhibit", self.inhibit_change_event) if not self.inhibit_change_event: # print("Choice.__current_index_changed") # if not getattr(self, "_inhibit_changed", False): if not self.changed.inhibit: if not getattr(self, "_inhibit_item_selected", False): index = self._qwidget.currentIndex() self.item_selected.emit(index) self.changed.emit() self.on_changed() def remove_item(self, index): self._qwidget.removeItem(index) def set_index(self, index, signal=True): try: if not signal: self.inhibit_change_event = True self._qwidget.setCurrentIndex(-1 if index is None else index) finally: if not signal: self.inhibit_change_event = False def set_item_text(self, index, text): self._qwidget.setItemText(index, text) def update_style(self): # There seems to be an issue with specifying padding-top and # padding-bottom for a QComboBox. The internal pop menu also gets # padding added, resulting in ugly white borders at the top/bottom of # the popup, and there seems to be no way to remove this. So instead, # we calculate minimum height based on font height manually. theme = get_theme(self) padding = theme.choice_padding() if padding: fontmetrics = QFontMetrics(self._qwidget.font()) fontheight = fontmetrics.height() print(fontheight) # FIXME: Assumed border = 4 min_height = fontheight + padding.top + padding.bottom + border self.set_min_height(min_height) self._qwidget.setStyleSheet(f""" QComboBox {{ padding-right: 8px; padding-left: 8px; }} """)
class Choice(QComboBox, WidgetMixin): changed_signal = Signal() item_selected = Signal(int) ITEM_SEPARATOR = "---" def __init__(self, parent, items=None, cursor_keys=True): if items is None: items = [] QComboBox.__init__(self, parent.get_container()) # Widget.__init__(self, parent) self.init_widget(parent) self.inhibit_change_event = False self.cursor_keys = cursor_keys for i, item in enumerate(items): self.insertItem(i, item) if len(items) > 0: self.set_index(0) self.currentIndexChanged.connect(self.__current_index_changed) self.changed = SignalWrapper(self, "changed") # self.changed.inhibit = self.inhibit_signal def keyPressEvent(self, event): if not self.cursor_keys: print("cursor keys is false", event.key(), Qt.Key_Up) if event.key() == Qt.Key_Up or event.key() == Qt.Key_Down: print("ignoring") return super().keyPressEvent(event) # @contextmanager # def inhibit_signal(self, name): # attr = "_inhibit_" + name # old = getattr(self, attr, False) # print("setattr", self, attr, True) # setattr(self, attr, True) # yield # print("setattr", self, attr, old) # setattr(self, attr, old) def add_item(self, label, icon=None): # item = QStandardItem(label) # if icon: # item.setIcon(icon.qicon) # item.setSizeHint(QSize(-1, 24)) if label == self.ITEM_SEPARATOR: self.insertSeparator(self.count()) elif icon is not None: self.addItem(icon.qicon, label) else: self.addItem(label) return self.count() - 1 def remove_item(self, index): self.removeItem(index) def __current_index_changed(self): # print("__current_index_changed", self.currentIndex(), # "inhibit", self.inhibit_change_event) if not self.inhibit_change_event: # print("Choice.__current_index_changed") # if not getattr(self, "_inhibit_changed", False): if not self.changed.inhibit: if not getattr(self, "_inhibit_item_selected", False): index = self.currentIndex() self.item_selected.emit(index) self.changed.emit() self.on_changed() def get_index(self): return self.currentIndex() def set_index(self, index, signal=True): try: if not signal: self.inhibit_change_event = True self.setCurrentIndex(-1 if index is None else index) finally: if not signal: self.inhibit_change_event = False def set_item_text(self, index, text): self.setItemText(index, text) def on_changed(self): pass def __len__(self): return self.count()