画像のビューアを作る 2 version 15

2019/06/19 16:43 by yamasyuh68
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
画像のビューアを作る 2todo
190618

# とりあえず作ってみた

- designer を使わないとさっとは書けない
サンプルがあったのでそれを使い回した感じ

< code >

- 何とか表示できたが、まだウインドウのサイズ調整がうまくいかない
大きくなった後小さいファイルを表示しても戻らないことがある

- ドラッグで開くのが基本
表示処理の後すぐフォルダをglobでスキャンして画像ファイルをリスト化して、マウスのホイールで表示ファイルを切り替えるようにした。これが基本の動作
リストは拡張子毎にglobを回してリストに加えていって、最後にソートした
- ちなみにドロップされたファイルをリストから検索してそのインデクスをカレントにしておく必要があるが、検索結果はエラー。対策必要

- ホイール
マウスホイールは wheelイベントとして QWidget に実装されてます
このイベントをクラス内で def すると、QWheelEvent Class が引数で来る
ここから angleDelta().y() を取り出して、マイナスなら普通の手前のホイール、プラスなら逆のホイールと判断する
ホイールに応じて画像リストのインデクスをインクリ・デクリメントしてやれば良い

- ちなみにこれはQt5の仕様で、Qt4は少し違うので注意
angleDelta() はposを返すので当然 x()も取得できるが、常に0だった
Qt4だと単にDelta()となっていて、これはintしか返さないから拡張したんだと思う
いずれ x() も何らかの値を返すようになるんだと思う

- とりあえず表示は出来たけど次は何の機能をつけよう
zip内のファイルが読めなければ意味ないからそこかな
zipモジュールを使うか自分でヘッダ解析をするかどうしよう?

- 現状だとzip化したjpgは読めなかった
しかしエラーになるわけでは無いので、pixmap(file) は失敗してもエラーは返さなってことだね

----

- 中ボタンクリックで終了
QWidget.mousePressEvent (self, QMouseEvent)
QMouseEvent Class Reference [QtGui]
 Qt.MouseButton QMouseEvent.button (self)

Qt.MouseButton------------------------
Qt.NoButton 0x00000000 The button state does not refer to any button (see QMouseEvent.button()). 
Qt.LeftButton 0x00000001 The left button is pressed, or an event refers to the left button. (The left button may be 

the right button on left-handed mice.) 
Qt.RightButton 0x00000002 The right button. 
Qt.MidButton 0x00000004 The middle button. 
Qt.MiddleButton MidButton The middle button. 
Qt.XButton1 0x00000008 The first X button. 
Qt.XButton2 0x00000010 The second X button. 

```
def mousePressEvent(self,e)
 if e.button() == Qt.MidButton :
   quit() # <----------- 終了処理書いた方が良いのかな
 elif e.button() == Qt.RightButton  :
  self.mg=True # mouse gesture
  self.mgpos=getcurpos() # ??

```

 
- マウスジェスチャー必要だな


