使用pyqt5时,上下文菜单不适用于任务栏图标

问题描述 投票:0回答:1

我正在使用pyqt5开发应用程序,它将在开始工作时自动隐藏窗口。我希望使用上下文菜单构建一个托盘图标,以再次显示该窗口。下面是我的简短代码,

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.set_sytem_tray_icon()

        self.current_status = Stop
        self.track_str = ''
        self.start_button.clicked.connect(self.start_button_clicked)
        self.stop_button.clicked.connect(self.stop_button_clicked)

        self.show()

    def set_sytem_tray_icon(self):
        contextMenu = QMenu()
        action = contextMenu.addAction("Show Window")
        action.triggered.connect(self.show)
        contextMenu.addAction(action)
        self.tray_icon = QSystemTrayIcon()
        self.tray_icon.setIcon(QtGui.QIcon("img.ico"))
        self.tray_icon.setContextMenu(contextMenu)
        self.tray_icon.show()

    def get_specific_window(self, class_name, title):


    def check_ULink_status(self):
        try:
            while True:
                # Doing something
                    break

    def start_button_clicked(self):

        self.hide()

        thread = threading.Thread(target=self.check_ULink_status)
        thread.setDaemon(True)
        thread.start()
        thread.join()

        self.show()

    def stop_button_clicked(self):
        reply = QMessageBox.information(self, "Warning", "Stop", QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.current_status = Stop
            self.change_button_availability()

这是我的问题,当我单击开始按钮时,该应用程序开始运行,但是任务栏图标没有响应任何操作。我相信我的主线程存在一些冲突,但是我仍然不知道发生了什么。有人对此有答案吗?

更新,我想使用qthread提供另一种解决方案。

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.set_sytem_tray_icon()

        self.current_status = Stop
        self.track_str = ''
        self.start_button.clicked.connect(self.start_button_clicked)
        self.stop_button.clicked.connect(self.stop_button_clicked)

        self.show()

    def set_sytem_tray_icon(self):
        contextMenu = QMenu()
        action = contextMenu.addAction("Show Window")
        action.triggered.connect(self.show)
        contextMenu.addAction(action)
        self.tray_icon = QSystemTrayIcon()
        self.tray_icon.setContextMenu(contextMenu)
        self.tray_icon.show()

    def set_sytem_tray_icon_with_qthread(self):
        set_sytem_tray_icon_qthread = qthread_definition.MyQThread2()
        set_sytem_tray_icon_qthread.signal.connect(self.set_sytem_tray_icon)
        set_sytem_tray_icon_qthread.start()
        set_sytem_tray_icon_qthread.wait()

    def show_mainwindow_with_qthread(self):
        show_mainwindow_qthread = qthread_definition.MyQThread2()
        show_mainwindow_qthread.signal.connect(self.show)
        show_mainwindow_qthread.start()
        show_mainwindow_qthread.wait()

    def get_specific_window(self, class_name, title):
        # doing something

    def check_ULink_status(self):
        self.set_sytem_tray_icon_with_qthread()  # add new qthread here
        try:
            while True:
                # Doing something
                    break
            self.show_mainwindow_with_qthread()

    def start_button_clicked(self):
        self.hide()
        thread = threading.Thread(target=self.check_ULink_status)
        thread.setDaemon(True)
        thread.start()

    def stop_button_clicked(self):
        reply = QMessageBox.information(self, "Warning", "Stop", QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.current_status = Stop
            self.change_button_availability()

下面显示MyQThread2类,

class MyQThread2(QtCore.QThread):
    # this thread is to create the tray icon
    signal = QtCore.pyqtSignal()

    def __init__(self):
        super().__init__()

    def run(self):
        self.signal.emit()

为了显示线程中的主窗口,我们需要创建一个qthread来完成此任务,因为显示窗口是对qt对象的一种修改,不允许在主线程之外显示。

python pyqt pyqt5 qmenu
1个回答
1
投票

[join()方法的文档指出:

join(timeout = None)

等待线程终止。这阻止了调用线程,直到调用其join()方法的线程为止终止 –通常或通过未处理的异常–或直到发生可选的超时。

[如果存在超时参数,而不是无,则应为浮点数,用于指定操作超时秒(或其分数)。由于join()始终返回None,因此您必须在join()之后调用is_alive()来确定是否发生超时–如果线程仍然存在,则join()调用超时。

当不存在超时参数或无时,该操作将阻塞直到线程终止。

一个线程可以被多次join()。

join()如果尝试加入当前的,将引发RuntimeError。线程,因为那样会导致死锁。 join()一个错误也是线程在启动之前尝试这样做例外。

(我的重点)

此方法将锁定,直到线程执行完毕,阻止GUI事件循环执行,因为它被冻结,因此它不响应事件。

解决方案是删除此方法:

join()

似乎OP使用def start_button_clicked(self): self.hide() thread = threading.Thread(target=self.check_ULink_status) thread.setDaemon(True) thread.start() # thread.join() # remove this line self.show(),以便在任务完成时再次显示窗口,如果这样,则正确的解决方案是使用信号:

join()
© www.soinside.com 2019 - 2024. All rights reserved.