Source code for magicclass.widgets.pywidgets.object
from __future__ import annotations
from typing import Callable, Any
from functools import wraps
from collections import defaultdict
from qtpy.QtWidgets import QLabel, QMenu, QAction
from qtpy.QtCore import Qt
from ..utils import FreeWidget
from ...utils import extract_tooltip
_Callback = Callable[[Any, int], Any]
[docs]class BaseWidget(FreeWidget):
# Abstract class for PyObject-like widgets.
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._title = QLabel(self.native)
self._title.setAlignment(Qt.AlignCenter)
self.running = False
self.set_widget(self._title)
self.title = self.name
self._callbacks: defaultdict[type, list[_Callback]] = defaultdict(list)
self._delegates: dict[type, Callable[[Any], str]] = dict()
self._contextmenu: defaultdict[type, list[_Callback]] = defaultdict(list)
@property
def value(self):
raise NotImplementedError()
@property
def title(self) -> str:
return self._title.text()
@title.setter
def title(self, text: str):
self._title.setText(text)
if text:
self._title.show()
else:
self._title.hide()
[docs] def register_callback(self, type_: type):
"""
Register a double-click callback function for items of certain type.
"""
def wrapper(func: Callable):
self._callbacks[type_].append(func)
return func
return wrapper
[docs] def register_delegate(self, type_: type):
"""
Register a custom display.
"""
def wrapper(func: Callable):
self._delegates[type_] = func
return func
return wrapper
[docs]class ContextMenuMixin:
"""
This class defines custom contextmenu with type dispatching.
"""
[docs] def setContextMenu(self):
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.contextMenu)
[docs] def contextMenu(self, point):
menu = QMenu(self)
menu.setToolTipsVisible(True)
item = self.itemAt(point)
type_ = type(item.obj)
menus = self._parent._contextmenu.get(type_, [])
for f in menus:
text = f.__name__.replace("_", " ")
action = QAction(text, self)
pfunc = partial_event(f, item.obj, self.row(item))
action.triggered.connect(pfunc)
doc = extract_tooltip(f)
if doc:
action.setToolTip(doc)
menu.addAction(action)
menu.exec_(self.mapToGlobal(point))