mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge pull request #1550 from pypeclub/feature/910-ask-user-to-restart-after-changing-global-environments-in-settings
This commit is contained in:
commit
194c81b0dc
12 changed files with 217 additions and 8 deletions
|
|
@ -680,6 +680,10 @@ class TrayModulesManager(ModulesManager):
|
||||||
output.append(module)
|
output.append(module)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def restart_tray(self):
|
||||||
|
if self.tray_manager:
|
||||||
|
self.tray_manager.restart()
|
||||||
|
|
||||||
def tray_init(self):
|
def tray_init(self):
|
||||||
report = {}
|
report = {}
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,10 @@ class SettingsAction(PypeModule, ITrayAction):
|
||||||
return
|
return
|
||||||
from openpype.tools.settings import MainWidget
|
from openpype.tools.settings import MainWidget
|
||||||
self.settings_window = MainWidget(self.user_role)
|
self.settings_window = MainWidget(self.user_role)
|
||||||
|
self.settings_window.trigger_restart.connect(self._on_trigger_restart)
|
||||||
|
|
||||||
|
def _on_trigger_restart(self):
|
||||||
|
self.manager.restart_tray()
|
||||||
|
|
||||||
def show_settings_window(self):
|
def show_settings_window(self):
|
||||||
"""Show settings tool window.
|
"""Show settings tool window.
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,8 @@ class BaseItemEntity(BaseEntity):
|
||||||
self.file_item = None
|
self.file_item = None
|
||||||
# Reference to `RootEntity`
|
# Reference to `RootEntity`
|
||||||
self.root_item = None
|
self.root_item = None
|
||||||
|
# Change of value requires restart of OpenPype
|
||||||
|
self._require_restart_on_change = False
|
||||||
|
|
||||||
# Entity is in hierarchy of dynamically created entity
|
# Entity is in hierarchy of dynamically created entity
|
||||||
self.is_in_dynamic_item = False
|
self.is_in_dynamic_item = False
|
||||||
|
|
@ -171,6 +173,14 @@ class BaseItemEntity(BaseEntity):
|
||||||
roles = [roles]
|
roles = [roles]
|
||||||
self.roles = roles
|
self.roles = roles
|
||||||
|
|
||||||
|
@property
|
||||||
|
def require_restart_on_change(self):
|
||||||
|
return self._require_restart_on_change
|
||||||
|
|
||||||
|
@property
|
||||||
|
def require_restart(self):
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_studio_override(self):
|
def has_studio_override(self):
|
||||||
"""Says if entity or it's children has studio overrides."""
|
"""Says if entity or it's children has studio overrides."""
|
||||||
|
|
@ -261,6 +271,14 @@ class BaseItemEntity(BaseEntity):
|
||||||
self, "Dynamic entity has set `is_group` to true."
|
self, "Dynamic entity has set `is_group` to true."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.require_restart_on_change
|
||||||
|
and (self.is_dynamic_item or self.is_in_dynamic_item)
|
||||||
|
):
|
||||||
|
raise EntitySchemaError(
|
||||||
|
self, "Dynamic entity can't require restart."
|
||||||
|
)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def set_override_state(self, state):
|
def set_override_state(self, state):
|
||||||
"""Set override state and trigger it on children.
|
"""Set override state and trigger it on children.
|
||||||
|
|
@ -788,6 +806,15 @@ class ItemEntity(BaseItemEntity):
|
||||||
# Root item reference
|
# Root item reference
|
||||||
self.root_item = self.parent.root_item
|
self.root_item = self.parent.root_item
|
||||||
|
|
||||||
|
# Item require restart on value change
|
||||||
|
require_restart_on_change = self.schema_data.get("require_restart")
|
||||||
|
if (
|
||||||
|
require_restart_on_change is None
|
||||||
|
and not (self.is_dynamic_item or self.is_in_dynamic_item)
|
||||||
|
):
|
||||||
|
require_restart_on_change = self.parent.require_restart_on_change
|
||||||
|
self._require_restart_on_change = require_restart_on_change
|
||||||
|
|
||||||
# File item reference
|
# File item reference
|
||||||
if self.parent.is_file:
|
if self.parent.is_file:
|
||||||
self.file_item = self.parent
|
self.file_item = self.parent
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,18 @@ class EndpointEntity(ItemEntity):
|
||||||
def on_change(self):
|
def on_change(self):
|
||||||
for callback in self.on_change_callbacks:
|
for callback in self.on_change_callbacks:
|
||||||
callback()
|
callback()
|
||||||
|
|
||||||
|
if self.require_restart_on_change:
|
||||||
|
if self.require_restart:
|
||||||
|
self.root_item.add_item_require_restart(self)
|
||||||
|
else:
|
||||||
|
self.root_item.remove_item_require_restart(self)
|
||||||
self.parent.on_child_change(self)
|
self.parent.on_child_change(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def require_restart(self):
|
||||||
|
return self.has_unsaved_changes
|
||||||
|
|
||||||
def update_default_value(self, value):
|
def update_default_value(self, value):
|
||||||
value = self._check_update_value(value, "default")
|
value = self._check_update_value(value, "default")
|
||||||
self._default_value = value
|
self._default_value = value
|
||||||
|
|
@ -115,6 +125,10 @@ class InputEntity(EndpointEntity):
|
||||||
"""Entity's value without metadata."""
|
"""Entity's value without metadata."""
|
||||||
return self._current_value
|
return self._current_value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def require_restart(self):
|
||||||
|
return self._value_is_modified
|
||||||
|
|
||||||
def _settings_value(self):
|
def _settings_value(self):
|
||||||
return copy.deepcopy(self.value)
|
return copy.deepcopy(self.value)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ class RootEntity(BaseItemEntity):
|
||||||
|
|
||||||
def __init__(self, schema_data, reset):
|
def __init__(self, schema_data, reset):
|
||||||
super(RootEntity, self).__init__(schema_data)
|
super(RootEntity, self).__init__(schema_data)
|
||||||
|
self._require_restart_callbacks = []
|
||||||
|
self._item_ids_require_restart = set()
|
||||||
self._item_initalization()
|
self._item_initalization()
|
||||||
if reset:
|
if reset:
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
@ -64,6 +66,31 @@ class RootEntity(BaseItemEntity):
|
||||||
"""Current OverrideState."""
|
"""Current OverrideState."""
|
||||||
return self._override_state
|
return self._override_state
|
||||||
|
|
||||||
|
@property
|
||||||
|
def require_restart(self):
|
||||||
|
return bool(self._item_ids_require_restart)
|
||||||
|
|
||||||
|
def add_require_restart_change_callback(self, callback):
|
||||||
|
self._require_restart_callbacks.append(callback)
|
||||||
|
|
||||||
|
def _on_require_restart_change(self):
|
||||||
|
for callback in self._require_restart_callbacks:
|
||||||
|
callback()
|
||||||
|
|
||||||
|
def add_item_require_restart(self, item):
|
||||||
|
was_empty = len(self._item_ids_require_restart) == 0
|
||||||
|
self._item_ids_require_restart.add(item.id)
|
||||||
|
if was_empty:
|
||||||
|
self._on_require_restart_change()
|
||||||
|
|
||||||
|
def remove_item_require_restart(self, item):
|
||||||
|
if item.id not in self._item_ids_require_restart:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._item_ids_require_restart.remove(item.id)
|
||||||
|
if not self._item_ids_require_restart:
|
||||||
|
self._on_require_restart_change()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset values and entities to initial state.
|
"""Reset values and entities to initial state.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
"key": "ftrack",
|
"key": "ftrack",
|
||||||
"label": "Ftrack",
|
"label": "Ftrack",
|
||||||
"collapsible": true,
|
"collapsible": true,
|
||||||
|
"require_restart": true,
|
||||||
"checkbox_key": "enabled",
|
"checkbox_key": "enabled",
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@
|
||||||
"key": "environment",
|
"key": "environment",
|
||||||
"label": "Environment",
|
"label": "Environment",
|
||||||
"type": "raw-json",
|
"type": "raw-json",
|
||||||
"env_group_key": "global"
|
"env_group_key": "global",
|
||||||
|
"require_restart": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "splitter"
|
"type": "splitter"
|
||||||
|
|
@ -44,7 +45,8 @@
|
||||||
"key": "openpype_path",
|
"key": "openpype_path",
|
||||||
"label": "Versions Repository",
|
"label": "Versions Repository",
|
||||||
"multiplatform": true,
|
"multiplatform": true,
|
||||||
"multipath": true
|
"multipath": true,
|
||||||
|
"require_restart": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
"key": "avalon",
|
"key": "avalon",
|
||||||
"label": "Avalon",
|
"label": "Avalon",
|
||||||
"collapsible": true,
|
"collapsible": true,
|
||||||
|
"require_restart": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"type": "number",
|
"type": "number",
|
||||||
|
|
@ -35,6 +36,7 @@
|
||||||
"key": "timers_manager",
|
"key": "timers_manager",
|
||||||
"label": "Timers Manager",
|
"label": "Timers Manager",
|
||||||
"collapsible": true,
|
"collapsible": true,
|
||||||
|
"require_restart": true,
|
||||||
"checkbox_key": "enabled",
|
"checkbox_key": "enabled",
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
|
|
@ -66,6 +68,7 @@
|
||||||
"key": "clockify",
|
"key": "clockify",
|
||||||
"label": "Clockify",
|
"label": "Clockify",
|
||||||
"collapsible": true,
|
"collapsible": true,
|
||||||
|
"require_restart": true,
|
||||||
"checkbox_key": "enabled",
|
"checkbox_key": "enabled",
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
|
|
@ -84,6 +87,7 @@
|
||||||
"key": "sync_server",
|
"key": "sync_server",
|
||||||
"label": "Site Sync",
|
"label": "Site Sync",
|
||||||
"collapsible": true,
|
"collapsible": true,
|
||||||
|
"require_restart": true,
|
||||||
"checkbox_key": "enabled",
|
"checkbox_key": "enabled",
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
|
|
@ -114,6 +118,7 @@
|
||||||
"type": "dict",
|
"type": "dict",
|
||||||
"key": "deadline",
|
"key": "deadline",
|
||||||
"label": "Deadline",
|
"label": "Deadline",
|
||||||
|
"require_restart": true,
|
||||||
"collapsible": true,
|
"collapsible": true,
|
||||||
"checkbox_key": "enabled",
|
"checkbox_key": "enabled",
|
||||||
"children": [
|
"children": [
|
||||||
|
|
@ -133,6 +138,7 @@
|
||||||
"type": "dict",
|
"type": "dict",
|
||||||
"key": "muster",
|
"key": "muster",
|
||||||
"label": "Muster",
|
"label": "Muster",
|
||||||
|
"require_restart": true,
|
||||||
"collapsible": true,
|
"collapsible": true,
|
||||||
"checkbox_key": "enabled",
|
"checkbox_key": "enabled",
|
||||||
"children": [
|
"children": [
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ class IgnoreInputChangesObj:
|
||||||
class SettingsCategoryWidget(QtWidgets.QWidget):
|
class SettingsCategoryWidget(QtWidgets.QWidget):
|
||||||
state_changed = QtCore.Signal()
|
state_changed = QtCore.Signal()
|
||||||
saved = QtCore.Signal(QtWidgets.QWidget)
|
saved = QtCore.Signal(QtWidgets.QWidget)
|
||||||
|
restart_required_trigger = QtCore.Signal()
|
||||||
|
|
||||||
def __init__(self, user_role, parent=None):
|
def __init__(self, user_role, parent=None):
|
||||||
super(SettingsCategoryWidget, self).__init__(parent)
|
super(SettingsCategoryWidget, self).__init__(parent)
|
||||||
|
|
@ -185,9 +186,10 @@ class SettingsCategoryWidget(QtWidgets.QWidget):
|
||||||
if self.user_role == "developer":
|
if self.user_role == "developer":
|
||||||
self._add_developer_ui(footer_layout)
|
self._add_developer_ui(footer_layout)
|
||||||
|
|
||||||
save_btn = QtWidgets.QPushButton("Save")
|
save_btn = QtWidgets.QPushButton("Save", footer_widget)
|
||||||
spacer_widget = QtWidgets.QWidget()
|
require_restart_label = QtWidgets.QLabel(footer_widget)
|
||||||
footer_layout.addWidget(spacer_widget, 1)
|
require_restart_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
|
footer_layout.addWidget(require_restart_label, 1)
|
||||||
footer_layout.addWidget(save_btn, 0)
|
footer_layout.addWidget(save_btn, 0)
|
||||||
|
|
||||||
configurations_layout = QtWidgets.QVBoxLayout(configurations_widget)
|
configurations_layout = QtWidgets.QVBoxLayout(configurations_widget)
|
||||||
|
|
@ -205,6 +207,7 @@ class SettingsCategoryWidget(QtWidgets.QWidget):
|
||||||
save_btn.clicked.connect(self._save)
|
save_btn.clicked.connect(self._save)
|
||||||
|
|
||||||
self.save_btn = save_btn
|
self.save_btn = save_btn
|
||||||
|
self.require_restart_label = require_restart_label
|
||||||
self.scroll_widget = scroll_widget
|
self.scroll_widget = scroll_widget
|
||||||
self.content_layout = content_layout
|
self.content_layout = content_layout
|
||||||
self.content_widget = content_widget
|
self.content_widget = content_widget
|
||||||
|
|
@ -323,6 +326,15 @@ class SettingsCategoryWidget(QtWidgets.QWidget):
|
||||||
def _on_reset_start(self):
|
def _on_reset_start(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _on_require_restart_change(self):
|
||||||
|
value = ""
|
||||||
|
if self.entity.require_restart:
|
||||||
|
value = (
|
||||||
|
"Your changes require restart of"
|
||||||
|
" all running OpenPype processes to take affect."
|
||||||
|
)
|
||||||
|
self.require_restart_label.setText(value)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.set_state(CategoryState.Working)
|
self.set_state(CategoryState.Working)
|
||||||
|
|
||||||
|
|
@ -339,6 +351,9 @@ class SettingsCategoryWidget(QtWidgets.QWidget):
|
||||||
dialog = None
|
dialog = None
|
||||||
try:
|
try:
|
||||||
self._create_root_entity()
|
self._create_root_entity()
|
||||||
|
self.entity.add_require_restart_change_callback(
|
||||||
|
self._on_require_restart_change
|
||||||
|
)
|
||||||
|
|
||||||
self.add_children_gui()
|
self.add_children_gui()
|
||||||
|
|
||||||
|
|
@ -433,6 +448,15 @@ class SettingsCategoryWidget(QtWidgets.QWidget):
|
||||||
return
|
return
|
||||||
|
|
||||||
def _save(self):
|
def _save(self):
|
||||||
|
# Don't trigger restart if defaults are modified
|
||||||
|
if (
|
||||||
|
self.modify_defaults_checkbox
|
||||||
|
and self.modify_defaults_checkbox.isChecked()
|
||||||
|
):
|
||||||
|
require_restart = False
|
||||||
|
else:
|
||||||
|
require_restart = self.entity.require_restart
|
||||||
|
|
||||||
self.set_state(CategoryState.Working)
|
self.set_state(CategoryState.Working)
|
||||||
|
|
||||||
if self.items_are_valid():
|
if self.items_are_valid():
|
||||||
|
|
@ -442,6 +466,10 @@ class SettingsCategoryWidget(QtWidgets.QWidget):
|
||||||
|
|
||||||
self.saved.emit(self)
|
self.saved.emit(self)
|
||||||
|
|
||||||
|
if require_restart:
|
||||||
|
self.restart_required_trigger.emit()
|
||||||
|
self.require_restart_label.setText("")
|
||||||
|
|
||||||
def _on_refresh(self):
|
def _on_refresh(self):
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -275,8 +275,6 @@ class UnsavedChangesDialog(QtWidgets.QDialog):
|
||||||
layout.addWidget(message_label)
|
layout.addWidget(message_label)
|
||||||
layout.addWidget(btns_widget)
|
layout.addWidget(btns_widget)
|
||||||
|
|
||||||
self.state = None
|
|
||||||
|
|
||||||
def on_cancel_pressed(self):
|
def on_cancel_pressed(self):
|
||||||
self.done(0)
|
self.done(0)
|
||||||
|
|
||||||
|
|
@ -287,6 +285,48 @@ class UnsavedChangesDialog(QtWidgets.QDialog):
|
||||||
self.done(2)
|
self.done(2)
|
||||||
|
|
||||||
|
|
||||||
|
class RestartDialog(QtWidgets.QDialog):
|
||||||
|
message = (
|
||||||
|
"Your changes require restart of process to take effect."
|
||||||
|
" Do you want to restart now?"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(RestartDialog, self).__init__(parent)
|
||||||
|
message_label = QtWidgets.QLabel(self.message)
|
||||||
|
|
||||||
|
btns_widget = QtWidgets.QWidget(self)
|
||||||
|
btns_layout = QtWidgets.QHBoxLayout(btns_widget)
|
||||||
|
|
||||||
|
btn_restart = QtWidgets.QPushButton("Restart")
|
||||||
|
btn_restart.clicked.connect(self.on_restart_pressed)
|
||||||
|
btn_cancel = QtWidgets.QPushButton("Cancel")
|
||||||
|
btn_cancel.clicked.connect(self.on_cancel_pressed)
|
||||||
|
|
||||||
|
btns_layout.addStretch(1)
|
||||||
|
btns_layout.addWidget(btn_restart)
|
||||||
|
btns_layout.addWidget(btn_cancel)
|
||||||
|
|
||||||
|
layout = QtWidgets.QVBoxLayout(self)
|
||||||
|
layout.addWidget(message_label)
|
||||||
|
layout.addWidget(btns_widget)
|
||||||
|
|
||||||
|
self.btn_cancel = btn_cancel
|
||||||
|
self.btn_restart = btn_restart
|
||||||
|
|
||||||
|
def showEvent(self, event):
|
||||||
|
super(RestartDialog, self).showEvent(event)
|
||||||
|
btns_width = max(self.btn_cancel.width(), self.btn_restart.width())
|
||||||
|
self.btn_cancel.setFixedWidth(btns_width)
|
||||||
|
self.btn_restart.setFixedWidth(btns_width)
|
||||||
|
|
||||||
|
def on_cancel_pressed(self):
|
||||||
|
self.done(0)
|
||||||
|
|
||||||
|
def on_restart_pressed(self):
|
||||||
|
self.done(1)
|
||||||
|
|
||||||
|
|
||||||
class SpacerWidget(QtWidgets.QWidget):
|
class SpacerWidget(QtWidgets.QWidget):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(SpacerWidget, self).__init__(parent)
|
super(SpacerWidget, self).__init__(parent)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from .categories import (
|
||||||
SystemWidget,
|
SystemWidget,
|
||||||
ProjectWidget
|
ProjectWidget
|
||||||
)
|
)
|
||||||
from .widgets import ShadowWidget
|
from .widgets import ShadowWidget, RestartDialog
|
||||||
from . import style
|
from . import style
|
||||||
|
|
||||||
from openpype.tools.settings import (
|
from openpype.tools.settings import (
|
||||||
|
|
@ -14,6 +14,8 @@ from openpype.tools.settings import (
|
||||||
|
|
||||||
|
|
||||||
class MainWidget(QtWidgets.QWidget):
|
class MainWidget(QtWidgets.QWidget):
|
||||||
|
trigger_restart = QtCore.Signal()
|
||||||
|
|
||||||
widget_width = 1000
|
widget_width = 1000
|
||||||
widget_height = 600
|
widget_height = 600
|
||||||
|
|
||||||
|
|
@ -60,6 +62,9 @@ class MainWidget(QtWidgets.QWidget):
|
||||||
for tab_widget in tab_widgets:
|
for tab_widget in tab_widgets:
|
||||||
tab_widget.saved.connect(self._on_tab_save)
|
tab_widget.saved.connect(self._on_tab_save)
|
||||||
tab_widget.state_changed.connect(self._on_state_change)
|
tab_widget.state_changed.connect(self._on_state_change)
|
||||||
|
tab_widget.restart_required_trigger.connect(
|
||||||
|
self._on_restart_required
|
||||||
|
)
|
||||||
|
|
||||||
self.tab_widgets = tab_widgets
|
self.tab_widgets = tab_widgets
|
||||||
|
|
||||||
|
|
@ -132,3 +137,15 @@ class MainWidget(QtWidgets.QWidget):
|
||||||
|
|
||||||
for tab_widget in self.tab_widgets:
|
for tab_widget in self.tab_widgets:
|
||||||
tab_widget.reset()
|
tab_widget.reset()
|
||||||
|
|
||||||
|
def _on_restart_required(self):
|
||||||
|
# Don't show dialog if there are not registered slots for
|
||||||
|
# `trigger_restart` signal.
|
||||||
|
# - For example when settings are runnin as standalone tool
|
||||||
|
if self.receivers(self.trigger_restart) < 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
dialog = RestartDialog(self)
|
||||||
|
result = dialog.exec_()
|
||||||
|
if result == 1:
|
||||||
|
self.trigger_restart.emit()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import atexit
|
||||||
|
import subprocess
|
||||||
|
|
||||||
import platform
|
import platform
|
||||||
from avalon import style
|
from avalon import style
|
||||||
from Qt import QtCore, QtGui, QtWidgets
|
from Qt import QtCore, QtGui, QtWidgets
|
||||||
from openpype.api import Logger, resources
|
from openpype.api import Logger, resources
|
||||||
|
from openpype.lib import get_pype_execute_args
|
||||||
from openpype.modules import TrayModulesManager, ITrayService
|
from openpype.modules import TrayModulesManager, ITrayService
|
||||||
from openpype.settings.lib import get_system_settings
|
from openpype.settings.lib import get_system_settings
|
||||||
import openpype.version
|
import openpype.version
|
||||||
|
|
@ -92,6 +95,34 @@ class TrayManager:
|
||||||
self.tray_widget.menu.addAction(version_action)
|
self.tray_widget.menu.addAction(version_action)
|
||||||
self.tray_widget.menu.addSeparator()
|
self.tray_widget.menu.addSeparator()
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
"""Restart Tray tool.
|
||||||
|
|
||||||
|
First creates new process with same argument and close current tray.
|
||||||
|
"""
|
||||||
|
args = get_pype_execute_args()
|
||||||
|
# Create a copy of sys.argv
|
||||||
|
additional_args = list(sys.argv)
|
||||||
|
# Check last argument from `get_pype_execute_args`
|
||||||
|
# - when running from code it is the same as first from sys.argv
|
||||||
|
if args[-1] == additional_args[0]:
|
||||||
|
additional_args.pop(0)
|
||||||
|
args.extend(additional_args)
|
||||||
|
|
||||||
|
kwargs = {}
|
||||||
|
if platform.system().lower() == "windows":
|
||||||
|
flags = (
|
||||||
|
subprocess.CREATE_NEW_PROCESS_GROUP
|
||||||
|
| subprocess.DETACHED_PROCESS
|
||||||
|
)
|
||||||
|
kwargs["creationflags"] = flags
|
||||||
|
|
||||||
|
subprocess.Popen(args, **kwargs)
|
||||||
|
self.exit()
|
||||||
|
|
||||||
|
def exit(self):
|
||||||
|
self.tray_widget.exit()
|
||||||
|
|
||||||
def on_exit(self):
|
def on_exit(self):
|
||||||
self.modules_manager.on_exit()
|
self.modules_manager.on_exit()
|
||||||
|
|
||||||
|
|
@ -116,6 +147,8 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
|
||||||
|
|
||||||
super(SystemTrayIcon, self).__init__(icon, parent)
|
super(SystemTrayIcon, self).__init__(icon, parent)
|
||||||
|
|
||||||
|
self._exited = False
|
||||||
|
|
||||||
# Store parent - QtWidgets.QMainWindow()
|
# Store parent - QtWidgets.QMainWindow()
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
|
|
@ -134,6 +167,8 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
|
||||||
# Add menu to Context of SystemTrayIcon
|
# Add menu to Context of SystemTrayIcon
|
||||||
self.setContextMenu(self.menu)
|
self.setContextMenu(self.menu)
|
||||||
|
|
||||||
|
atexit.register(self.exit)
|
||||||
|
|
||||||
def on_systray_activated(self, reason):
|
def on_systray_activated(self, reason):
|
||||||
# show contextMenu if left click
|
# show contextMenu if left click
|
||||||
if reason == QtWidgets.QSystemTrayIcon.Trigger:
|
if reason == QtWidgets.QSystemTrayIcon.Trigger:
|
||||||
|
|
@ -145,6 +180,10 @@ class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
|
||||||
|
|
||||||
- Icon won't stay in tray after exit.
|
- Icon won't stay in tray after exit.
|
||||||
"""
|
"""
|
||||||
|
if self._exited:
|
||||||
|
return
|
||||||
|
self._exited = True
|
||||||
|
|
||||||
self.hide()
|
self.hide()
|
||||||
self.tray_man.on_exit()
|
self.tray_man.on_exit()
|
||||||
QtCore.QCoreApplication.exit()
|
QtCore.QCoreApplication.exit()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue