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 ?
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.
Just a small edit, i saw on some c++ examples they used to use ,
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]
.
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
.
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.
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