This repository was archived by the owner on Aug 17, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMultiPyAlarm.py
More file actions
204 lines (167 loc) · 6.63 KB
/
MultiPyAlarm.py
File metadata and controls
204 lines (167 loc) · 6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# -*- coding: utf-8 -*-
import datetime
import os
import sys
import win32api
import win32gui
import wx
import wx.adv
from listframe import ListFrame
from messageframe import MessageFrame
from namedmutex.namedmutex import NamedMutex
from timerlist import TimerList
from logger import Logger
class MyApp(wx.App):
# def __init__(self):
# wx.App.__init__(self,False)
def OnInit(self):
# アイコン取得
exeName = win32api.GetModuleFileName(win32api.GetModuleHandle(None))
self.icon = wx.Icon(exeName, wx.BITMAP_TYPE_ICO)
self.alarmicon = wx.Icon(self._resource_path('alarm.ico'), wx.BITMAP_TYPE_ICO)
# タスクトレイにアイコン表示
self.tb_ico = MyTaskBar(self, self.icon)
self.logger = Logger()
# アラームタイマーのリスト
self.timerlist = TimerList()
# 不可視のトップウィンドウ
frame = wx.Frame(None)
self.SetTopWindow(frame)
# メインウィンドウ描画
self.listframe = None
# タイマースタート
self.timer = wx.Timer(self)
self.timer.Start(1000)
self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
return True
def _resource_path(self, relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
def show_balloon(self, key, timer):
endtime = timer["endtime"].strftime("%H:%M:%S")
message = timer["message"]
balloonmessage = '{0} {1}'.format(endtime, message)
self.tb_ico.ShowBalloonTip('add alarm', balloonmessage)
self.timerlist.displayed(key)
def alarm(self, key, timer):
# listframe が表示されていたら、タイマー一覧から削除
if self.listframe:
self.listframe.del_item(timer["index"])
MessageFrame(None, "Alarm", timer["message"], self.alarmicon)
def onTimer(self, event):
"""一秒ごとに実行する処理
タイマーリストの中から指定時間が経過したもののアラーム表示
ListFrame があれば、その画面の更新
"""
# ファイルの更新があれば読み込み
self.timerlist.update()
# このあと timerlist ファイルが保存されるまでの間にファイルの更新があっ
# ても無視。
# ファイルのロックをした方がよいかも。現実的には大丈夫だろうけど。
# タイマーがなければ何もしない
if not self.timerlist:
return
# print self.timerlist
del_keys = []
for key, timer in self.timerlist.items():
# 時間になったタイマーをアラーム。
if timer["endtime"] < datetime.datetime.today():
self.alarm(key, timer)
self.logger.timer("Alarm", timer)
del_keys.append(key)
continue
# 新規追加されたタイマーがあり、listframe が表示されていない場合
# 、システムトレイにタイマー追加のバルーンを表示する。
if not timer["displayed"] and not self.listframe:
self.show_balloon(key, timer)
for key in del_keys:
self.timerlist.delete(key)
# listframe が表示されていたらタイマー一覧を更新する。
if self.listframe:
self.listframe.update_items()
class MyTaskBar(wx.adv.TaskBarIcon):
def __init__(self, parent, icon):
wx.adv.TaskBarIcon.__init__(self)
self.parent = parent
self.icon = icon
self.SetIcon(self.icon, 'MultiPyAlarm')
self.Bind(wx.adv.EVT_TASKBAR_LEFT_DCLICK, self.OnTbiLeftDoubleClicked)
def CreatePopupMenu(self):
traymenu = wx.Menu()
id = wx.NewIdRef()
item = wx.MenuItem(traymenu, id=id, text=u'&Quit')
self.Bind(wx.EVT_MENU, self.OnQuit, id=id)
traymenu.Append(item)
return traymenu
def OnTbiLeftDoubleClicked(self, evt):
if self.parent.listframe:
self.parent.listframe.Raise()
else:
self.parent.listframe = ListFrame(None, self.parent.timerlist,
self.icon)
self.parent.listframe.Show()
def OnQuit(self, evt):
self.RemoveIcon()
sys.exit(0)
def ShowBalloonTip(self, title, msg):
"""Show Balloon tooltip
@param title The title of the balloon
@param msg The tooltip message
"""
if os.name == 'nt':
try:
self.SetBalloonTip(self.parent.icon.GetHandle(), title, msg)
self.SetIcon(self.icon, 'MultiPyAlarm')
except Exception as e:
print(e)
def SetBalloonTip(self, hicon, title, msg):
"""Don't call this method, call ShowBalloonTip instead"""
lpdata = (self.GetIconHandle(),
99,
win32gui.NIF_MESSAGE | win32gui.NIF_ICON | win32gui.NIF_INFO,
0,
hicon,
'', msg, 0, title, win32gui.NIIF_INFO)
win32gui.Shell_NotifyIcon(win32gui.NIM_MODIFY, lpdata)
def GetIconHandle(self):
"""Find the icon window.
this is ugly but for now there is no way to find this window directly
from wx
"""
if not hasattr(self, "_chwnd"):
try:
for handle in wx.GetTopLevelWindows():
handle = handle.GetHandle()
if len(win32gui.GetWindowText(handle)) == 0 and \
win32gui.GetWindowRect(handle) == (0, 0, 400, 250):
self._chwnd = handle
break
if not hasattr(self, "_chwnd"):
raise Exception
except:
raise Exception("Icon window not found")
return self._chwnd
if __name__ == "__main__":
# コマンドラインからタイマー追加
argc = len(sys.argv)
if argc > 1:
if argc > 2:
message = " ".join(sys.argv[2:])
else:
message = ""
try:
timerlist = TimerList()
timerlist.add(sys.argv[1], message)
del timerlist
except Exception as e:
ex = wx.App()
wx.MessageBox(str(e), 'Error', wx.OK | wx.ICON_INFORMATION)
ex.Destroy()
# 二重起動防止
mut = NamedMutex(b'MultiPyAlarm', True, 0)
if not mut.acret:
sys.exit()
app = MyApp()
app.RedirectStdio("MultiPyAlarm.log")
app.MainLoop()