fork(2) download
  1. #!/usr/bin/env python
  2. #coding:utf-8
  3. import gtk
  4. import subprocess
  5. import sys
  6. import os
  7. import Image
  8.  
  9. class PyApp(gtk.Window):
  10. def __init__(self):
  11. super(PyApp,self).__init__()
  12.  
  13. #コマンドライン引数からファイル名とディレクトリパスを取得
  14. self.args = sys.argv
  15. if(len(self.args)>1):
  16. path = self.args[1]
  17. num = path.rfind("/")
  18. self.filename = path[num+1:]
  19. self.filepath = path[:num+1]
  20.  
  21. #画面状態のフラグ
  22. self.screenFlag = True
  23. #画像の回転方向のフラグ
  24. self.mouseRotateFlag = False
  25. self.fixFlag = True
  26. #シフトを押しているかどうかのフラグ
  27. self.shift_Flag = False
  28. self.rotate = 0
  29. #画像の水平反転のフラグ
  30. self.flip_LR = False
  31. #画像の上下反転フラグ
  32. self.flip_TB = False
  33.  
  34. #---------------WINDOW---------------------
  35. #バックカラー
  36. self.color = gtk.gdk.color_parse('#000000')
  37. self.modify_bg(gtk.STATE_NORMAL, self.color)
  38.  
  39. self.set_title(self.filename)
  40. self.connect("destroy",gtk.main_quit)
  41. self.connect("realize",self.hide_mouse)
  42. #ウインドウイベント
  43. self.connect("window_state_event",self.window_change)
  44.  
  45. #イベント処理
  46. self.add_events(gtk.gdk.KEY_PRESS_MASK|gtk.gdk.BUTTON_PRESS_MASK|gtk.gdk.SCROLL_MASK|gtk.gdk.WINDOW_STATE_ICONIFIED)
  47. self.connect("key-press-event",self.key_event)
  48. self.connect("key-release-event",self.key_release_event)
  49. self.connect("button-press-event", self.mouse_button_event)
  50. self.connect("scroll-event",self.mouse_scroll_event)
  51.  
  52. self.set_size_request(250,150)
  53. self.set_position(gtk.WIN_POS_CENTER)
  54.  
  55. #filelist:ディレクトリ内の画像ファイルの一覧
  56. self.filelist = self.get_dirimage(self.filepath)
  57. self.filelist.sort()
  58. #self.number:現在の画像ファイルの番号
  59. self.number = self.filelist.index(self.filename)
  60. for i in self.filelist:
  61. print i
  62.  
  63. self.fix = gtk.Fixed()
  64. tmp = self.load_image( self.filepath + self.filename )
  65. self.set_image(tmp)
  66. self.show_all()
  67.  
  68. self.fullscreen()
  69.  
  70. #マウス非表示
  71. def hide_mouse(self,widget):
  72. pixmap = gtk.gdk.Pixmap(None, 1, 1, 1)
  73. color = gtk.gdk.Color()
  74. cursor = gtk.gdk.Cursor(pixmap, pixmap, color, color, 0, 0)
  75. widget.window.set_cursor(cursor)
  76.  
  77. def window_change(self,widget,event):
  78. pass
  79. #print event.new_window_state
  80.  
  81. #ショートカットキー入力で呼ばれる関数
  82. def key_event(self,widget,event):
  83. keyname = gtk.gdk.keyval_name(event.keyval)
  84. #print event.type
  85. #print keyname
  86. if(keyname=="F11" or keyname=="f"):
  87. #画面表示の切り替え
  88. if(self.screenFlag == True):
  89. self.screenFlag = not(self.screenFlag)
  90. self.unfullscreen()
  91. self.maximize()
  92. elif(self.screenFlag == False):
  93. self.screenFlag = not(self.screenFlag)
  94. self.fullscreen()
  95. if(keyname=="Home"):
  96. self.update("home")
  97. if(keyname=="End"):
  98. pass
  99. if(keyname=="Delete"):
  100. #もしShiftキーを押していれば
  101. if( self.shift_Flag == True ):
  102. #ファイルを削除する
  103. hoge = self.filepath + self.filelist[self.number]
  104. os.remove(hoge)
  105. print "削除:",hoge
  106. #ディレクトリリスト更新
  107. self.filelist = self.get_dirimage(self.filepath)
  108. self.filelist.sort()
  109. #画像を消したので画像のリストの番号を一つ後ろにする
  110. if(self.number == 0):
  111. self.number = len(self.filelist) - 1
  112. else:
  113. self.number -= 1
  114. #そして次の画像表示
  115. self.update("down")
  116. if(keyname=="h"):
  117. #画像を水平に反転する
  118. self.flip_LR = not(self.flip_LR)
  119. self.image_ch()
  120. if(keyname=="H"):
  121. #左右反転して保存
  122. try:
  123. im = Image.open( self.filepath + self.filelist[self.number] )
  124. im = im.transpose(Image.FLIP_LEFT_RIGHT)
  125. im.save( self.filepath + self.filelist[self.number], quality = 100 )
  126. print "画像反転完了",self.filepath + self.filelist[self.number]
  127. self.image_ch()
  128. except:
  129. print "画像反転失敗"
  130. if(keyname=="u"):
  131. #画像を垂直に反転する
  132. self.flip_TB = not(self.flip_TB)
  133. self.image_ch()
  134. if(keyname=="U"):
  135. #上下反転して保存
  136. try:
  137. im = Image.open( self.filepath + self.filelist[self.number] )
  138. im = im.transpose(Image.FLIP_TOP_BOTTOM)
  139. im.save( self.filepath + self.filelist[self.number], quality = 100 )
  140. print "画像反転完了",self.filepath + self.filelist[self.number]
  141. self.image_ch()
  142. except:
  143. print "画像反転失敗"
  144. if(keyname=="Up"):
  145. self.update("up")
  146. if(keyname=="Down"):
  147. self.update("down")
  148. if(keyname=="space"):
  149. self.update("up")
  150. if(keyname=="Left" or keyname=="l"):
  151. self.mouseRotateFlag = False
  152. self.rotate_update(2)
  153. if(keyname=="Right" or keyname=="r"):
  154. self.mouseRotateFlag = True
  155. self.rotate_update(1)
  156. if(keyname=="Escape"):
  157. self.flip_LR = False
  158. self.flip_TB = False
  159. self.rotate_update(0)
  160. if(keyname=="Shift_L" or keyname=="Shift_R"):
  161. self.shift_Flag = True
  162. print "Shift",self.shift_Flag
  163.  
  164.  
  165. #キーボードを離した時の処理
  166. def key_release_event(self,widget,event):
  167. keyname = gtk.gdk.keyval_name(event.keyval)
  168. #print keyname
  169. if(keyname == "Shift_L" or keyname == "Shift_R"):
  170. self.shift_Flag = False
  171. print "Shift",self.shift_Flag
  172.  
  173. #マウス入力
  174. def mouse_scroll_event(self,widget,event):
  175. if(event.direction == gtk.gdk.SCROLL_UP):
  176. self.update("up")
  177. if(event.direction == gtk.gdk.SCROLL_DOWN):
  178. self.update("down")
  179.  
  180. #マウスボタン入力
  181. def mouse_button_event(self,widget,event):
  182. #print event.button
  183. #左クリックかつダブルクリックじゃない場合
  184. if(event.button == 1 and event.type == gtk.gdk.BUTTON_PRESS):
  185. self.update("down")
  186. #右クリックかつダブルクリックで終了
  187. if(event.button == 3 and event.type == gtk.gdk._2BUTTON_PRESS):
  188. sys.exit(0)
  189. #上サイドクリック(回転)
  190. if(event.button == 9 and event.type == gtk.gdk.BUTTON_PRESS):
  191. if(self.mouseRotateFlag == False):
  192. self.mouseRotateFlag = not(self.mouseRotateFlag)
  193. self.rotate_update(1)
  194. elif(self.mouseRotateFlag == True):
  195. self.mouseRotateFlag = not(self.mouseRotateFlag)
  196. self.rotate_update(2)
  197. #下サイドクリック
  198. if(event.button == 8):
  199. if(self.fixFlag == True and event.type == gtk.gdk.BUTTON_PRESS):
  200. self.fix.hide()
  201. self.fixFlag = not(self.fixFlag)
  202. elif(self.fixFlag == False and event.type == gtk.gdk.BUTTON_PRESS):
  203. self.fix.show()
  204. self.fixFlag = not(self.fixFlag)
  205.  
  206. #ロードした画像オブジェクトtmpを加工して画面に表示する
  207. def set_image(self,tmp):
  208. #画像変数
  209. width = tmp.get_width()
  210. height = tmp.get_height()
  211. screenx = gtk.gdk.screen_width()
  212. screeny = gtk.gdk.screen_height()
  213.  
  214. image = gtk.Image()
  215. new_width = int(height*float(screeny)/width)
  216. if(self.rotate>0 and height>=width):
  217. if(new_width<=screenx):
  218. tmp = self.set_rotation(self.rotate,tmp)
  219. tmp = tmp.scale_simple(new_width,screeny,gtk.gdk.INTERP_HYPER)
  220. image.set_from_pixbuf(tmp)
  221. self.fix.put(image,(screenx-new_width)/2,0)
  222. elif(new_width>screenx):
  223. new_height = int(width*float(screenx)/height)
  224. tmp = self.set_rotation(self.rotate,tmp)
  225. tmp = tmp.scale_simple(screenx,new_height,gtk.gdk.INTERP_HYPER)
  226. image.set_from_pixbuf(tmp)
  227. self.fix.put(image,0,(screeny-new_height)/2)
  228. elif(self.rotate==0 or height<width):
  229. new_width = int(width*float(screeny)/height)
  230. if(new_width<=screenx):
  231. tmp = self.set_flip(self.flip_LR , self.flip_TB , tmp)
  232. tmp = tmp.scale_simple(new_width,screeny,gtk.gdk.INTERP_HYPER)
  233. image.set_from_pixbuf(tmp)
  234. self.fix.put(image,(screenx-new_width)/2,0)
  235. else:
  236. tmp = self.set_flip(self.flip_LR,self.flip_TB,tmp)
  237. new_height = int(height*float(screenx)/width)
  238. tmp = tmp.scale_simple(screenx,new_height,gtk.gdk.INTERP_HYPER)
  239. image.set_from_pixbuf(tmp)
  240. self.fix.put(image,0,(screeny-new_height)/2)
  241. self.add(self.fix)
  242.  
  243. #アイコン設定
  244. def set_icon(self,path):
  245. try:
  246. self.set_icon_from_file(path)
  247. except Exception,e:
  248. print e.message
  249. sys.exit(1)
  250.  
  251. #画像を回転させる
  252. def set_rotation(self,rotate,tmp):
  253. if(rotate==0):
  254. pass
  255. if(rotate==1):
  256. tmp = tmp.rotate_simple(270)
  257. if(rotate==2):
  258. tmp = tmp.rotate_simple(90)
  259. return tmp
  260.  
  261. #画像を左右上下反転させる
  262. def set_flip(self , flip_LR , flip_TB , tmp):
  263. if(flip_LR==True):
  264. tmp = tmp.flip(True)
  265. if(flip_TB==True):
  266. tmp = tmp.flip(False)
  267. return tmp
  268.  
  269. #画像ファイルをロードする
  270. def load_image(self,path):
  271. try:
  272. tmp = gtk.gdk.pixbuf_new_from_file(path)
  273. except Exception,e:
  274. #もしロードできなければ,ディレクトリ内の画像リストをもう一度更新する
  275. self.filelist = self.get_dirimage(self.filepath)
  276. self.filelist.sort()
  277. #画像を消したので画像のリストの番号を一つ後ろにする
  278. if(self.number>=(len(self.filelist)-1)):
  279. self.number = 0
  280. else:
  281. self.number += 1
  282.  
  283. #もう一度再帰呼出し
  284. #self.load_image(path)
  285.  
  286. return tmp
  287.  
  288. #ディレクトリ内の画像をリストに取得
  289. def get_dirimage(self,path):
  290. files = os.listdir(path)
  291. list = []
  292. for i in files:
  293. if((".jpg"in i) == True or (".jpeg"in i) == True or (".png"in i) == True or (".JPG"in i) == True or (".bmp"in i) == True or (".gif"in i) == True):
  294. list.append(i)
  295.  
  296. return list
  297.  
  298. #回転命令時に呼ばれる関数
  299. def rotate_update(self,a):
  300. self.rotate = a
  301. self.image_ch()
  302.  
  303. #表示画面を次の画像に変える関数
  304. def update(self,a):
  305. if(a=="up"):
  306. if(self.number == 0):
  307. self.number = len(self.filelist)-1
  308. else:
  309. self.number -= 1
  310. self.image_ch()
  311.  
  312. elif(a=="down"):
  313. if(self.number>=(len(self.filelist)-1)):
  314. self.number = 0
  315. else:
  316. self.number += 1
  317. self.image_ch()
  318.  
  319. elif(a=="home"):
  320. self.number = 0
  321. self.image_ch()
  322. else:
  323. print "self.update():エラー"
  324.  
  325. self.set_title(self.filelist[self.number])
  326.  
  327. #self.update()などから呼ばれる画像表示を変更する関数
  328. def image_ch(self):
  329. self.remove(self.fix)
  330. self.fix = None
  331. self.fix = gtk.Fixed()
  332. try:
  333. tmp = self.load_image( self.filepath + self.filelist[self.number] )
  334. self.set_image(tmp)
  335. except:
  336. pass
  337. self.show_all()
  338.  
  339.  
  340. #多重起動防止関数
  341. def prevent_multi_process():
  342. cmd = "ps ax | grep 'python /home/martin/python/gazowa_flip.py'"
  343. ret = subprocess.check_output( cmd , shell=True)
  344. #print ret
  345. script_name = 'python /home/martin/python/gazowa_flip.py'
  346. number = ret.count(script_name)
  347. #上のpsコマンドとgrepの数を減らす
  348. number -= 2
  349. print "がぞわーの起動数:",number,"個"
  350. if( number >= 3 ):
  351. print "多重起動禁止(3つ以上の起動は禁止しています)"
  352. sys.exit()
  353.  
  354.  
  355. prevent_multi_process()
  356. PyApp()
  357. gtk.main()
  358.  
Runtime error #stdin #stdout #stderr 0.08s 32928KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
(process:21142): Gtk-WARNING **: Locale not supported by C library.
	Using the fallback 'C' locale.
/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:57: GtkWarning: could not open display
  warnings.warn(str(e), _gtk.Warning)
Error, do this: mount -t proc proc /proc
Traceback (most recent call last):
  File "prog.py", line 355, in <module>
  File "prog.py", line 343, in prevent_multi_process
  File "/usr/lib/python2.7/subprocess.py", line 573, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command 'ps ax | grep 'python /home/martin/python/gazowa_flip.py'' returned non-zero exit status 1