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