def set_layout( self, layout: LayoutStr | QtWidgets.QLayout | None, margin: int | None = None, spacing: int | None = None, ): if layout is None: return if layout == "horizontal": self.box = widgets.BoxLayout("horizontal") elif layout == "vertical": self.box = widgets.BoxLayout("vertical") elif layout == "grid": self.box = widgets.GridLayout() elif layout == "form": self.box = widgets.FormLayout() elif layout == "stacked": self.box = widgets.StackedLayout() elif layout == "flow": from prettyqt import custom_widgets self.box = custom_widgets.FlowLayout() elif isinstance(layout, QtWidgets.QLayout): self.box = layout else: raise ValueError("Invalid Layout") self.setLayout(self.box) if margin is not None: self.box.set_margin(margin) if spacing is not None: self.box.setSpacing(spacing)
def __init__(self, parent: QtWidgets.QWidget | None = None): super().__init__(parent) self.set_frame_shape("styled_panel") self.set_frame_shadow("plain") # layout self._layout = widgets.BoxLayout("vertical") self._layout.set_margin(0) self._layout.setSpacing(0) self.setLayout(self._layout) # button self._button = widgets.ToolButton(self) self._button.set_arrow_type("right") self._button.set_style("text_beside_icon") self._button.setAutoRaise(False) self._button.set_text("CollapsibleFrame") self.set_size_policy("minimum_expanding", "fixed") self._layout.addWidget(self._button, 0) self._button.setVisible(True) # group box self._panel = widgets.Widget(self) self._layout.addWidget(self._panel) self._panel.setVisible(False) self._panel_layout = widgets.BoxLayout("vertical") self._panel_layout.set_margin(1) self._panel_layout.setSpacing(2) self._panel.setLayout(self._panel_layout) # connect signals self._button.clicked.connect(self.on_button_click) # private state variables self._is_collapsed = True
def add_custom( self, label: str = "Other", typ: TypeStr = "string", default: None | float | str = None, regex: str | None = None, ): if typ == "string": self.widget_custom = widgets.LineEdit() elif typ == "int": self.widget_custom = widgets.SpinBox() elif typ == "float": self.widget_custom = widgets.DoubleSpinBox() else: raise ValueError(typ) # TODO: Enable this or add BAR radio and option. self.widget_custom.set_disabled() # type: ignore if default is not None: self.widget_custom.set_value(default) # type: ignore self.rb_other.setText(label) self.rb_other.toggled.connect( self.widget_custom.set_enabled) # type: ignore self.widget_custom.value_changed.connect( # type: ignore lambda: self.update_choice(True)) if regex and typ == "string": self.widget_custom.set_regex_validator(regex) # type: ignore layout = widgets.BoxLayout("horizontal") layout.add(self.rb_other) layout.add(self.widget_custom) self.box.add(layout)
def createEditor( self, parent: QtWidgets.QWidget, option: QtWidgets.QStyleOptionViewItem, index: QtCore.QModelIndex, ) -> widgets.Widget: editor = widgets.Widget(parent) editor.set_margin(0) editor.setAutoFillBackground(True) # create a button group to keep track of the checked radio editor.button_group = widgets.ButtonGroup() # adding the widget as an argument to the layout constructor automatically # applies it to the widget layout = widgets.BoxLayout("horizontal", parent=editor) layout.set_margin(0) for i, k in enumerate(self.items): rb = widgets.RadioButton(k) layout.addWidget(rb) # prevent the radio to get focus from keyboard or mouse rb.set_focus_policy("none") rb.installEventFilter(self) editor.button_group.addButton(rb, i) # add a stretch to always align contents to the left layout.addStretch(1) # set a property that will be used for the mask editor.setProperty("offMask", gui.Region(editor.rect())) # type: ignore editor.installEventFilter(self) return editor
def test_widget(): widget = widgets.Widget() layout = widgets.BoxLayout() widget.set_layout(layout) with open("data.pkl", "wb") as jar: pickle.dump(widget, jar) with open("data.pkl", "rb") as jar: widget = pickle.load(jar) with widget.block_signals(): pass widget.set_enabled() widget.set_disabled() widget.set_min_size(1, 1) widget.set_max_size(2, 2) widget.title = "test" assert widget.title == "test" with widget.updates_off(): widget.set_title("test2") widget.enabled = True assert widget.enabled is True widget.set_modality("window") with pytest.raises(ValueError): widget.set_modality("test") assert widget.get_modality() == "window" widget.center() widget.set_layout("horizontal") widget.set_layout("form") widget.set_layout("stacked") widget.set_layout("flow")
def __init__(self, labels, orientation="horizontal", parent=None): super().__init__(parent=parent) if not isinstance(labels, (tuple, list)): raise Exception("<labels> is a list or tuple.") levels = range(len(labels)) self.levels = list(zip(levels, labels)) self.layout = widgets.BoxLayout(orientation, self) # gives some space to print labels self.left_margin = 10 self.top_margin = 10 self.right_margin = 10 self.bottom_margin = 10 self.layout.set_margin(10) self.sl = widgets.Slider(orientation) self.sl.value_changed.connect(self.value_changed) self.sl.set_range(0, len(labels) - 1) self.sl.set_value(0) if orientation == QtCore.Qt.Horizontal: self.sl.set_tick_position("below") self.sl.setMinimumWidth(300) else: self.sl.set_tick_position("left") self.sl.setMinimumHeight(300) self.sl.setTickInterval(1) self.sl.setSingleStep(1) self.layout.addWidget(self.sl)
def __init__( self, target_widget: QtWidgets.QWidget, use_global_css: bool = False, use_queue: bool = True, max_messages: int = 2, ): """Constructor. Arguments: target_widget : QtWidgets.QWidget The widget to project the notifications on use_global_css : bool (default: False) Flag which indicates whether global style sheets should be used (which have been set at app-level). If False, the default style sheets stored at DEFAULT_NOTIFICATION_STYLES will be loaded. use_queue : bool (default: True) Indicates whether a message queue should be implemented. This will only show *max_messages* at the same time and will put all other messages in a queue. Once a message disappears, the next one in the queue will be shown (up to max_messages at the same time) max_messages : int (default: 2) The number of messages to display at the same time. Raises: TypeError : target_widget is not an object that inherits QWidget """ if not isinstance(target_widget, QtWidgets.QWidget): raise TypeError("target_widget is not a QWidget (or child of it") # Pop some variables from kwargs. self.use_queue = use_queue self.max_messages = max_messages super().__init__(parent=target_widget) if not use_global_css: self.setStyleSheet(DEFAULT_NOTIFICATION_STYLES) if self.use_queue: self.queue: Queue[Notification] = Queue() self.target_widget = target_widget self.set_margin(0) notification_area_layout = widgets.BoxLayout("vertical") self.setLayout(notification_area_layout) # Init effects to None self.entry_effect: FadeInValue = None self.entry_effect_duration = 250 self.exit_effect: FadeOutValue = None self.exit_effect_duration = 500 # Store original target classes resizeEvent to be called in our own # function self.target_resize_event = target_widget.resizeEvent # Overwrite resizeEvent function of target_widget to capture it ourself # (parent's resizeEvent will be called in our function too) self.target_widget.resizeEvent = self.resizeEvent # type: ignore self.hide()
def test_object(qapp): obj = core.Object() obj.set_id("test") with open("data.pkl", "wb") as jar: pickle.dump(obj, jar) with open("data.pkl", "rb") as jar: obj = pickle.load(jar) assert obj.get_id() == "test" w = widgets.Splitter("horizontal") w1 = widgets.PushButton() w1.set_id("w1") w2 = widgets.PlainTextEdit() w2.set_id("w2") w3 = widgets.MainWindow() w3.set_id("w3") w4 = widgets.TableView() w4.set_id("w4") w.add(w1, w2, w3, w4) assert w.find_children(widgets.PushButton, recursive=False) == [w1] assert w.find_children(core.Object, name="w2", recursive=False) == [w2] assert w.find_child(widgets.PlainTextEdit, recursive=True) == w2 assert w.find_child(core.Object, name="w2", recursive=False) == w2 assert w2.find_parent(widgets.Splitter) == w layout = widgets.BoxLayout("vertical") layout.add(w)
def __init__(self, parent=None): super().__init__(parent) self.layout = widgets.BoxLayout("horizontal") self.rb_other = widgets.RadioButton("Other") self.buttons = dict() # self.rb_comma.setChecked(True) self.setLayout(self.layout)
def __init__( self, label: str = "", layout: Literal["horizontal", "vertical"] = "vertical", parent: QtWidgets.QWidget | None = None, ): super().__init__(title=label, parent=parent) self.box = widgets.BoxLayout(layout) self.buttons: dict[widgets.CheckBox, int] = {} self.set_layout(self.box)
def test_widget(): widget = widgets.Widget() layout = widgets.BoxLayout() widget.set_layout(layout) with open("data.pkl", "wb") as jar: pickle.dump(widget, jar) with open("data.pkl", "rb") as jar: widget = pickle.load(jar) with widget.block_signals(): pass widget.set_enabled() widget.set_disabled()
def test_groupbox(): widget = widgets.GroupBox() ly = widgets.BoxLayout("horizontal") widget.set_layout(ly) ly += widgets.RadioButton("+=") widget.set_alignment("left") with open("data.pkl", "wb") as jar: pickle.dump(widget, jar) with open("data.pkl", "rb") as jar: widget = pickle.load(jar) widget.set_enabled(False) repr(widget)
def __init__(self, parent=None, text=None): super().__init__(parent=parent) self.timer = core.Timer.single_shot(callback=self.close) self.label = widgets.Label() self.setWindowFlags(self.windowFlags() | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint) layout = widgets.BoxLayout("vertical") layout.setContentsMargins(20, 20, 20, 20) self.setLayout(layout) self.setStyleSheet("background-color: black;") # 2a82da layout.addWidget(self.label)
def __init__( self, label: str = "", layout: constants.OrientationStr = "horizontal", parent: QtWidgets.QWidget | None = None, ): super().__init__(title=label, parent=parent) self.box = widgets.BoxLayout(layout) self.widget_custom: widgets.Widget | None = None self.rb_other = widgets.RadioButton() self.buttons: dict[widgets.RadioButton, Any] = {} self.set_layout(self.box)
def test_boxlayout(): layout = widgets.BoxLayout("horizontal", margin=0) widget = widgets.RadioButton("test") layout += widget layout2 = widgets.BoxLayout("horizontal") layout += layout2 assert layout[1] == layout2 layout.set_size_mode("maximum") assert layout.get_size_mode() == "maximum" layout.set_alignment("left") # assert layout.get_alignment() == "left" with pytest.raises(ValueError): layout.set_size_mode("bla") layout.set_margin(0) with open("data.pkl", "wb") as jar: pickle.dump(layout, jar) with open("data.pkl", "rb") as jar: layout = pickle.load(jar) assert len(layout) == 2 repr(layout) layout.add_stretch(1) layout.add_spacing(1)
def __init__(self, font=None, parent=None): super().__init__(parent) self.current_font = font layout = widgets.BoxLayout("horizontal", self) layout.set_margin(0) self.lineedit = widgets.LineEdit() self.lineedit.set_read_only() layout += self.lineedit action = widgets.Action() action.triggered.connect(self.choose_font) self.button = widgets.ToolButton() self.button.setDefaultAction(action) layout += self.button
def __init__(self, parent: QtWidgets.QWidget | None = None, text: str | None = None): super().__init__(parent=parent) self.timer = core.Timer.single_shot(callback=self.close) self.label = widgets.Label() self.set_flags(stay_on_top=True, frameless=True, tool=True) layout = widgets.BoxLayout("vertical") layout.set_margin(20) self.set_layout(layout) self.set_background_color("black") self.label.set_color("white") layout.add(self.label)
def __init__(self, parent: QtWidgets.QWidget | None = None): super().__init__(parent) layout = widgets.BoxLayout("horizontal") row_nb = 14 cindex = 0 for k, v in widgets.style.STANDARD_PIXMAP.items(): if cindex == 0: col_layout = widgets.BoxLayout("vertical") icon_layout = widgets.BoxLayout("horizontal") icon = widgets.Application.get_style_icon(k) label = widgets.Label() label.setPixmap(icon.pixmap(32, 32)) icon_layout.addWidget(label) icon_layout.addWidget(widgets.LineEdit(k)) col_layout.addLayout(icon_layout) cindex = (cindex + 1) % row_nb if cindex == 0: layout.addLayout(col_layout) self.set_layout(layout) self.set_title("Standard Platform Icons") icon = widgets.Application.get_style_icon("titlebar_menu_button") self.set_icon(icon)
def __init__(self, color=None, parent=None): super().__init__(parent) layout = widgets.BoxLayout("horizontal", self) layout.set_margin(0) self.lineedit = widgets.LineEdit() self.lineedit.set_regex_validator(r"^#(?:[0-9a-fA-F]{6})$") layout += self.lineedit action = widgets.Action(icon="mdi.format-color-fill") action.triggered.connect(self.choose_color) self.button = widgets.ToolButton() self.button.setDefaultAction(action) layout += self.button if color is not None: self.set_color(color)
def add_widget_as_dock(self, name: str, title: str, vertical: bool = True, position: str = "left") -> widgets.DockWidget: dock_widget = widgets.DockWidget(self, name=name, title=title) widget = widgets.Widget() widget.id = f"{name}.widget" orientation = "vertical" if vertical else "horizontal" layout = widgets.BoxLayout(orientation, widget, margin=0) dock_widget.setWidget(widget) self.add_dockwidget(dock_widget, position) dock_widget.box = layout return dock_widget
def test_boxlayout(): layout = widgets.BoxLayout("horizontal") widget = widgets.RadioButton("test") layout += widget layout.set_size_mode("maximum") with pytest.raises(ValueError): layout.set_size_mode("bla") layout.set_margin(0) with open("data.pkl", "wb") as jar: pickle.dump(layout, jar) with open("data.pkl", "rb") as jar: layout = pickle.load(jar) assert len(layout) == 1 repr(layout)
def setup_title_bar(self): title_bar = widgets.Widget() layout = widgets.BoxLayout("horizontal") layout.set_alignment("right") title_bar.setLayout(layout) maximise_button = widgets.PushButton() layout.addWidget(maximise_button) maximise_button.set_style_icon("maximise") maximise_button.clicked.connect(self.maximise) close_button = widgets.PushButton() close_button.set_style_icon("close") layout.addWidget(close_button) close_button.clicked.connect(self.close) self.setTitleBarWidget(title_bar)
def __init__(self, title: str = "", parent: QtWidgets.QWidget | None = None): super().__init__(checkable=False, title=title) self.set_layout("vertical") self.rb_lineedit = widgets.RadioButton("String") self.lineedit = widgets.LineEdit() self.rb_spinbox = widgets.RadioButton("Number") self.spinbox = widgets.DoubleSpinBox() layout_lineedit = widgets.BoxLayout("horizontal") layout_lineedit.add(self.rb_lineedit) layout_lineedit.add(self.lineedit) layout_spinbox = widgets.BoxLayout("horizontal") layout_spinbox.add(self.rb_spinbox) layout_spinbox.add(self.spinbox) self.box.add(layout_lineedit) self.box.add(layout_spinbox) self.rb_spinbox.toggled.connect(self.spinbox.setEnabled) self.rb_spinbox.toggled.connect(self.lineedit.setDisabled) self.rb_lineedit.toggled.connect(self.lineedit.setEnabled) self.rb_lineedit.toggled.connect(self.spinbox.setDisabled) self.spinbox.value_changed.connect(self.on_value_change) self.lineedit.value_changed.connect(self.on_value_change) self.rb_lineedit.setChecked(True)
def __init__(self, parent: QtWidgets.QWidget | None = None): super().__init__(parent) # Remove window title bar and frame self.setWindowFlags(QtCore.Qt.WindowFlag.Window # type: ignore | QtCore.Qt.WindowFlag.FramelessWindowHint) self.title_bar = CustomTitleBar(self) self.main_widget = widgets.MainWindow() # Set up layout self.main_layout = widgets.BoxLayout("vertical") self.main_layout.addWidget(self.title_bar) self.main_layout.addWidget(self.main_widget) self.main_layout.setContentsMargins(0, 0, 0, 0) self.main_layout.setSpacing(0) self.grip_layout = widgets.GridLayout() self.grip_layout.addLayout(self.main_layout, 1, 1) self.grip_layout.addWidget(EdgeGrip("top"), 0, 1) self.grip_layout.addWidget(EdgeGrip("right"), 1, 2) self.grip_layout.addWidget(EdgeGrip("bottom"), 2, 1) self.grip_layout.addWidget(EdgeGrip("left"), 1, 0) self.grip_layout.addWidget(EdgeGrip("top_left"), 0, 0) self.grip_layout.addWidget(EdgeGrip("top_right"), 0, 2) self.grip_layout.addWidget(EdgeGrip("bottom_left"), 2, 0) self.grip_layout.addWidget(EdgeGrip("bottom_right"), 2, 2) self.grip_layout.setContentsMargins(0, 0, 0, 0) self.grip_layout.setSpacing(0) self.setLayout(self.grip_layout) if sys.platform == "win32": self.hwnd = self.winId().__int__() window_style = win32gui.GetWindowLong(self.hwnd, GWL_STYLE) win32gui.SetWindowLong( self.hwnd, GWL_STYLE, window_style | WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, )
def set_layout(self, layout): if layout in ["horizontal", "vertical"]: self.box = widgets.BoxLayout(layout) elif layout == "grid": self.box = widgets.GridLayout() elif layout == "form": self.box = widgets.FormLayout() elif layout == "stacked": self.box = widgets.StackedLayout() elif layout == "flow": from prettyqt import custom_widgets self.box = custom_widgets.FlowLayout() else: self.box = layout if self.box is not None: self.setLayout(self.box)
def __init__(self, extensions=None, mode="save", parent=None): super().__init__(parent) self.path = None self.extensions = extensions self.mode = mode layout = widgets.BoxLayout("horizontal", self) layout.set_margin(0) self.lineedit = widgets.LineEdit() self.lineedit.set_read_only() layout += self.lineedit action = widgets.Action() action.set_icon("mdi.file-outline") action.triggered.connect(self.open_file) self.button = widgets.ToolButton() self.button.setDefaultAction(action) layout += self.button
def add_widget_as_dock( self, name: str, title: str, vertical: bool = True, position: constants.DockPositionStr = "left", ) -> widgets.DockWidget: dock_widget = widgets.DockWidget(self, name=name, title=title) widget = widgets.Widget() widget.set_id(f"{name}.widget") layout = widgets.BoxLayout( "vertical" if vertical else "horizontal", widget, margin=0 ) dock_widget.setWidget(widget) self.add_dockwidget(dock_widget, position) dock_widget.box = layout return dock_widget
def __init__( self, color: types.ColorType = None, parent: QtWidgets.QWidget | None = None ): super().__init__(parent) layout = widgets.BoxLayout("horizontal", self) layout.set_margin(0) self.lineedit = widgets.LineEdit() self.lineedit.set_regex_validator(r"^#(?:[0-9a-fA-F]{6})$") layout.add(self.lineedit) action = widgets.Action(icon="mdi.format-color-fill") action.triggered.connect(self.choose_color) self.button = widgets.ToolButton() self.button.setDefaultAction(action) layout.add(self.button) self._current_color: gui.Color = gui.Color("white") if color is not None: self.set_current_color(color)
def __init__(self, title: str = "", icon=None, parent=None, delete_on_close: bool = True, layout: Optional[str] = None): super().__init__(parent=parent) if self.DEFAULT_SIZE: self.resize(*self.DEFAULT_SIZE) self.title = title self.set_icon(icon) if delete_on_close: self.delete_on_close() self.box = None if layout in ["horizontal", "vertical"]: self.box = widgets.BoxLayout(layout) self.set_layout(self.box)
def __init__( self, bounds: tuple[int, int] | None = None, parent: QtWidgets.QWidget | None = None, ): super().__init__(parent) self.path = None layout = widgets.BoxLayout("horizontal", self) layout.set_margin(0) self.spinbox = widgets.SpinBox() layout.add(self.spinbox) self.slider = widgets.Slider() layout.add(self.slider) if bounds: self.set_range(*bounds) self.spinbox.valueChanged.connect(self.slider.set_value) self.slider.valueChanged.connect(self.spinbox.set_value) self.spinbox.valueChanged.connect(self.value_changed)