앱을 사용하다가 tray icon 으로 축소를 하면 좀더 편하겠다는 생각이 들었습니다.
1) 코드 생성
사용한 ChatGPT 프롬프트는 다음과 같습니다.
pyqt5 로 Hello 라는 버튼을 표시해주세요.
축소 아이콘을 클릭하면 누르면 tray 로 축소하고
종료 아이콘을 클릭하면 앱을 종료하시겠습니까? 라고 묻고 Yes 선택 시 앱을 종료하고 다른 것을 선택하면 tray 로 축소하도록 해주세요.
생성된 코드는 다음과 같으며 일부 버그는 수정하였습니다.
아래 코드는 다음과 같이 다운받을 수 있습니다.
git clone git@github.com:jbpark/jbDeskExample.git
cd jbDeskExample/jbDesk/ch1.4
tray_icon.py
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMenu, QAction, QMessageBox, QSystemTrayIcon
class HelloApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("PyQt5 Tray Example")
self.setGeometry(100, 100, 300, 200)
# 버튼 생성
self.button = QPushButton("Hello", self)
self.button.setGeometry(100, 80, 100, 40)
self.button.clicked.connect(self.show_message)
# 시스템 트레이 아이콘 생성
self.tray_icon = QSystemTrayIcon(self)
icon_path = "tray_icon.png" # 아이콘 경로 확인 (아이콘 파일이 있어야 합니다)
self.tray_icon.setIcon(QIcon(icon_path))
self.tray_icon.setToolTip("PyQt5 Tray App")
self.tray_icon.show() # 트레이 아이콘 표시
# 트레이 메뉴 설정
tray_menu = QMenu()
restore_action = QAction("열기", self)
restore_action.triggered.connect(self.show_window)
quit_action = QAction("종료", self)
quit_action.triggered.connect(self.exit_app)
tray_menu.addAction(restore_action)
tray_menu.addAction(quit_action)
self.tray_icon.setContextMenu(tray_menu)
self.tray_icon.activated.connect(self.tray_icon_clicked)
def show_message(self):
QMessageBox.information(self, "Message", "Hello, PyQt5!")
def closeEvent(self, event):
"""창 닫기 버튼(X) 클릭 시 앱 종료 여부 확인"""
reply = QMessageBox.question(self, "종료 확인", "앱을 종료하시겠습니까?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
self.exit_app()
else:
event.ignore() # 창을 최소화하여 숨깁니다
self.hide() # 창 숨기기
self.tray_icon.showMessage(
"앱이 실행 중", "트레이에서 실행 중입니다.", QSystemTrayIcon.Information, 2000
)
def show_window(self):
"""트레이 메뉴에서 '열기' 선택 시 창 복원"""
self.showNormal()
self.activateWindow()
def tray_icon_clicked(self, reason):
"""트레이 아이콘 클릭 시 창을 다시 보이게 함"""
if reason == QSystemTrayIcon.ActivationReason.Trigger:
self.show_window()
def exit_app(self):
"""트레이 메뉴에서 '종료' 선택 시 앱 완전히 종료"""
self.tray_icon.hide() # 트레이 아이콘 숨기기
QApplication.quit() # PyQt5 이벤트 루프 종료
sys.exit(0) # 강제 종료
if __name__ == "__main__":
app = QApplication(sys.argv)
# 모든 창이 닫혀도 앱이 종료되지 않도록 설정
app.setQuitOnLastWindowClosed(False)
# 아이콘 설정
app.setWindowIcon(QIcon("tray_icon.png"))
window = HelloApp()
window.show()
sys.exit(app.exec_())
2) 코드 실행
코드 실행 후 tray 축소 전입니다.
축소 아이콘을 클릭하면 아래와 같이 tray icon 으로 표시됩니다.
3) JbDesk 에 코드 통합
tray_icon.py 에서 tray 관련 부분만 jbesk.py 에 머지하면 됩니다.
코드는 다음 위치에 있습니다.
git clone git@github.com:jbpark/jbDeskExample.git
cat jbDeskExample/jbDesk/ch1.4/jbesk.py
다음은 코드 통합 후 실행한 모습이며 종료 아이콘 클릭 시 앱을 종료할지 물어봅니다.
Yes 클릭 시 앱이 종료되며 No 선택 시 Tray icon 으로 축소됩니다.
'유틸리티 > JbDesk' 카테고리의 다른 글
JbDesk 1.6편-코드 리팩터링 (1) | 2025.03.28 |
---|---|
JbDesk 1.5편-exe 만들기 (0) | 2025.03.28 |
JbDesk 1.3편-로그 timezone 변경 (0) | 2025.03.27 |
JbDesk 1.2편-표기법 변환 (2) | 2025.03.27 |
JbDesk 1.1편-짜잘한 유틸리티 모음(빈줄 제거) (0) | 2025.03.26 |