我正在使用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对象的一种修改,不允许在主线程之外显示。
[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()