def __init__( self, children: ChildrenType = None, show: PropValueType[bool] = None, hide_on_scroll: bool = None, # this is the reveal prop elevated: bool = None, bordered: bool = None, classes: ClassesType = None, styles: StylesType = None, props: PropsType = None, events: EventsType = None): props = build_props( self.defaults['props'], props, { 'reveal': hide_on_scroll, 'elevated': elevated, 'bordered': bordered, 'show': show, }) show = props['show'] model = show if isinstance(show, Reactive) else Model(show) super().__init__(model=model, children=children, classes=classes, styles=styles, props=props, events=events)
def __init__(self, children: ChildrenType = None, menu_in_header: bool = True, side: str = None, show: Union[Model, bool] = True, bordered: bool = None, classes: ClassesType = None, styles: StylesType = None, props: PropsType = None, events: EventsType = None): """ :menu_in_header: if used together with QLayout, it instructs to put a close menu into the header. """ self.menu_in_header = menu_in_header children = children props = build_props({}, props, { 'side': side, 'bordered': bordered, }) model = show if isinstance(show, Reactive) else Model(show) super().__init__(model=model, children=children, classes=classes, styles=styles, props=props, events=events)
def __init__(self, renderer: PropValueType[str] = 'mpld3', classes: ClassesType = None, styles: StylesType = None): """ :param renderer: valid values are 'png' and 'mpld3'. :param classes: :param styles: """ self.renderer = Model(renderer) if isinstance(renderer, str) else renderer self.renderer.add_callback(self.update) self._check_imports() self.fig = None self.html = {} self.img_base64 = Model('') self.last_renderer = None super().__init__(classes=classes, styles=styles) self.dependents.append(self.img_base64)
def __init__(self, label: str = None, model: Model = None, appearance: str = 'checkbox', classes: ClassesType = None, styles: StylesType = None, props: PropsType = None, events: EventsType = None, children: List[Slot] = None): self.component = { 'checkbox': 'q-checkbox', 'toggle': 'q-toggle' }[appearance] model = model or Model(False) model.set_conversion(bool, bool) super().__init__(label=label, model=model, classes=classes, styles=styles, props=props, events=events, children=children)
def __init__(self, label: str = None, model: Model = None, appearance: str = 'editor', classes: ClassesType = None, label_classes: ClassesType = None, styles: StylesType = None, props: PropsType = None, events: EventsType = None, children: List[Slot] = None): """ :param label: :param model: :param appearance: 'editor' or 'textarea' :param classes: :param styles: :param props: :param events: :param children: """ model = model or Model('') if appearance == 'editor': raise NotImplementedError( 'Cannot use appearance == "editor" ' 'at the moment since it is not editable for some reason' 'and we couldn\'t fix it.') self.component = 'div' children = [ label, QEditor(model=model, classes=classes, styles=styles, props=props, events=events, children=children) ] label_classes = merge_classes(self.defaults['label_classes'], label_classes) super().__init__(classes=label_classes, children=children) else: self.component = 'q-input' props = build_props({'type': 'textarea'}, props, { 'label': label, 'v-model': model }) super().__init__(classes=classes, styles=styles, props=props, events=events, children=children)
def __init__( self, children: ChildrenType = None, hide_on_scroll: bool = None, # this is the reveal prop elevated: bool = None, bordered: bool = None, show: PropValueType[bool] = True, classes: ClassesType = None, styles: StylesType = None, props: PropsType = None): if 1 <= len(children) <= 2 and isinstance(children[-1], str): children = [QToolbar([QToolbarTitle(children)])] props = build_props({}, props, { 'reveal': hide_on_scroll, 'elevated': elevated, 'bordered': bordered, }) model = show if isinstance(show, Reactive) else Model(show) super().__init__(model=model, children=children, classes=classes, styles=styles, props=props)
class Plot(Component): """ This component is not a quasar component. If interactive=False, it can be styled, it shows a png image. However, if interactive=True, it can *not* be styled as it shows an interactive svg, created by mpld3. "Different sizes can be created using ``plt.figure(figsize=(width,height))`` where width and height are in inches." ref. https://stackoverflow.com/a/31843288/1031191 TODO: Bokeh integration, probably via file_html ref. https://docs.bokeh.org/en/latest/docs/reference/embed.html#bokeh.embed.file_html otherwise a bokeh server needs to start in the background - which is also not impossible... """ script_sources = ['mpld3-figure.js'] defaults = { 'render': 'png', # other choice: 'mpld3' } renderers = {'png', 'mpld3'} def __init__(self, renderer: PropValueType[str] = 'mpld3', classes: ClassesType = None, styles: StylesType = None): """ :param renderer: valid values are 'png' and 'mpld3'. :param classes: :param styles: """ self.renderer = Model(renderer) if isinstance(renderer, str) else renderer self.renderer.add_callback(self.update) self._check_imports() self.fig = None self.html = {} self.img_base64 = Model('') self.last_renderer = None super().__init__(classes=classes, styles=styles) self.dependents.append(self.img_base64) def _check_imports(self): if self.renderer.value == 'mpld3': if not MPLD3: raise ImportError( "Please install mpld3 package to use interactive plots") elif self.renderer.value == 'png': if not MATPLOTLIB: raise ImportError( "Please install matplotlib package to use interactive plots" ) else: raise AssertionError( 'Wrong renderer. Renderer is set to "{wrong}", ' 'should be one of {should}'.format(wrong=self.renderer.value, should=self.renderers)) def update(self): self.set_figure(self.fig) def set_figure(self, fig: 'Figure'): self.fig = fig self._check_imports() if self.renderer.value == 'mpld3': raw_html = mpld3.fig_to_html( fig, d3_url='file://' + join(QUASAR_GUI_ASSETS_PATH, 'd3.v5.js'), mpld3_url='file://' + join(QUASAR_GUI_ASSETS_PATH, 'mpld3.v0.5.2.js'), ) self.html['figId'] = str_between(raw_html, '<div id="', '"></div>') self.html['script'] = str_between(raw_html, "<script>", "</script>") self.html['style'] = str_between(raw_html, "<style>", "</style>") elif self.renderer.value == 'png': tmpfile = BytesIO() fig.savefig(tmpfile, format='png') encoded = base64.b64encode(tmpfile.getvalue()).decode('utf-8') self.img_base64.value = "data:image/png;base64,{}".format(encoded) if self.last_renderer != self.renderer.value or self.renderer.value != 'png': super().update() self.last_renderer = self.renderer.value @property def vue(self) -> dict: if self.renderer.value == 'mpld3': return self._merge_vue({ 'component': 'mpld3-figure', 'props': { 'script': self.html['script'], 'style': self.html['style'], 'figId': self.html['figId'] } }) elif self.renderer.value == 'png': return self._merge_vue({ 'component': 'img', 'props': { 'src': self.img_base64.render_as_data() } }) else: return self._merge_vue({'component': 'div'})
def _get_model(self, model): model = model or Model(None) model.set_conversion(self._to_python, self._from_python) return model
def __init__(self, label: str = None, model: Model = None, choices: Union[Renderable, list] = None, multiple: bool = None, appearance: str = 'auto', item_props: PropsType = None, label_props: PropsType = None, props: PropsType = None, classes: ClassesType = None, styles: StylesType = None, events: EventsType = None): """ :param label: :param model: the value of the model depends on the choices parameter (and the item_props). List[str] choice format yields the displayed label as model value, List[dict] format yields the value of 'value' field as value, if dict has only 'label' and 'value' fields. Otherwise List[dict] format yields the whole dict of the selected item. This behavior can be overridden with item_props that is sent to QSelect ('select'), QOptionGroup ('radio') or QButtonToggle ('buttons') as props parameter. :param choices: format is ['choice 1', 'choice 2', ...] or [{'label':'Choice 1', 'value': 1}, ...]. :param appearance: if multiple=False: 'auto', 'radio', 'buttons' or 'select'. 'auto' means 'radio' for small lists, 'select' for large lists. if multiple=True: 'auto', 'checkboxes', 'toggles', 'select' or 'tags' 'auto' means 'checkboxes' for small lists, 'select' for large lists, 'tags' if choices is None. :param item_props: The props for the items. (also if appearance=='select', props for the QSelect) :param classes: :param styles: :param label_props: :param events: """ def is_lvc(choices_): """ is_label_value_choice """ # noinspection PyBroadException try: return set(choices_[0].keys()) == {'label', 'value'} except Exception: return False single_only_appearances = {'input', 'radio', 'buttons'} multiple_only_appearances = {'checkboxes', 'toggles', 'tags'} props = props or {} if multiple is None: multiple = appearance in multiple_only_appearances model = model or Model([] if multiple else '') self.dependents = [model] allowed_appearances = { 'auto', 'radio', 'checkboxes', 'toggles', 'buttons', 'select', 'tags' } if appearance not in allowed_appearances: raise AssertionError( 'Wrong appearance {}. Must be one of {}'.format( appearance, allowed_appearances)) if appearance in single_only_appearances and multiple: raise AssertionError( 'appearance=={} can be only used if multiple==False'.format( appearance)) elif appearance in multiple_only_appearances and not multiple: raise AssertionError( 'appearance=={} can be only used if multiple==True'.format( appearance)) if appearance == 'auto': # auto is for providing the user a reasonable default. if isinstance(choices, list): n_choices = len(choices) elif isinstance(choices, Reactive): n_choices = len(choices.value) else: n_choices = 0 if multiple: appearance = ('tags' if n_choices == 0 else 'checkboxes' if n_choices <= 10 else 'select') else: appearance = 'radio' if 0 < n_choices <= 5 else \ 'input' if n_choices == 0 else \ 'select' if appearance == 'input': self.component = 'q-input' children = [] elif appearance in {'radio', 'buttons', 'checkboxes', 'toggles'}: if (isinstance(choices, list) and len(choices) and isinstance(choices[0], str)): choices = [{ 'label': choice, 'value': choice } for choice in choices] default_item_props = build_props( self.defaults['item_props'], {'type': 'radio'} if appearance == 'radio' else {'type': 'checkbox'} if appearance == 'checkboxes' else {'type': 'toggle'} if appearance == 'toggles' else {}) item_props = build_props(default_item_props, item_props) children = [ Div([label], props=label_props), ] if appearance in {'radio', 'checkboxes', 'toggles'}: del item_props['clearable'] type_ = { 'radio': 'radio', 'checkboxes': 'checkbox', 'toggles': 'toggle', }[appearance] children += [ QOptionGroup(model=model, type=type_, options=choices, props=item_props) ] elif appearance == 'buttons': children += [ QButtonToggle(model=model, options=choices, props=item_props) ] elif appearance == 'select': if isinstance(choices, Reactive): is_label_value_choice = Computed(is_lvc, choices) else: is_label_value_choice = is_lvc(choices) default_props = { 'emit-value': is_label_value_choice, 'map-options': is_label_value_choice } default_props = build_props(default_props, self.defaults['item_props']) item_props = build_props(default_props, item_props, { 'options': choices, 'multiple': multiple, 'use-chips': multiple }) children = [QSelect(label=label, model=model, props=item_props)] elif appearance == 'tags': label_props = build_props({ 'hide-bottom-space': True, }, label_props) item_props = build_props( { 'placeholder': props.get('placeholder', ''), 'add-on-key': [13, ','], # 'separators': [','] }, item_props) children = [ QField(label=label, model=model, props=label_props, children=[ Slot('control', [VueTagsInput(model, props=item_props)]) ]), ] else: raise NotImplementedError( 'appearance=={} is not implemented.'.format(appearance)) super().__init__(label=label, model=model, classes=classes, styles=styles, props=props, events=events, children=children)
def __init__(self, label: str = None, model: Model = None, appearance: str = None, min: Union[int, float] = None, max: Union[int, float] = None, props: PropsType = None, field_props: PropsType = None, field_classes: ClassesType = None, field_styles: StylesType = None, children: List[Slot] = None, classes: ClassesType = None, styles: StylesType = None, events: EventsType = None): appearance = appearance or 'input' self.component = { 'input': 'q-input', 'knob': 'q-field', 'slider': 'q-field' }[appearance] model = model or Model(0, self._type) model.modifiers.add('number') model.set_conversion(self._type) special_props = {'min': min, 'max': max} if appearance in {'knob', 'slider'}: min = 0 if min is None else min max = 100 if max is None else max component_class = {'knob': QKnob, 'slider': QSlider}[appearance] control_props = build_props({'snap': self._type == int}, props) control_props = build_props(self.defaults['control_props'], control_props) if self._type == float: control_props = build_props({'step': (max - min) / 1000}, control_props) control_props = build_props( { 'label-position': 'before' if appearance == 'knob' else 'top' }, control_props, special_props) control = component_class( model=model, props=control_props, children=children, classes=classes, styles=styles, events=events, ) label_position = control_props['label-position'] field_props = build_props( { 'borderless': True, 'stack-label': True, }, field_props, {'label': label if label_position == 'top' else None}) label_slot = [] if label and label_position != 'top': field_classes = merge_classes(self.defaults['field_classes'], field_classes or '') if isinstance(label, str): label = Div([label], classes=field_classes) label_position = { 'left': 'before', 'right': 'after' }.get(label_position, label_position) label_slot = [Slot(label_position, children=[label])] super().__init__(model=model, props=field_props, children=[Slot('control', [control])] + label_slot) else: props = build_props({'type': 'number'}, props, special_props) props = build_props(props, field_props, {'label': label}) classes = merge_classes(classes or '', field_classes or '') styles = build_props(styles or {}, field_styles) self.component = 'q-input' super().__init__(model=model, classes=classes, styles=styles, props=props, events=events, children=children)