- リストからドロップファイルのインデクスが取得出来ない
リストを見たら、globで取得したパスの形式がおかしい
winとlinuxが混じったような・・( ´∀`)
c:/**/**/**\\hoge.jpg
って感じ
globに検索フォルダを投げるときにos.path.join()を使ったんだが、[\\]はこれがつけたんだと思う
ドロップファイルとリスト化されたファイルパスが、文字列としては違うのが原因だと思う

- パスは無視してファイル名だけで比較するか、globに投げる文字列を変えるか
glodの結果をファイル名だけに出来ないのかな?
リストはその方が軽くて良さそうだけど


- pathlib も使えるらしい

from pathlib import Path

# Pathオブジェクトを生成
p = Path("/test_dir/dir_A/")

# ファイル名の条件指定 リストで返る

pics = list(p.glob("*.txt"))



- 何か面倒っぽいのでやっぱりglobで

```
# cp=os.getcwd()
os.chdir(<path>) # まずこれをしてから
glob.glob(< パス無しのファイル名だけ >)
# os.chdir( cp )   戻す必要あるかな??
```
カレントフォルダを設定しておけば今後全てのファイル操作はパス無しのファイル名だけでイケるからこの方が簡単で良いのかも (・∀・)ノ
そのかわりカレントフォルダを self.current['folda'] で管理する
(必要ないかな??)

_
_


# Mouse Gesture

①mousePressed
右クリック時のポジション取得(A)、フラグ立てる
②mousemoove
フラグなし
 pass
フラグ有り
 ポジション取得(B)
 (A)との差で左右上下を取得  udrl up down right left
  x,y それぞれ10以上の増減があった時点でカウント
 取得した時点のポジションを(A)に再設定して判定を継続
③mouseReleased
フラグ無し
 pass
フラグ有り
 フラグ解除
 取得文字列をコマンド解析
  rrrrllrrrr --> rlr というコマンドになる
 コマンド実行


```
def __init__
 self.ges = {'flag':False , 'pos':QPoint() , 'cmd':'' }
command = [
 ['→←→' , 'cm_bye' ] ,
 ['↓→↓' , 'cm_del' ] ,
 ['↑→↑' , 'cm_bye' ] ,
 ['↓→↑' , 'cm_bye' ] ,
]

def mousePressEvent (self, e):
 if e.button() == Qt.RightButton  :
  self.ges['flag']=True
  self.ges['pos'] =e.pos()

def mouseMoveEvent (self, e):
 if self.ges['flag'] :
  if self.ges['pos'].x() - e.x() > 10 : # left
    self.ges['cmd'] += '←'
    self.ges['pos'] =e.pos()
  elif self.ges['pos'].x() - e.x() < 10 : # right
    self.ges['cmd'] += '→'
    self.ges['pos'] =e.pos()
  elif self.ges['pos'].y() - e.y() < 10 : # up
    self.ges['cmd'] += '↑'
    self.ges['pos'] =e.pos()
  elif self.ges['pos'].y() - e.y() > 10 : # down
    self.ges['cmd'] += '↓'
    self.ges['pos'] =e.pos()
  self.setWindowTitle( '-- mouse GESTURE -- {} --'.format(self.ges['cmd'] ))

def mouseReleaseEvent (self, e):
 if self.ges['flag']  and ( e.button() == Qt.RightButton ) :
  self.ges['flag'] =False
  self.goGesture()

def goGesture(self):
cmd=re.sub(r'(.)\1{1,}',r'\1', self.ges['cmd'] )
self.ges['cmd'] = ''
ccmd=''

for l in command :
 if l[0] == cmd :
  ccmd=l[1]
print(ccmd)

if ccmd == 'cm_bye':
  pass
elif ccmd== '' :
  self.setWindowTitle( '-- GESTURE -- ┐('д')┌ -- MISSING --')
elif ccmd== 'cm_del' :
  pass


```
- hogetta

```
import re
cmd='rrrlludddl'
cmd_new=re.sub(r'(.)\1{1,}' , r'\1' , cmd )
print(cmd)
print(cmd_new)
```
----
→ []()






      

190618

とりあえず作ってみた

  • designer を使わないとさっとは書けない
    サンプルがあったのでそれを使い回した感じ

< code >

  • 何とか表示できたが、まだウインドウのサイズ調整がうまくいかない
    大きくなった後小さいファイルを表示しても戻らないことがある

  • ドラッグで開くのが基本
    表示処理の後すぐフォルダをglobでスキャンして画像ファイルをリスト化して、マウスのホイールで表示ファイルを切り替えるようにした。これが基本の動作
    リストは拡張子毎にglobを回してリストに加えていって、最後にソートした

  • ちなみにドロップされたファイルをリストから検索してそのインデクスをカレントにしておく必要があるが、検索結果はエラー。対策必要

  • ホイール
    マウスホイールは wheelイベントとして QWidget に実装されてます
    このイベントをクラス内で def すると、QWheelEvent Class が引数で来る
    ここから angleDelta().y() を取り出して、マイナスなら普通の手前のホイール、プラスなら逆のホイールと判断する
    ホイールに応じて画像リストのインデクスをインクリ・デクリメントしてやれば良い

  • ちなみにこれはQt5の仕様で、Qt4は少し違うので注意
    angleDelta() はposを返すので当然 x()も取得できるが、常に0だった
    Qt4だと単にDelta()となっていて、これはintしか返さないから拡張したんだと思う
    いずれ x() も何らかの値を返すようになるんだと思う

  • とりあえず表示は出来たけど次は何の機能をつけよう
    zip内のファイルが読めなければ意味ないからそこかな
    zipモジュールを使うか自分でヘッダ解析をするかどうしよう?

  • 現状だとzip化したjpgは読めなかった
    しかしエラーになるわけでは無いので、pixmap(file) は失敗してもエラーは返さなってことだね


  • 中ボタンクリックで終了
    QWidget.mousePressEvent (self, QMouseEvent)
    QMouseEvent Class Reference [QtGui]
    Qt.MouseButton QMouseEvent.button (self)

Qt.MouseButton------------------------
Qt.NoButton 0x00000000 The button state does not refer to any button (see QMouseEvent.button()).
Qt.LeftButton 0x00000001 The left button is pressed, or an event refers to the left button. (The left button may be

the right button on left-handed mice.)
Qt.RightButton 0x00000002 The right button.
Qt.MidButton 0x00000004 The middle button.
Qt.MiddleButton MidButton The middle button.
Qt.XButton1 0x00000008 The first X button.
Qt.XButton2 0x00000010 The second X button.

def mousePressEvent(self,e)
 if e.button() == Qt.MidButton :
   quit() # <----------- 終了処理書いた方が良いのかな
 elif e.button() == Qt.RightButton  :
  self.mg=True # mouse gesture
  self.mgpos=getcurpos() # ??

  • マウスジェスチャー必要だな

  • リストからドロップファイルのインデクスが取得出来ない
    リストを見たら、globで取得したパスの形式がおかしい
    winとlinuxが混じったような・・( ´∀`)
    c:///**\hoge.jpg
    って感じ
    globに検索フォルダを投げるときにos.path.join()を使ったんだが、[\]はこれがつけたんだと思う
    ドロップファイルとリスト化されたファイルパスが、文字列としては違うのが原因だと思う

  • パスは無視してファイル名だけで比較するか、globに投げる文字列を変えるか
    glodの結果をファイル名だけに出来ないのかな?
    リストはその方が軽くて良さそうだけど

  • pathlib も使えるらしい

