class ZenDisplay(QtWidgets.QSystemTrayIcon): """System tray icon class""" def __init__(self): super().__init__() self.controller = Controller() self.displays = Displays() if len(self.displays) == 0: print('Could not find supported displays') quit() self.sensors = LuminanceSourceManager() self.sensors.add_source_type(LuminanceIIO) self.sensors.add_source_type(LuminanceMQTT, { 'topic': MQTT_TOPIC, 'host': MQTT_HOST }) manual_parameters = self.controller.get_range() manual_parameters.update({'value': self.displays.get_brightness()}) self.sensors.add_source_type(LuminanceManual, manual_parameters) self.sensors.activate(DEFAULT_SENSOR) self.menu = self.construct_menu() self.menu_visible = False self.setContextMenu(self.menu) self.activated.connect(lambda reason: self.action_click(reason, self)) self.timer = QtCore.QTimer() self.timer.timeout.connect(self.main_control) self.timer.start(1000) if MQTT_PUBLISH is True: self.mqtt_publisher = LuminanceMQTT(name="mqttp", path=MQTT_TOPIC, host=MQTT_HOST) def toggle_menu(self): """Toggle context menu visibility""" if self.menu_visible: self.menu.hide() else: self.menu.popup(QtGui.QCursor.pos()) self.menu_visible = not self.menu_visible def construct_menu(self): """Construct a menu from the sitemap""" menu = QtWidgets.QMenu() self.construct_menu_displays(menu) self.construct_menu_sensors(menu) # Create quit button menu.addSeparator() action_quit = menu.addAction("Quit") action_quit.triggered.connect(lambda _: quit()) return menu def construct_menu_displays(self, parent): """Create submenu for displays""" display_menu = parent.addMenu('Displays') for display in self.displays: action = display_menu.addAction(display['name']) action.setCheckable(True) action.setChecked(display['use']) did = display['id'] action.triggered.connect( lambda state, did=did: self.displays.set_active(did, state)) def construct_menu_sensors(self, parent): """Create submenu for sensors""" sensor_menu = parent.addMenu('Sensors') sensor_group = QtWidgets.QActionGroup(sensor_menu, exclusive=True) for sensor in self.sensors: action = sensor_menu.addAction(sensor.name + " (" + sensor.path + ")") action.setCheckable(True) if sensor.uid == self.sensors.get_active(): action.setChecked(True) sid = sensor.uid action.triggered.connect( lambda state, sid=sid: self.sensors.activate(sid)) sensor_group.addAction(action) def main_control(self): """Main control function, sets display brightness dynamically""" luminance = self.sensors.get_luminance() current_brightness = self.displays.get_brightness() recommended_brightness = self.controller.recommend_brightness( luminance, current_brightness) self.setToolTip('Brightness: ' + str(recommended_brightness) + '%') self.displays.set_brightness(recommended_brightness) if MQTT_PUBLISH is True: self.mqtt_publisher.publish(luminance) def event(self, event): """Event handler for QEvent objects""" if event.type() == QtCore.QEvent.Wheel: new_value = None if event.angleDelta().y() < 0: new_value = self.sensors[self.sensors.get_active()].decrease() else: new_value = self.sensors[self.sensors.get_active()].increase() if new_value is not None and self.supportsMessages(): self.showMessage('Brightness', str(new_value) + '%', msecs=500) return True return False @classmethod @QtCore.pyqtSlot() def action_click(cls, reason, tray): """Toggle menu on click""" if reason in [ QtWidgets.QSystemTrayIcon.Trigger, QtWidgets.QSystemTrayIcon.Context ]: tray.toggle_menu()