画像のビューアを作る 3

190619

結構順調 ( ´∀`)

import sys , glob ,os,re
from zipfile import ZipFile
from PyQt5.QtWidgets import QApplication, QWidget, QLabel,QVBoxLayout
from PyQt5.QtGui import QPixmap 
from PyQt5.QtSvg import QSvgRenderer,QSvgWidget
from PyQt5.QtCore import Qt,QPoint

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.setAcceptDrops(True)
        self.title = 'PyQt Viewer'
        self.pics=[]
        self.current={'index':0, 'picslen':0}
        self.ges = {'flag':False , 'pos':QPoint() , 'cmd':'' ,'sensibility':20}
        self.command = [
                    ['→←→' , 'cm_bye' ] ,
                    ['↓→↓' , 'cm_del' ] ,
                    ['↑→↑' , 'cm_bye' ] ,
                    ['↓→↑' , 'cm_bye' ] ,
            ]

        self.setWindowTitle(self.title)
        self.__lyt = QVBoxLayout()
        self.__lyt.setContentsMargins(0, 0, 0, 0)
        self.__lyt.setSpacing(0)
        self.setLayout(self.__lyt)

        self.label = QLabel(self)
        self.__lyt.addWidget(self.label)

        pixmap = QPixmap(<pass>)
        self.label.setPixmap(pixmap)
        self.resize(pixmap.width(),pixmap.height())
        self.show()

    def dragEnterEvent(self, e):               # これ必要 ここでacceptしてやる
        e.accept()

    def dropEvent(self, e):                    # ここで受け取る
        self.showimage(e.mimeData().text()[8:])
        self.getpictures(e.mimeData().text()[8:])

    def showimage(self,e):
        pixmap = QPixmap(e)
        self.label.setPixmap(pixmap)
        self.resize(pixmap.width(),pixmap.height())
        self.show()

    def showzip(self,fname):
        zi = ZipFile( fname , 'r' )
        l_name = zi.namelist()
        with zi.open( l_name[0] ) as z_image :
            pix = QPixmap()
            pix.loadFromData(z_image.read())
            self.label.setPixmap(pix)
            self.resize(pix.width(),pix.height())
            self.show()
        zi.close()

    def mousePressEvent(self,e):
        if e.button() == Qt.MidButton :
            quit() # <----------- 終了処理書いた方が良いのかな
        elif 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() > self.ges['sensibility'] : # left
                self.ges['cmd'] += '←'
                self.ges['pos'] =e.pos()
            elif self.ges['pos'].x() - e.x() < -1*self.ges['sensibility'] : # right
                self.ges['cmd'] += '→'
                self.ges['pos'] =e.pos()
            elif self.ges['pos'].y() - e.y() < -1*self.ges['sensibility'] : # up
                self.ges['cmd'] += '↑'
                self.ges['pos'] =e.pos()
            elif self.ges['pos'].y() - e.y() > self.ges['sensibility'] : # 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 self.command :
            if l[0] == cmd :
                ccmd=l[1]
                print(ccmd)
        if ccmd == 'cm_bye':
            quit()
        elif ccmd== '' :
            self.setWindowTitle( r'-- GESTURE  MISSING --')
            # self.setWindowTitle( r'-- GESTURE -- ┐('д')┌ -- MISSING --')
        elif ccmd== 'cm_del' :
            pass

    def getpictures(self,e):
        ext=['jpg','jpeg','png','gif']
        os.chdir(os.path.split(e)[0]) 
        for f in ext :
            self.pics += glob.glob( '*.'+ f )
        self.pics.sort()
        print( self.pics )
        self.current['picslen']=len(self.pics)
        try:
            self.current['index']=self.pics.index(os.path.split(e)[1])
        except:
            self.current['index']=0
    
    def wheelEvent (self, e):#  mousewheel 引いたら-yが128
        if e.angleDelta().y() < 0 : # increase
            self.current['index'] +=1
            if self.current['index'] > self.current['picslen'] -1 :
                self.current['index']=0
        else:
            self.current['index'] -=1
            if self.current['index'] < 0 :
                self.current['index']=self.current['picslen']-1

        fname=self.pics[self.current['index']]
        if ('-zip-' in fname ):
            self.showzip(fname)
        else:
            self.showimage(self.pics[self.current['index'] ])

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    # ex.show()
    sys.exit(app.exec_())
  • リストからドロップファイルを検索出来るようになった
    globはカレントフォルダを設定して走らせることにした、フルパスではなく
  • zip内の画像表示はできた( ´∀`)
  • マウス中クリックで終了
  • マウスジェスチャもいけた、簡単だった
  • 職場で構想を練ってメモを残して家に帰ってから試してるが、かなり効率よく進みます
    まあサボってるわけだけど(・∀・)ノ

マウスジェスチャの考え方

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

zip_jpg対応

参考サイト
https://python.civic-apps.com/zipfile/
公式ドキュメント
https://docs.python.org/ja/3.7/library/zipfile.html?highlight=zipfile#module-zipfile

①まずファイル名から[zip]の文字列を探してヒットしたらzip解析に回す
これはshowルーチンかな
②zipとして開いてファイルリストを取得して最初のファイルをバッファにロードしてQpixmapに渡して表示
リストは self.zip=[] だな

戻る

END

Close