from pathlib import Path

Pathオブジェクトを生成

p = Path("/test_dir/dir_A/")

ファイル名の条件指定 リストで返る

pics = list(p.glob("*.txt"))

  • 何か面倒っぽいのでやっぱりglobで
# cp=os.getcwd()
os.chdir(<path>) # まずこれをしてから
glob.glob(< パス無しのファイル名だけ >)
# os.chdir( cp )   戻す必要あるかな??

カレントフォルダを設定しておけば今後全てのファイル操作はパス無しのファイル名だけでイケるからこの方が簡単で良いのかも (・∀・)ノ
そのかわりカレントフォルダを self.current['folda'] で管理する
(必要ないかな??)

_
_

Mouse Gesture

①mousePressed
右クリック時のポジション取得(A)、フラグ立てる
②mousemoove
フラグなし
 pass
フラグ有り
 ポジション取得(B)
 (A)との差で左右上下を取得 udrl up down right left
  x,y それぞれ10以上の増減があった時点でカウント
 取得した時点のポジションを(A)に再設定して判定を継続
③mouseReleased
フラグ無し
 pass
フラグ有り
 フラグ解除
 取得文字列をコマンド解析
  rrrrllrrrr --> rlr というコマンドになる
 コマンド実行

def __init__
 self.ges = {'flag':False , 'pos':QPoint() , 'cmd':'' }
command = [
 ['→←→' , 'cm_bye' ] ,
 ['↓→↓' , 'cm_del' ] ,
 ['↑→↑' , 'cm_bye' ] ,
 ['↓→↑' , 'cm_bye' ] ,
]

def mousePressEvent (self, e):
 if e.button() == Qt.RightButton  :
  self.ges['flag']=True
  self.ges['pos'] =e.pos()

def mouseMoveEvent (self, e):
 if self.ges['flag'] :
  if self.ges['pos'].x() - e.x() > 10 : # left
    self.ges['cmd'] += '←'
    self.ges['pos'] =e.pos()
  elif self.ges['pos'].x() - e.x() < 10 : # right
    self.ges['cmd'] += '→'
    self.ges['pos'] =e.pos()
  elif self.ges['pos'].y() - e.y() < 10 : # up
    self.ges['cmd'] += '↑'
    self.ges['pos'] =e.pos()
  elif self.ges['pos'].y() - e.y() > 10 : # down
    self.ges['cmd'] += '↓'
    self.ges['pos'] =e.pos()
  self.setWindowTitle( '-- mouse GESTURE -- {} --'.format(self.ges['cmd'] ))

def mouseReleaseEvent (self, e):
 if self.ges['flag']  and ( e.button() == Qt.RightButton ) :
  self.ges['flag'] =False
  self.goGesture()

def goGesture(self):
cmd=re.sub(r'(.)\1{1,}',r'\1', self.ges['cmd'] )
self.ges['cmd'] = ''
ccmd=''

for l in command :
 if l[0] == cmd :
  ccmd=l[1]
print(ccmd)

if ccmd == 'cm_bye':
  pass
elif ccmd== '' :
  self.setWindowTitle( '-- GESTURE -- ┐('д')┌ -- MISSING --')
elif ccmd== 'cm_del' :
  pass


  • hogetta
import re
cmd='rrrlludddl'
cmd_new=re.sub(r'(.)\1{1,}' , r'\1' , cmd )
print(cmd)
print(cmd_new)

→