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 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 add_button( self, button: QtWidgets.QPushButton | ButtonStr, role: RoleStr = "accept", callback: Callable | None = None, ) -> widgets.PushButton: """Add a button. Args: button: button to add role: role of the button callback: function to call when button gets clicked Returns: created button Raises: InvalidParamError: Button type not available """ if isinstance(button, str): button = widgets.PushButton(button) self.addButton(button, ROLES[role]) if callback: button.clicked.connect(callback) return button
def test_propertyanimation(): animation = core.PropertyAnimation() button = widgets.PushButton() animation.set_easing("in_cubic") assert animation.get_easing() == "in_cubic" animation.set_direction("forward") with pytest.raises(InvalidParamError): animation.set_direction("test") assert animation.get_direction() == "forward" assert animation.get_state() == "stopped" animation.setDuration(100) assert len(animation) == 100 animation.apply_to(button, "geometry") assert animation.get_property_name() == "geometry" animation.setEndValue(core.Rect(20, 50, 70, 89)) animation[0] = 1 assert animation[0] == 1 with pytest.raises(InvalidParamError): animation.start_animation("test") # TODO: this one breaks PySide2 test # animation.start_animation("keep") def test(val): return val animation.set_easing(test) # PySide2 looses custom fn here if prettyqt.qt.API.startswith("pyqt"): assert animation.get_easing() == test else: with pytest.raises(AttributeError): animation.get_easing()
def test_flowlayout(): widget = widgets.Widget() layout = custom_widgets.FlowLayout() btn = widgets.PushButton("Short") layout += btn layout += widgets.PushButton("Longer") layout += widgets.PushButton("Different text") layout += widgets.PushButton("More text") layout += widgets.PushButton("Even longer button text") widget.set_layout(layout) assert layout[0] == btn for i in range(len(layout)): pass layout.get_children() with open("data.pkl", "wb") as jar: pickle.dump(layout, jar) with open("data.pkl", "rb") as jar: layout = pickle.load(jar)
def __init__(self, label, value=None, check=True, use_push=False): super().__init__(label, value=value, check=check) if use_push: self.widget = widgets.PushButton() self.widget.setCheckable(True) else: self.widget = widgets.CheckBox() if value is not None: self.widget.set_value(value)
def createEditor(self, parent, option, index) -> widgets.PushButton: label = index.data() btn_callback = index.data(self.fn_role) btn = widgets.PushButton(label, parent) if not btn_callback: btn.set_disabled() else: btn.clicked.connect(btn_callback) return btn
def test_pushbutton(): widget = widgets.PushButton("Test") widget.set_disabled() widget.set_enabled() widget.set_icon("mdi.timer") widget.set_style_icon("close") with open("data.pkl", "wb") as jar: pickle.dump(widget, jar) with open("data.pkl", "rb") as jar: widget = pickle.load(jar)
def createEditor(self, parent, option, index) -> widgets.PushButton: label = index.data() btn_callback = index.data(self.fn_role) btn = widgets.PushButton(label, parent) if not btn_callback: btn.setEnabled(False) else: btn.clicked.connect(btn_callback) # btn.setStyleSheet("border:1px;") return btn
def test_flowlayout(): widget = widgets.Widget() layout = custom_widgets.FlowLayout(margin=1) btn = widgets.PushButton("Short") layout += btn layout += widgets.PushButton("Longer") layout += widgets.PushButton("Different text") layout += widgets.PushButton("More text") layout += widgets.PushButton("Even longer button text") layout.do_layout(core.Rect(), False) layout.sizeHint() widget.set_layout(layout) assert layout[0] == btn for i in layout: pass assert len(layout) == 5 layout.get_children() with open("data.pkl", "wb") as jar: pickle.dump(layout, jar) with open("data.pkl", "rb") as jar: layout = pickle.load(jar)
def test_pushbutton(): widget = widgets.PushButton("Test", callback=print) widget.set_disabled() widget.set_enabled() widget.set_icon("mdi.timer") widget.set_style_icon("close") with open("data.pkl", "wb") as jar: pickle.dump(widget, jar) with open("data.pkl", "rb") as jar: widget = pickle.load(jar) widget.is_on = False assert widget.is_on is False widget.set_value(True)
def add_button(self, button, role="accept", callback=None): """add a button Args: button: button to add role: role of the button callback: function to call when button gets clicked Returns: created button Raises: ValueError: Button type not available """ if isinstance(button, str): button = widgets.PushButton(button) self.addButton(button, ROLES[role]) if callback: button.clicked.connect(callback) return button
def __init__( self, message: str, category: CategoryStr, timeout=None, autohide: bool = False, buttontext: str | None = None, *args, **kwargs, ): super().__init__(*args, **kwargs) # Store instance variables self.message = message self.category = category self.timeout = timeout self.autohide = autohide # Set Object name for reference self.setObjectName(category) self.set_layout("horizontal", margin=0) # Create a message area message_area = widgets.BoxLayout("horizontal") message_area.set_margin(0) # Create the layout self.message_display = MessageLabel() self.message_display.setObjectName("message") self.message_display.set_size_policy("minimum", "minimum") self.message_display.setWordWrap(True) # Create a button that can close notifications if not buttontext: close_button = widgets.PushButton("\u2715") else: close_button = widgets.PushButton(buttontext) close_button.setStyleSheet("text-decoration: underline;") close_button.set_size_policy("fixed", "fixed") close_button.setFlat(True) close_button.setObjectName("closeButton") close_button.clicked.connect(self.close_clicked) # Add everything together message_area.addWidget(self.message_display) # message_area.addStretch(1) message_area.addWidget(close_button) self.layout().addLayout(message_area) # Initialize some variables # self.setStyle(category) self.setVisible(False) # Flag that is set if notification is being removed. This can be used to # make sure that even though the notification has not been really removed # yet (because it is for example in a fade out animation), it is in the # process of being removed self.is_being_removed = False self.is_fading_in = False self.opacity_effect = widgets.GraphicsOpacityEffect(self) # Fade in animation self.fade_in_anim = core.PropertyAnimation() self.fade_in_anim.apply_to(self.opacity_effect, "opacity") self.fade_in_anim.set_range(0.0, 1.0) # Fade out animation self.fade_out_anim = core.PropertyAnimation() self.fade_out_anim.apply_to(self.opacity_effect, "opacity") self.fade_in_anim.set_range(1.0, 0.0)
c.clearSelection() c.setCharFormat(old_fmt) if __name__ == "__main__": app = widgets.app() w = widgets.Widget() w.set_layout("vertical") widget = LogTextEdit() logger = logging.getLogger() def raise_exc(): try: raise Exception("test") except Exception as e: logger.exception(e) w.box.add(widgets.PushButton("Raise", callback=raise_exc)) w.box.add( widgets.PushButton("Debug", callback=lambda: logger.debug("Debug"))) w.box.add(widgets.PushButton("Info", callback=lambda: logger.info("Info"))) w.box.add( widgets.PushButton("Warning", callback=lambda: logger.warning("Warning"))) w.box.add( widgets.PushButton("Critical", callback=lambda: logger.critical("Critical"))) w.box.add(widget) w.show() app.main_loop()
def __init__(self): super().__init__() self.setMinimumSize(400, 300) self.set_title("Icon Browser") from prettyqt import iconprovider iconprovider._instance() font_maps = iconprovider._instance().charmap icon_names = [ f"{font_collection}.{icon_name}" for font_collection, font_data in font_maps.items() for icon_name in font_data ] self._filter_timer = core.Timer(self) self._filter_timer.setSingleShot(True) self._filter_timer.setInterval(AUTO_SEARCH_TIMEOUT) self._filter_timer.timeout.connect(self._update_filter) model = IconModel(self.get_palette().get_color("text")) model.setStringList(sorted(icon_names)) self._proxy_model = core.SortFilterProxyModel() self._proxy_model.setSourceModel(model) self._proxy_model.set_filter_case_sensitive(True) self._listview = IconListView(self) self._listview.setUniformItemSizes(True) self._listview.set_view_mode("icon") self._listview.set_model(self._proxy_model) self._listview.set_contextmenu_policy("custom") self._listview.doubleClicked.connect(self._copy_icon_text) self._lineedit = widgets.LineEdit(parent=self) self._lineedit.textChanged.connect(self._filter_timer.restart) self._lineedit.returnPressed.connect(self._trigger_instant_update) self._combobox = widgets.ComboBox(parent=self) self._combobox.setMinimumWidth(75) self._combobox.currentIndexChanged.connect( self._trigger_instant_update) self._combobox.addItems([ALL_COLLECTIONS] + sorted(font_maps.keys())) lyt = widgets.BoxLayout("horizontal") lyt.set_margin(0) lyt.add(self._combobox) lyt.add(self._lineedit) search_bar_frame = widgets.Frame(self) search_bar_frame.setLayout(lyt) self._copy_button = widgets.PushButton("Copy Name", self) self._copy_button.clicked.connect(self._copy_icon_text) lyt = widgets.BoxLayout("vertical") lyt.add(search_bar_frame) lyt.add(self._listview) lyt.add(self._copy_button) frame = widgets.Frame(self) frame.set_layout(lyt) self.setCentralWidget(frame) widgets.Shortcut(gui.KeySequence("return"), self, self._copy_icon_text) self._lineedit.setFocus() self.center()
def __init__(self, label, callback, icon=None, value=None, check=True): super().__init__("", value=value, check=check) self.widget = widgets.PushButton(label) if value is not None: self.widget.set_value(value)
from __future__ import annotations from prettyqt import core, widgets class HoverIconEventFilter(core.Object): def __init__(self, normal, hover, parent=None): super().__init__(parent) self.normal = normal self.hover = hover def eventFilter(self, obj, event: core.Event): if event.type() == core.Event.Type.Enter: obj.set_icon(self.hover) elif event.type() == core.Event.Type.Leave: obj.set_icon(self.normal) return super().eventFilter(obj, event) if __name__ == "__main__": app = widgets.app() widget = widgets.PushButton() test = HoverIconEventFilter("mdi.timer", "mdi.folder") widget.installEventFilter(test) widget.show() app.main_loop()
def __init__(self, label, callback, icon=None, default=None, check=True): super().__init__("", default=default, check=check) self.widget = widgets.PushButton(label) if default is not None: self.widget.set_value(default)
self.exit_effect_duration) else: self.__delete_notification(notification) # Internal Qt functions def resizeEvent(self, event): """Internal QT function (do not call directly).""" self.target_resize_event(event) newsize = event.size() self.setFixedWidth(newsize.width()) self.adjustSize() def paintEvent(self, pe): """Redefinition of paintEvent. Makes class NotificationArea available in style sheets. Internal QT function (do not call directly). """ o = widgets.StyleOption.based_on(self) p = gui.Painter(self) self.style().drawPrimitive(widgets.Style.PE_Widget, o, p, self) if __name__ == "__main__": app = widgets.app() p = widgets.PushButton("test") noti = NotificationArea(p) p.clicked.connect(lambda: noti.display("test", "danger", timeout=2000)) p.show() app.main_loop()
from __future__ import annotations import contextlib from prettyqt.qt import QtWidgets class WhatsThis(QtWidgets.QWhatsThis): @classmethod @contextlib.contextmanager def enter_mode(cls): cls.enterWhatsThisMode() yield cls cls.leaveWhatsThisMode() if __name__ == "__main__": from prettyqt import widgets app = widgets.app() def test(): with WhatsThis.enter_mode() as w: print(w.inWhatsThisMode()) btn = widgets.PushButton(callback=test) btn.show() app.main_loop()
def _create_widget(self) -> widgets.PushButton: widget = widgets.PushButton(self.button_label) widget.set_icon(self.icon) callback = functools.partial(self.callback, parent=widget.window()) widget.clicked.connect(callback) return widget
if next_x - space_x > rect.right() and line_height > 0: x = rect.x() space_y = space + wid.style().layoutSpacing( pb, pb, QtCore.Qt.Vertical) y = y + line_height + space_y next_x = x + item.sizeHint().width() + space_x line_height = 0 if not test_only: item.setGeometry(core.Rect(core.Point(x, y), item.sizeHint())) x = next_x line_height = max(line_height, item.sizeHint().height()) return y + line_height - rect.y() if __name__ == '__main__': app = widgets.app() widget = widgets.Widget() layout = FlowLayout() layout += FlowLayout() layout += widgets.PushButton("Short") layout += widgets.PushButton("Longer") layout += widgets.PushButton("Different text") layout += widgets.PushButton("More text") layout += widgets.PushButton("Even longer button text") widget.set_layout(layout) widget.show() app.exec_()
def test_pushbutton(): widget = widgets.PushButton("Test") widget.show()