简体   繁体   English

从pyside2获取根对象

[英]Get root object from pyside2

i have small application that i want to minimize to system tray, and i do have code that creates icon and minimizes it to system tray on push of a button, (on purpose i did not want to overwrite default close operation). 我有一个小的应用程序,我想将其最小化到系统托盘,并且我确实有创建代码并将代码最小化到按一下按钮的系统托盘中的代码(目的是我不想覆盖默认的关闭操作)。

How ever, i dont know how to get my root object from qml, so i am unable to perform any action, and when i would get it, what type would it be ? 但是,我不知道如何从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)

now the following code i made to "work" on my application, even though is not working properly. 现在,即使我的应用无法正常运行,我仍在执行以下代码来“运行”我的应用程序。

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
        ) 

the only thing i did i changed 我所做的唯一改变

class Manager(QObject): to (QMainWindow)

and i could use this code, but instead manipulating my window, i got the completly new window, nonetheless i did get normal system tray icon and all menu items i needed. 而且我可以使用此代码,但是却操纵了我的窗口,我得到了一个全新的窗口,尽管如此,我的确得到了正常的系统任务栏图标和所需的所有菜单项。

So bottom line, how can i get reference of my root, and how can i use minimize to tray on it. 因此,最重要的是,我如何获得我的根目录的引用,以及如何使用最小化来对其进行托盘化。

root of my QML is normal ApplicationWindow. 我的QML的根是普通的ApplicationWindow。

Just a small edit, i saw on some c++ examples they used to use , 只是一个小小的修改,我在他们曾经使用的一些c ++示例中看到了,

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

but this does not work anymore as i have seen. 但这就像我所见不再有效。 but i havent found any similar way. 但我还没有找到任何类似的方法。

In C++ rootObjects() returns a QList and the method at(i) returns the i-th object, in the case of at(0) returns the first element, in the case of Python rootObjects() returns a list , and to access the first element in python you should only use rootObjects()[0] . 在C ++中, rootObjects()返回一个QList ,方法at(i)返回第i个对象,在at(0)返回第一个元素的情况下,在Python rootObjects()返回list的情况下,并访问python中的第一个元素,您只能使用rootObjects()[0]

If you are still using the code of your previous questions it is not advisable to mix classes, in the case of Manager had another objective so it is advisable to create another class specialized in handling the QSystemTrayIcon . 如果您仍在使用先前问题的代码,则不建议混合使用类,如果Manager具有另一个目标,则建议创建另一个专门处理QSystemTrayIcon

If you are using QQmlApplicationEngine then you must be using ApplicationWindow or Window , and these classes inherit from QQuickWindow so we can use their methods since in Python the casting is automatic unlike C++, QQuickWindow has the method close, show and hide. 如果您使用的是QQmlApplicationEngine那么您必须使用ApplicationWindowWindow ,并且这些类都继承自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_()) 

You can find the complete code in the following link 您可以在以下链接中找到完整的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM