mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 01:14:15 +02:00
gem selector panel working
This commit is contained in:
@@ -49,7 +49,7 @@ else:
|
||||
enabled_managers = [m for m in managers if m.is_enabled()]
|
||||
|
||||
if not user_config.gems and enabled_managers:
|
||||
gem_panel = GemSelectorPanel(enabled_managers, i18n, boot=True)
|
||||
gem_panel = GemSelectorPanel(enabled_managers, i18n, managers_set=None)
|
||||
gem_panel.show()
|
||||
else:
|
||||
manager = GenericSoftwareManager(enabled_managers, context=context, app_args=args)
|
||||
@@ -62,7 +62,9 @@ else:
|
||||
download_icons=bool(args.download_icons),
|
||||
screen_size=app.primaryScreen().size(),
|
||||
suggestions=args.sugs,
|
||||
display_limit=args.max_displayed)
|
||||
display_limit=args.max_displayed,
|
||||
config=user_config,
|
||||
context=context)
|
||||
|
||||
if args.tray:
|
||||
trayIcon = TrayIcon(locale_keys=i18n,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import inspect
|
||||
import os
|
||||
import pkgutil
|
||||
from typing import List
|
||||
from typing import List, Type
|
||||
|
||||
from bauh import ROOT_DIR
|
||||
from bauh.api.abstract.controller import SoftwareManager, ApplicationContext
|
||||
@@ -29,10 +29,11 @@ def load_managers(locale: str, context: ApplicationContext, names: List[str] = N
|
||||
manager_class = find_manager(module)
|
||||
|
||||
if manager_class:
|
||||
locale_path = '{}/resources/locale'.format(f.path)
|
||||
if locale:
|
||||
locale_path = '{}/resources/locale'.format(f.path)
|
||||
|
||||
if os.path.exists(locale_path):
|
||||
context.i18n.update(util.get_locale_keys(locale, locale_path))
|
||||
if os.path.exists(locale_path):
|
||||
context.i18n.update(util.get_locale_keys(locale, locale_path))
|
||||
|
||||
managers.append(manager_class(context=context))
|
||||
|
||||
|
||||
@@ -113,6 +113,11 @@ def save_several(pkgnames: Set[str], mirror: str, overwrite: bool = True) -> int
|
||||
if entries:
|
||||
desktop_matches[pkg] = entries[0]
|
||||
|
||||
if len(entries) > 1:
|
||||
for e in entries:
|
||||
if e.startswith('/usr/share/applications'):
|
||||
desktop_matches[pkg] = e
|
||||
|
||||
if not desktop_matches:
|
||||
no_desktop_files = to_cache
|
||||
else:
|
||||
@@ -130,7 +135,7 @@ def save_several(pkgnames: Set[str], mirror: str, overwrite: bool = True) -> int
|
||||
|
||||
for field in RE_DESKTOP_ENTRY.findall(desktop_entry):
|
||||
if field[0] == 'Exec':
|
||||
p.command = field[1].strip()
|
||||
p.command = field[1].strip().replace('"', '')
|
||||
elif field[0] == 'Icon':
|
||||
p.icon_path = field[1].strip()
|
||||
|
||||
|
||||
@@ -90,13 +90,14 @@ class ArchPackage(SoftwarePackage):
|
||||
return cache
|
||||
|
||||
def fill_cached_data(self, data: dict):
|
||||
for a in {'command', 'icon_path', 'mirror', 'desktop_entry'}:
|
||||
val = data.get(a)
|
||||
if val:
|
||||
setattr(self, a, val)
|
||||
if data:
|
||||
for a in {'command', 'icon_path', 'mirror', 'desktop_entry'}:
|
||||
val = data.get(a)
|
||||
if val:
|
||||
setattr(self, a, val)
|
||||
|
||||
if a == 'icon_path':
|
||||
self.icon_url = val
|
||||
if a == 'icon_path':
|
||||
self.icon_url = val
|
||||
|
||||
def can_be_run(self) -> bool:
|
||||
# only returns if there is a desktop entry set for the application to avoid running command-line applications
|
||||
|
||||
@@ -44,7 +44,7 @@ popup.button.yes=Yes
|
||||
popup.button.no=No
|
||||
popup.button.cancel=Cancel
|
||||
tray.action.manage=Manage applications
|
||||
tray.action.exit=Exit
|
||||
tray.action.exit=Quit
|
||||
tray.action.about=About
|
||||
tray.action.refreshing=Refreshing
|
||||
notification.new_updates=Updates
|
||||
@@ -85,7 +85,7 @@ bt.app_upgrade=Upgrade
|
||||
bt.app_not_upgrade=Don't upgrade
|
||||
manage_window.upgrade_all.popup.title=Upgrade
|
||||
manage_window.upgrade_all.popup.body=Upgrade all selected applications ?
|
||||
manage_window.bt_about.tooltip=About
|
||||
manage_window.settings.about=About
|
||||
warning.no_managers=There are no installed extensions. It will not be possible to intall and manage applications.
|
||||
confirmation=confirmation
|
||||
and=and
|
||||
@@ -103,3 +103,10 @@ manage_window.name_filter.tooltip=Type here to filter apps by name
|
||||
manage_window.name_filter.placeholder=Filter by name
|
||||
publisher=publisher
|
||||
publisher.unknown=unknown publisher
|
||||
welcome=welcome
|
||||
gem_selector.title=Application types
|
||||
gem_selector.question=What types of applications do you want to find here ?
|
||||
proceed=proceed
|
||||
change=change
|
||||
exit=exit
|
||||
manage_window.settings.gems=Application types
|
||||
@@ -46,7 +46,7 @@ popup.button.yes=Sí
|
||||
popup.button.no=No
|
||||
popup.button.cancel=Cancelar
|
||||
tray.action.manage=Administrar aplicativos
|
||||
tray.action.exit=Salir
|
||||
tray.action.exit=Cerrar
|
||||
tray.action.about=Sobre
|
||||
tray.action.refreshing=Recargando
|
||||
notification.new_updates=Actualizaciones
|
||||
@@ -87,7 +87,7 @@ bt.app_upgrade=Actualizar
|
||||
bt.app_not_upgrade=No actualizar
|
||||
manage_window.upgrade_all.popup.title=Actualizar
|
||||
manage_window.upgrade_all.popup.body=¿Actualizar todos los aplicativos seleccionados?
|
||||
manage_window.bt_about.tooltip=Sobre
|
||||
manage_window.settings.about=Sobre
|
||||
warning.no_managers=No hay extensiones instaladas. No será posible instalar y administrar aplicaciones.
|
||||
confirmation=confirmación
|
||||
and=y
|
||||
@@ -104,4 +104,11 @@ any=cualquier
|
||||
manage_window.name_filter.tooltip=Escriba aquí para filtrar aplicaciones por nombre
|
||||
manage_window.name_filter.placeholder=Filtrar por nombre
|
||||
publisher=publicador
|
||||
publisher.unknown=publicador desconocido
|
||||
publisher.unknown=publicador desconocido
|
||||
welcome=bienvenido
|
||||
gem_selector.title=Tipos de aplicativos
|
||||
gem_selector.question=¿Qué tipos de aplicativos quieres encontrar aquí?
|
||||
proceed=continuar
|
||||
change=cambiar
|
||||
exit=salir
|
||||
manage_window.settings.gems=Tipos de aplicativos
|
||||
@@ -46,7 +46,7 @@ popup.button.yes=Sim
|
||||
popup.button.no=Não
|
||||
popup.button.cancel=Cancelar
|
||||
tray.action.manage=Gerenciar aplicativos
|
||||
tray.action.exit=Sair
|
||||
tray.action.exit=Fechar
|
||||
tray.action.about=Sobre
|
||||
tray.action.refreshing=Recarregando
|
||||
notification.new_updates=Atualizações
|
||||
@@ -87,7 +87,7 @@ bt.app_upgrade=Atualizar
|
||||
bt.app_not_upgrade=Não atualizar
|
||||
manage_window.upgrade_all.popup.title=Atualizar
|
||||
manage_window.upgrade_all.popup.body=Atualizar todos os aplicativos selecionados ?
|
||||
manage_window.bt_about.tooltip=Sobre
|
||||
manage_window.settings.about=Sobre
|
||||
warning.no_managers=Não há nenhuma extensão instalada. Não será possível instalar e gerenciar aplicações.
|
||||
confirmation=confirmação
|
||||
and=e
|
||||
@@ -104,4 +104,11 @@ any=qualquer
|
||||
manage_window.name_filter.tooltip=Digite aqui para filtrar aplicativos pelo nome
|
||||
manage_window.name_filter.placeholder=Filtrar por nome
|
||||
publisher=publicador
|
||||
publisher.unknown=publicador desconhecido
|
||||
publisher.unknown=publicador desconhecido
|
||||
welcome=bem vindo
|
||||
gem_selector.title=Tipos de aplicativos
|
||||
gem_selector.question=Quais tipos de aplicativos você quer encontrar por aqui ?
|
||||
proceed=continuar
|
||||
change=alterar
|
||||
exit=sair
|
||||
manage_window.settings.gems=Tipos de aplicativos
|
||||
@@ -47,11 +47,12 @@ class AsyncDiskCacheLoader(Thread, DiskCacheLoader):
|
||||
if os.path.exists(pkg.get_disk_data_path()):
|
||||
with open(pkg.get_disk_data_path()) as f:
|
||||
cached_data = json.loads(f.read())
|
||||
pkg.fill_cached_data(cached_data)
|
||||
cache = self.cache_map.get(pkg.__class__)\
|
||||
if cached_data:
|
||||
pkg.fill_cached_data(cached_data)
|
||||
cache = self.cache_map.get(pkg.__class__)\
|
||||
|
||||
if cache:
|
||||
cache.add_non_existing(pkg.id, cached_data)
|
||||
if cache:
|
||||
cache.add_non_existing(pkg.id, cached_data)
|
||||
|
||||
|
||||
class DefaultDiskCacheLoaderFactory(DiskCacheLoaderFactory):
|
||||
@@ -63,10 +64,8 @@ class DefaultDiskCacheLoaderFactory(DiskCacheLoaderFactory):
|
||||
|
||||
def map(self, pkg_type: Type[SoftwarePackage], cache: MemoryCache):
|
||||
if pkg_type:
|
||||
if pkg_type in self.cache_map:
|
||||
raise Exception('{} is already mapped')
|
||||
|
||||
self.cache_map[pkg_type] = cache
|
||||
if pkg_type not in self.cache_map:
|
||||
self.cache_map[pkg_type] = cache
|
||||
|
||||
def new(self) -> AsyncDiskCacheLoader:
|
||||
return AsyncDiskCacheLoader(enabled=self.disk_cache_enabled, cache_map=self.cache_map)
|
||||
|
||||
@@ -13,32 +13,12 @@ from bauh.api.abstract.model import PackageStatus
|
||||
from bauh.util import resource
|
||||
from bauh.util.html import strip_html
|
||||
from bauh.view.qt import dialog
|
||||
from bauh.view.qt.components import IconButton
|
||||
from bauh.view.qt.view_model import PackageView, PackageViewStatus
|
||||
|
||||
INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold'
|
||||
|
||||
|
||||
class IconButton(QWidget):
|
||||
|
||||
def __init__(self, icon_path: str, action, background: str = None, align: int = Qt.AlignCenter, tooltip: str = None):
|
||||
super(IconButton, self).__init__()
|
||||
self.bt = QToolButton()
|
||||
self.bt.setIcon(QIcon(icon_path))
|
||||
self.bt.clicked.connect(action)
|
||||
|
||||
if background:
|
||||
self.bt.setStyleSheet('QToolButton { color: white; background: ' + background + '}')
|
||||
|
||||
if tooltip:
|
||||
self.bt.setToolTip(tooltip)
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setAlignment(align)
|
||||
layout.addWidget(self.bt)
|
||||
self.setLayout(layout)
|
||||
|
||||
|
||||
class UpdateToggleButton(QWidget):
|
||||
|
||||
def __init__(self, app_view: PackageView, root: QWidget, i18n: dict, checked: bool = True, clickable: bool = True):
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QRadioButton, QGroupBox, QCheckBox, QComboBox, QGridLayout, QWidget, \
|
||||
QLabel, QSizePolicy, QLineEdit
|
||||
QLabel, QSizePolicy, QLineEdit, QToolButton, QHBoxLayout
|
||||
|
||||
from bauh import ROOT_DIR
|
||||
from bauh.api.abstract.view import SingleSelectComponent, InputOption, MultipleSelectComponent, SelectViewType
|
||||
from bauh.commons import resource
|
||||
|
||||
|
||||
class RadioButtonQt(QRadioButton):
|
||||
@@ -162,6 +161,27 @@ class InputFilter(QLineEdit):
|
||||
self.last_text = p_str
|
||||
|
||||
|
||||
class IconButton(QWidget):
|
||||
|
||||
def __init__(self, icon_path: str, action, background: str = None, align: int = Qt.AlignCenter, tooltip: str = None):
|
||||
super(IconButton, self).__init__()
|
||||
self.bt = QToolButton()
|
||||
self.bt.setIcon(QIcon(icon_path))
|
||||
self.bt.clicked.connect(action)
|
||||
|
||||
if background:
|
||||
self.bt.setStyleSheet('QToolButton { color: white; background: ' + background + '}')
|
||||
|
||||
if tooltip:
|
||||
self.bt.setToolTip(tooltip)
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setAlignment(align)
|
||||
layout.addWidget(self.bt)
|
||||
self.setLayout(layout)
|
||||
|
||||
|
||||
def new_single_select(model: SingleSelectComponent):
|
||||
if model.type == SelectViewType.RADIO:
|
||||
return RadioSelectQt(model)
|
||||
|
||||
@@ -16,26 +16,28 @@ from bauh.view.qt.components import MultipleSelectQt, CheckboxQt, new_spacer
|
||||
|
||||
class GemSelectorPanel(QWidget):
|
||||
|
||||
def __init__(self, managers: List[SoftwareManager], i18n: dict, boot: bool):
|
||||
def __init__(self, managers: List[SoftwareManager], i18n: dict, managers_set: List[str], exit_on_close: bool = True):
|
||||
super(GemSelectorPanel, self).__init__()
|
||||
self.managers = managers
|
||||
self.setLayout(QGridLayout())
|
||||
self.setWindowIcon(QIcon(resource.get_path('img/logo.svg', ROOT_DIR)))
|
||||
self.setWindowTitle('Welcome' if boot else 'Supported types')
|
||||
self.setWindowTitle(i18n['welcome'].capitalize() if not managers_set else i18n['gem_selector.title'])
|
||||
self.resize(400, 400)
|
||||
self.exit_on_close = exit_on_close
|
||||
|
||||
self.label_question = QLabel('What types of applications do you want to find here ?')
|
||||
self.label_question = QLabel(i18n['gem_selector.question'])
|
||||
self.label_question.setStyleSheet('QLabel { font-weight: bold}')
|
||||
self.layout().addWidget(self.label_question, 0, 1, Qt.AlignHCenter)
|
||||
|
||||
self.bt_proceed = QPushButton('Proceed')
|
||||
self.bt_proceed.setStyleSheet('QPushButton { background: green; color: white; font-weight: bold}')
|
||||
self.bt_proceed.setEnabled(True)
|
||||
self.bt_proceed = QPushButton(i18n['proceed' if not managers_set else 'change'].capitalize())
|
||||
self.bt_proceed.setStyleSheet("""QPushButton { background: green; color: white; font-weight: bold}
|
||||
QPushButton:disabled { background-color: gray; }
|
||||
""")
|
||||
self.bt_proceed.clicked.connect(self.save)
|
||||
|
||||
self.bt_exit = QPushButton('Exit')
|
||||
self.bt_exit = QPushButton(i18n['exit'].capitalize())
|
||||
self.bt_exit.setStyleSheet('QPushButton { background: red; color: white; font-weight: bold}')
|
||||
self.bt_exit.clicked.connect(lambda: QCoreApplication.exit())
|
||||
self.bt_exit.clicked.connect(self.exit)
|
||||
|
||||
gem_options = []
|
||||
|
||||
@@ -45,7 +47,14 @@ class GemSelectorPanel(QWidget):
|
||||
value=modname,
|
||||
icon_path='{r}/gems/{n}/resources/img/{n}.png'.format(r=ROOT_DIR, n=modname)))
|
||||
|
||||
self.gem_select_model = MultipleSelectComponent(label='', options=gem_options, default_options=set(gem_options), max_per_line=3)
|
||||
if managers_set:
|
||||
default_ops = {o for o in gem_options if o.value in managers_set}
|
||||
else:
|
||||
default_ops = set(gem_options)
|
||||
|
||||
self.bt_proceed.setEnabled(bool(default_ops))
|
||||
|
||||
self.gem_select_model = MultipleSelectComponent(label='', options=gem_options, default_options=default_ops, max_per_line=3)
|
||||
|
||||
self.gem_select = MultipleSelectQt(self.gem_select_model, self.check_state)
|
||||
self.layout().addWidget(self.gem_select, 1, 1)
|
||||
@@ -59,11 +68,18 @@ class GemSelectorPanel(QWidget):
|
||||
self.setFixedSize(self.size())
|
||||
|
||||
def check_state(self, model: CheckboxQt, checked: bool):
|
||||
self.bt_proceed.setEnabled(bool(self.gem_select_model.values))
|
||||
if self.isVisible():
|
||||
self.bt_proceed.setEnabled(bool(self.gem_select_model.values))
|
||||
|
||||
def save(self):
|
||||
config = Configuration(gems=[o.value for o in self.gem_select_model.values])
|
||||
save(config)
|
||||
subprocess.Popen([sys.executable, *sys.argv])
|
||||
self.close()
|
||||
QCoreApplication.exit()
|
||||
|
||||
def exit(self):
|
||||
if self.exit_on_close:
|
||||
QCoreApplication.exit()
|
||||
else:
|
||||
self.close()
|
||||
|
||||
|
||||
@@ -3,20 +3,24 @@ from functools import reduce
|
||||
from typing import List, Type, Set
|
||||
|
||||
from PyQt5.QtCore import QEvent, Qt, QSize, pyqtSignal
|
||||
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent, QPixmap
|
||||
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent, QPixmap, QCursor
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \
|
||||
QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QPushButton, QComboBox
|
||||
QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QPushButton, QComboBox, QMenu, QAction
|
||||
|
||||
from bauh.api.abstract.cache import MemoryCache
|
||||
from bauh.api.abstract.context import ApplicationContext
|
||||
from bauh.api.abstract.controller import SoftwareManager
|
||||
from bauh.api.abstract.model import SoftwarePackage, PackageAction
|
||||
from bauh.api.abstract.view import MessageType
|
||||
|
||||
from bauh.core import gems
|
||||
from bauh.core.config import Configuration
|
||||
from bauh.util import util, resource
|
||||
from bauh.view.qt import dialog, commons
|
||||
from bauh.view.qt.about import AboutDialog
|
||||
from bauh.view.qt.apps_table import AppsTable, UpdateToggleButton
|
||||
from bauh.view.qt.components import new_spacer, InputFilter
|
||||
from bauh.view.qt.components import new_spacer, InputFilter, IconButton
|
||||
from bauh.view.qt.confirmation import ConfirmationDialog
|
||||
from bauh.view.qt.gem_selector import GemSelectorPanel
|
||||
from bauh.view.qt.history import HistoryDialog
|
||||
from bauh.view.qt.info import InfoDialog
|
||||
from bauh.view.qt.root import is_root, ask_root_password
|
||||
@@ -39,7 +43,8 @@ class ManageWindow(QWidget):
|
||||
signal_user_res = pyqtSignal(bool)
|
||||
signal_table_update = pyqtSignal()
|
||||
|
||||
def __init__(self, i18n: dict, icon_cache: MemoryCache, manager: SoftwareManager, disk_cache: bool, download_icons: bool, screen_size, suggestions: bool, display_limit: int, tray_icon=None):
|
||||
def __init__(self, i18n: dict, icon_cache: MemoryCache, manager: SoftwareManager, disk_cache: bool, download_icons: bool,
|
||||
screen_size, suggestions: bool, display_limit: int, config: Configuration, context: ApplicationContext, tray_icon=None):
|
||||
super(ManageWindow, self).__init__()
|
||||
self.i18n = i18n
|
||||
self.manager = manager
|
||||
@@ -53,6 +58,8 @@ class ManageWindow(QWidget):
|
||||
self.disk_cache = disk_cache
|
||||
self.download_icons = download_icons
|
||||
self.screen_size = screen_size
|
||||
self.config = config
|
||||
self.context = context
|
||||
|
||||
self.icon_app = QIcon(resource.get_path('img/logo.svg'))
|
||||
self.resize(ManageWindow.__BASE_HEIGHT__, ManageWindow.__BASE_HEIGHT__)
|
||||
@@ -230,12 +237,8 @@ class ManageWindow(QWidget):
|
||||
|
||||
self.toolbar_bottom.addWidget(new_spacer())
|
||||
|
||||
bt_about = QToolButton()
|
||||
bt_about.setStyleSheet('QToolButton { border: 0px; }')
|
||||
bt_about.setIcon(QIcon(resource.get_path('img/about.svg')))
|
||||
bt_about.clicked.connect(self._show_about)
|
||||
bt_about.setToolTip(self.i18n['manage_window.bt_about.tooltip'])
|
||||
self.ref_bt_about = self.toolbar_bottom.addWidget(bt_about)
|
||||
bt_settings = IconButton(icon_path=resource.get_path('img/app_settings.svg'), action=self._show_settings_menu, background='#12ABAB')
|
||||
self.ref_bt_settings = self.toolbar_bottom.addWidget(bt_settings)
|
||||
|
||||
self.layout.addWidget(self.toolbar_bottom)
|
||||
|
||||
@@ -712,7 +715,7 @@ class ManageWindow(QWidget):
|
||||
def _begin_action(self, action_label: str, keep_search: bool = False, keep_bt_installed: bool = True, clear_filters: bool = False):
|
||||
self.ref_input_name_filter.setVisible(False)
|
||||
self.ref_combo_filter_type.setVisible(False)
|
||||
self.ref_bt_about.setVisible(False)
|
||||
self.ref_bt_settings.setVisible(False)
|
||||
self.ref_label_updates.setVisible(False)
|
||||
self.thread_animate_progress.stop = False
|
||||
self.thread_animate_progress.start()
|
||||
@@ -748,7 +751,7 @@ class ManageWindow(QWidget):
|
||||
self.progress_bar.setTextVisible(False)
|
||||
|
||||
self._change_label_substatus('')
|
||||
self.ref_bt_about.setVisible(True)
|
||||
self.ref_bt_settings.setVisible(True)
|
||||
|
||||
self.ref_label_updates.setVisible(True)
|
||||
self.ref_bt_refresh.setVisible(True)
|
||||
@@ -897,3 +900,27 @@ class ManageWindow(QWidget):
|
||||
self.refresh_apps(pkg_types={res['pkg'].model.__class__})
|
||||
else:
|
||||
self.checkbox_console.setChecked(True)
|
||||
|
||||
def _show_gems_selector(self):
|
||||
managers = gems.load_managers(context=self.context, locale=None)
|
||||
enabled_managers = [m for m in managers if m.is_enabled()]
|
||||
gem_panel = GemSelectorPanel(managers=enabled_managers, i18n=self.i18n, managers_set=self.config.gems, exit_on_close=False)
|
||||
gem_panel.show()
|
||||
|
||||
def _show_settings_menu(self):
|
||||
menu_row = QMenu()
|
||||
|
||||
action_gems = QAction(self.i18n['manage_window.settings.gems'])
|
||||
action_gems.setIcon(self.icon_app)
|
||||
|
||||
action_gems.triggered.connect(self._show_gems_selector)
|
||||
menu_row.addAction(action_gems)
|
||||
|
||||
action_about = QAction(self.i18n['manage_window.settings.about'])
|
||||
action_about.setIcon(QIcon(resource.get_path('img/about.svg')))
|
||||
action_about.triggered.connect(self._show_about)
|
||||
menu_row.addAction(action_about)
|
||||
|
||||
menu_row.adjustSize()
|
||||
menu_row.popup(QCursor.pos())
|
||||
menu_row.exec_()
|
||||
|
||||
Reference in New Issue
Block a user