#!/usr/bin/env python3 # qtvcp # # Copyright (c) 2018 Chris Morley # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ################################################################################# from qtpy.QtCore import Signal from qtpy.QtWidgets import QStackedWidget, QLayout from collections import OrderedDict from qtvcp.widgets.widget_baseclass import _HalWidgetBase from qtvcp import logger # Instantiate the libraries with global reference # LOG is for running code logging LOG = logger.getLogger(__name__) # Force the log level for this module # LOG.setLevel(logger.INFO) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL class WidgetSwitcher(QStackedWidget, _HalWidgetBase): widgetChanged = Signal(int) def __init__(self, parent=None): super(WidgetSwitcher, self).__init__(parent) self._widgetNames = OrderedDict() self._current_object = None self._current_number = 0 # do this now so we have a reference to all the widets # through QTVCP_INSTANCE def _hal_init(self): wlist = self.property("widget_list") if wlist is None: LOG.warning('No widget names found for switching.') else: for i in wlist: LOG.debug('Widget specified in list: {}'.format(i)) self.register_widget(i, self.QTVCP_INSTANCE_) # check for enough pages - need one for default and one for each widget. total = len(self._widgetNames) count = self.count() if count < total +1: LOG.error('Not enough pages for widget total +1, widget count = {} page count = {}'.format(total,count)) # add the widget info so switcher will know what to switch # makes a list of: widget object, widget's layout, position in the layout def register_widget(self, name, object): layout, position = self.search(object[name]) self._widgetNames[name] = [object[name], layout, position] LOG.debug( 'registering: {} {} {}'.format(name,layout,position)) # find the layout and position that the widget is in def search(self, widget): for i in widget.parent().findChildren(QLayout): if i.indexOf(widget) > -1: #print i.layout(), widget.objectName(), i.objectName() return i.layout(), i.indexOf(widget) print(widget.parent()) LOG.error('No layout found for {}'.format(widget)) return widget.parent(),None # Show the widgets based on a reference number # -1 will return to default layout def show_id_widget(self, number): #print 'requested:',number if number == 0: self.show_default() return for n, i in enumerate(self._widgetNames): obj = self._widgetNames[i] num = n+1 if num == number: #print 'switch to ',obj[0],' tp ',self.widget(num).layout().objectName() #print num, self.widget(num).objectName(),self.widget(num).layout() if self.widget(num).layout() is None: LOG.error('''Cannot move widget '{}' to widget '{}', No layout found in '{}' '''.format( obj[0].objectName(),self.widget(num).objectName(), self.widget(num).objectName())) else: self.widget(num).layout().addWidget(obj[0]) self.setCurrentIndex(num) self._current_object = obj self._current_number = num self.widgetChanged.emit(num) else: #print 'replace',obj[0],' into ',obj[1] obj[1].addWidget(obj[0]) obj[0].show() #print '\n' # show widget based on object name (a string) def show_named_widget(self, name): for num, i in enumerate(self._widgetNames): obj = self._widgetNames[i] if i == name: self.addWidget(obj[0]) self.setCurrentWidget(obj[0]) self._current_object = obj self._current_number = num self.widgetChanged.emit(num) else: try: obj[1].addWidget(obj[0]) except: obj[0].setParent(obj[1]) obj[0].show() # show the stacked widget as originally laid out (hopefully) # This will set the stacked widget to display the first page # which is index 0 def show_default(self): for i in self._widgetNames: obj = self._widgetNames[i] if obj[2] is None: obj[0].setParent(obj[1]) obj[0].show() continue obj[1].insertWidget(obj[2], obj[0]) obj[0].show() self.setCurrentIndex(0) self._current_object = None self._current_number = 0 self.widgetChanged.emit(0) def show_next(self): total = len(self._widgetNames) next = self._current_number + 1 if next > total: next = 0 self.show_id_widget(next) def get_current_object(self): return self._current_object def get_current_number(self): return self._current_number ############################## # required class boiler code # ############################## def __getitem__(self, item): return getattr(self, item) def __setitem__(self, item, value): return setattr(self, item, value)