I'm developing an application with pyqt5, which will hide window automatically when it starts to work. And I hope to build a tray icon with context menu to show the window again. Below is my brief code,
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()
Here is my problem, when I clicked start button, the application started working but tray icon didn't response to any action. I believe there was some conflict with my main thread, but I still can't figure out what's going on. Does anyone have answer for this?
Update, I would like to provide another solution using 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()
where MyQThread2 class is shown below,
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()
To show the main window in the thread, we need to create a qthread to finish this task, because showing the window is a kind of modification of qt object, which is not allowed outside main thread.