【问题标题】:Trouble with executing "While" loop, using system tray on Python在 Python 上使用系统托盘执行“While”循环时遇到问题
【发布时间】:2020-01-18 16:14:44
【问题描述】:

我正在尝试创建每 X 秒运行一次代码块的应用程序,它的系统托盘图标只有“退出”选项。但问题是当它到达托盘函数时,它并没有读取下一行代码,因此无法启动“While”循环。 有没有其他方法可以做到这一点?

import time
import os
import sys
from PySide2 import QtWidgets, QtGui

class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
        self.setToolTip(f'Wallpy')
        menu = QtWidgets.QMenu(parent)

        exit_ = menu.addAction("Exit")
        exit_.triggered.connect(lambda: sys.exit())

        menu.addSeparator()
        self.setContextMenu(menu)


def tray():
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QWidget()
    tray_icon = SystemTrayIcon(QtGui.QIcon("tray.ico"), w)
    tray_icon.show()
    app.exec_()


def loop_function():
    print("Nice") # anything executable


tray() # launch tray icon


while True:
    loop_function() # executing every minute
    time.sleep(60)

【问题讨论】:

    标签: python pyside2 system-tray


    【解决方案1】:

    这是因为,当您使用 tray() 时,您的主应用程序启动并且 GUI 主循环启动。它会一直运行到您的应用程序退出,然后执行 while loop

    但是,如果您希望循环同时运行,则应将其与Qt 的主循环集成。在Gtk 中我们使用GLib.add_main_thread 和其他方法进行此操作,我不知道Qt,但是您可以使用线程来使用这个通用解决方案。

    from threading import Thread
    import time
    import os
    import sys
    from PySide2 import QtWidgets, QtGui
    
    
    def loop_function():
        print("Nice") # anything executable
    
    def thread_loop():
        while True:
            loop_function() # executing every minute
            time.sleep(60)
    
    class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
        def __init__(self, icon, parent=None):
            QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
            self.setToolTip(f'Wallpy')
            menu = QtWidgets.QMenu(parent)
    
            exit_ = menu.addAction("Exit")
            exit_.triggered.connect(lambda: sys.exit())
    
            menu.addSeparator()
            self.setContextMenu(menu)
    
    
    def tray():
        app = QtWidgets.QApplication(sys.argv)
        w = QtWidgets.QWidget()
        tray_icon = SystemTrayIcon(QtGui.QIcon("tray.ico"), w)
        tray_icon.show()
        app.exec_()
    
    my_loop = Thread(target=thread_loop, args=()) # Start the thread with no args
    my_loop.start()
    tray() # launch tray icon
    

    【讨论】:

    • 有一个问题,当我点击“退出”时,它一直卡住,直到我关闭 CMD 窗口,有什么解决办法吗?
    • 可能是因为,您将“退出”按钮与sys.exit 连接起来。这不好。 Python 会关闭你的脚本,但窗口仍然在屏幕上,没有任何控制器。所以解决方案是在Qt中使用正确的主循环退出。
    • 我会尝试找到合适的主循环退出,希望这可行,谢谢。如果你能指出我在哪里搜索它会很好
    • 这是一个基本信息。您可以在几乎所有教程和演示代码中找到它。我没有用过Qt,所以让我也搜索一下。如果你愿意,可以接受我的回答
    • @JArunMani 谢谢,我尝试应用相同的代码,但没有成功,我可能用错了。
    最近更新 更多