Получить корневой объект из pyside2

У меня есть небольшое приложение, которое я хочу свернуть в системный лоток, и у меня есть код, который создает значок и минимизирует его в системном лотке при нажатии кнопки (специально я не хотел перезаписывать операцию закрытия по умолчанию).

Однако я не знаю, как получить свой корневой объект из qml, поэтому я не могу выполнить никаких действий, и когда я его получу, какого типа это будет?

app = QApplication(sys.argv)

engine = QQmlApplicationEngine()
manager = Manager()
ctx = engine.rootContext()
ctx.setContextProperty("Manager", manager)
engine.load('main.qml')
if not engine.rootObjects():
    sys.exit(-1)
app.setWindowIcon(QtGui.QIcon('ico.png')) 
sys.exit(app.exec_()) 



class Manager(QObject):
 def __init__(self):
    QObject.__init__(self)


 self.tray_icon = QSystemTrayIcon(self)

Теперь следующий код, который я заставил "работать" в моем приложении, даже если он не работает должным образом.

self.tray_icon.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
    show_action = QAction("Show", self)
    quit_action = QAction("Exit", self)
    hide_action = QAction("Hide", self)
    show_action.triggered.connect(self.show)
    hide_action.triggered.connect(self.hide)
    quit_action.triggered.connect(qApp.quit)
    tray_menu = QMenu()
    tray_menu.addAction(show_action)
    tray_menu.addAction(hide_action)
    tray_menu.addAction(quit_action)
    self.tray_icon.setContextMenu(tray_menu)
    self.tray_icon.show()


def minimize(self):
    self.hide()
    print("Test")
    _translate = QtCore.QCoreApplication.translate
    #self.hide()
    self.tray_icon.showMessage(
            "Tray Program",
            "Application was minimized to Tray",
            QSystemTrayIcon.Information,
            2000
        ) 

единственное, что я сделал, я изменил

class Manager(QObject): to (QMainWindow)

и я мог бы использовать этот код, но вместо того, чтобы манипулировать своим окном, я получил полностью новое окно, тем не менее, я получил нормальный значок на панели задач и все элементы меню, которые мне были нужны.

Итак, суть в том, как я могу получить ссылку на свой корень и как я могу использовать на нем сворачивание в трей.

корень моего QML - это обычный ApplicationWindow.

Небольшое изменение, которое я видел на некоторых примерах C ++, которые они использовали,

root = engine.rootObjects().at(0);

но это больше не работает, как я видел. но я не нашел подобного пути.


person ImRaphael    schedule 26.05.2018    source источник


Ответы (1)


В C ++ rootObjects() возвращает QList, а метод at(i) возвращает i-й объект, в случае at(0) возвращает первый элемент, в случае Python rootObjects() возвращает list, а для доступа к первому элементу в python вы должны использовать только rootObjects()[0] .

Если вы все еще используете код из своих предыдущих вопросов, не рекомендуется смешивать классы, в случае, если у Manager была другая цель, поэтому рекомендуется создать другой класс, специализирующийся на обработке QSystemTrayIcon.

Если вы используете QQmlApplicationEngine, вы должны использовать ApplicationWindow или Window, и эти классы наследуются от QQuickWindow, поэтому мы можем использовать их методы, поскольку в Python приведение типов выполняется автоматически, в отличие от C ++, QQuickWindow имеет метод close, show и hide.

import sys
import os

from PySide2.QtCore import Qt, QObject, Signal, Slot, Property
from PySide2.QtWidgets import QApplication, QSystemTrayIcon, QStyle, QAction, QMenu, QMessageBox
from PySide2.QtQml import QQmlApplicationEngine

my_list = ['here','is','my','list']

class Manager(QObject):
    ...

class SystemTrayIconManager(QObject):
    def __init__(self, window, parent=None):
        QObject.__init__(self, parent)
        self.window = window
        self.window.closing.connect(self.onClosing)
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(qApp.style().standardIcon(QStyle.SP_MediaPlay))
        show_action = QAction("Show", self)
        quit_action = QAction("Exit", self)
        hide_action = QAction("Hide", self)
        minimize_action = QAction("Minimize", self)
        show_action.triggered.connect(self.window.show)
        hide_action.triggered.connect(self.window.hide)
        quit_action.triggered.connect(qApp.quit)
        minimize_action.triggered.connect(self.minimize)
        tray_menu = QMenu()
        tray_menu.addAction(show_action)
        tray_menu.addAction(hide_action)
        tray_menu.addAction(quit_action)
        tray_menu.addAction(minimize_action)
        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.show()

    def onClosing(self):
        if self.tray_icon.isVisible():
            QMessageBox.information(None, "Systray",
                    "The program will keep running in the system tray. To "
                    "terminate the program, choose <b>Quit</b> in the "
                    "context menu of the system tray entry.")
            self.window.hide()

    def minimize(self):
        self.window.hide()
        self.tray_icon.showMessage(
                "Tray Program",
                "Application was minimized to Tray",
                QSystemTrayIcon.Information,
                2000
            ) 


if __name__ == "__main__":
    os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
    app = QApplication(sys.argv)

    if not QSystemTrayIcon.isSystemTrayAvailable():
        QMessageBox.critical(None, "Systray",
                "I couldn't detect any system tray on this system.")
        sys.exit(1)

    QApplication.setQuitOnLastWindowClosed(False)
    engine = QQmlApplicationEngine()
    manager = Manager()
    ctx = engine.rootContext()
    ctx.setContextProperty("Manager", manager)
    engine.load('main.qml')

    if not engine.rootObjects():
        sys.exit(-1)
    m = SystemTrayIconManager(engine.rootObjects()[0])
    manager.list_fill()
    sys.exit(app.exec_()) 

Вы можете найти полный код по следующей ссылке

person eyllanesc    schedule 26.05.2018