Python/2.7 for fun.

(편의) pyqt를 이용한 gui 만화책 정리 스크립트.

qkqhxla1 2015. 3. 1. 21:33

pyqt는 처음 사용한다. 앞에서 gui 멀티쓰레드 채팅 서버를 만들었을때는 tkinter로 만들었었는데...


tkinter는 모든걸 코드로 조절해야 하기 때문에 gui요소들을 원하는 위치로 배치하기가 어렵다. 

반면에 pyqt는 c#에서 gui를 프로그래밍 하는 것처럼 마우스로 원하는 위치에 배열할수 있어서 편하다.

다만 pyqt는 디자인해서 만들어진 .ui파일을 다시 .py로 변환해야 된다는게 좀 짜증나긴 한다.

이러한 불편함이 있지만 그래도 마우스로 원하는 위치에 gui요소들을 배치할수 있다는 장점이 더 커서,

gui사용시 pyqt를 사용하기로 했다.(사실 별로 하지도 않을 것 같지만..)


다운로드 : http://www.riverbankcomputing.com/software/pyqt/download

참고 : http://blog.naver.com/powerhw/220133596797


이전에 만들었던 만화책 정리 스크립트에 gui를 조금 덮어씌우기로 했다. qt designer로 이렇게 만들었다.




사용 예.

앞에서 만들어진 소스코드를 알아서 잘 붙여넣어서 실행하면 당연히 앞에서 만들었던 폼인


가 보인다. (뒤에 프롬프트 창도 실행되는데 처음부터 gui만 실행되게 하는건 어떻게 하는 지 모르겠다.)

그리고 정렬을 할 만화책을 드래그하면.



이렇게 경로와 내부에 어떤 폴더가 있는지, 그리고 내부 폴더가 어떻게 정렬될건지 자동으로 보여준다.

(순서가 틀리거나 하면 본인이 파일 이름을 바꿔줘야 함..)

재설정을 누르면 처음화면처럼 경로와 경로 내부의 폴더가 사라지고 다시 설정을 할 수 있다.


정렬시작 버튼을 누르면 정렬되면서 내부의 폴더에 진행상황이 나타(나게 하려고 했는데 렉걸리면서 그냥 끝날때 바뀜.)난다..


예외처리로는 잘못된 경로나, 폴더가 아닐 경우 아니라고 하는 메시지와, 해당 폴더 내부에 정리라는 이름의 폴더가 있을시 정렬이 안되게끔 에러메시지를 띄우는 정도이다.



정리가 잘 되면 정리라는 이름의 폴더에 만화책들이 정리되서 나온다. 앞의 cui로 만든 프로그래밍과 실행 결과가 같음. cui : http://qkqhxla1.tistory.com/292


모듈 : new_ui.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'new.ui'
#
# Created: Mon Mar 02 12:25:22 2015
#      by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_widget(object):
    def setupUi(self, widget):
        widget.setObjectName(_fromUtf8("widget"))
        widget.resize(339, 369)
        widget.setAcceptDrops(True)
        self.textEdit = QtGui.QTextEdit(widget)
        self.textEdit.setGeometry(QtCore.QRect(10, 70, 311, 31))
        self.textEdit.setAcceptDrops(True)
        self.textEdit.setObjectName(_fromUtf8("textEdit"))
        self.pushButton = QtGui.QPushButton(widget)
        self.pushButton.setGeometry(QtCore.QRect(50, 110, 91, 41))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.label = QtGui.QLabel(widget)
        self.label.setGeometry(QtCore.QRect(10, 20, 331, 41))
        self.label.setAcceptDrops(True)
        self.label.setObjectName(_fromUtf8("label"))
        self.pushButton_2 = QtGui.QPushButton(widget)
        self.pushButton_2.setGeometry(QtCore.QRect(200, 110, 91, 41))
        self.pushButton_2.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.label_2 = QtGui.QLabel(widget)
        self.label_2.setGeometry(QtCore.QRect(90, 160, 161, 16))
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.textEdit_2 = QtGui.QTextEdit(widget)
        self.textEdit_2.setGeometry(QtCore.QRect(40, 180, 261, 161))
        self.textEdit_2.setObjectName(_fromUtf8("textEdit_2"))

        self.retranslateUi(widget)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.textEdit.clear)
        QtCore.QObject.connect(self.pushButton_2, QtCore.SIGNAL(_fromUtf8("clicked()")), widget.slot1_click)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.textEdit_2.clear)
        QtCore.QMetaObject.connectSlotsByName(widget)

    def retranslateUi(self, widget):
        widget.setWindowTitle(_translate("widget", "Form", None))
        self.pushButton.setText(_translate("widget", "재설정", None))
        self.label.setText(_translate("widget", "                       만화책 정리 스크립트.\n"
"책 제목에서 처음으로 나오는 숫자로 순서를 판별합니다.\n"
"숫자가 없는 폴더는 숫자 이후에 사전순서대로 이어붙입니다.", None))
        self.pushButton_2.setText(_translate("widget", "정렬시작", None))
        self.label_2.setText(_translate("widget", "경로 내부의 폴더(정렬순서)", None))

main 소스.

# -*- encoding: cp949 -*-
import PyQt4
from PyQt4 import QtGui, QtCore
from new_ui import *
import sys,os,re,shutil
from operator import itemgetter
class TestListView(QtGui.QListWidget):
    def __init__(self, type, parent=None):
        super(TestListView, self).__init__(parent)
        self.setAcceptDrops(True) #드래그 엔 드롭 True
        self.setIconSize(QtCore.QSize(72, 72))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(QtCore.SIGNAL("dropped"), links)
        else:
            event.ignore()

class myform(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = Ui_widget()
        self.view = TestListView(self)
        self.connect(self.view, QtCore.SIGNAL("dropped"), self.pictureDropped)
        self.setCentralWidget(self.view)
        self.ui.setupUi(self)
        
    def slot1_click(self):
        cnt = 1
        if os.path.exists(self.folder[0]+'\\정리'): 
            self.ui.textEdit_2.setText(unicode('경로 내부에 \'정리\'라는 이름의 폴더가 없어야 합니다!!!','cp949'))
        else:
            os.makedirs(self.folder[0]+'\\정리') #해당 경로 내부에 '정리'라는 폴더가 없으면 새로만듬.
            self.ui.textEdit_2.setText(unicode('','cp949'))
            for inn in self.dirnames:
                if inn!='정리': #해당 내부 폴더가 '정리'폴더가 아니면
                    self.ui.textEdit_2.append(unicode(inn+' 폴더의 사진을 정리중...','cp949')) 
                    for a,i,all_filenames in os.walk(self.folder[0]+'\\'+inn):
                        for f in all_filenames: #내부에서 모든 파일을 가져와서
                            if f.find('.jpg')!= -1 or f.find('.png')!= -1: #그중 .jpg나 .png가 포함된 사진파일만 가져와서
                                shutil.copy(self.folder[0]+'\\'+inn+'\\'+f, self.folder[0]+'\\정리\\0000'+str(cnt)+'.jpg') #정리 폴더에 새로 복사.
                                cnt += 1
            self.ui.textEdit_2.append(unicode('\n모든 사진 정리 완료!','cp949')) 
        return
    def pictureDropped(self, l):
        self.folder = l
        self.dirnames = []
        for url in l:
            if os.path.exists(url):
                self.ui.textEdit.setText(unicode('경로: ','cp949')+url)
                d = {}
                for all_dirname, inner_dirnames, all_filenames in os.walk(url):
                    last = 999999
                    for i in inner_dirnames:#숫자만 보고 정렬. 그냥 무조건 숫자를 찾아서 첫번째 찾은 숫자대로 정렬.
                        try:
                            d[int(re.findall('\d+',i)[0])]=i
                        except:
                            d[last]=i
                            last += 1
                s_d = sorted(d.items(), key=itemgetter(0))
                if not s_d: self.ui.textEdit_2.setText(unicode('폴더 내부에 아무 폴더도 없거나 잘못된 경로입니다..','cp949'))
                else:
                    for i in range(len(s_d)):
                        self.dirnames.append(s_d[i][1])
                    if not self.dirnames: self.ui.textEdit_2.setText(unicode('폴더 내부에 아무 폴더도 없거나 잘못된 경로입니다..','cp949'))
                    else:
                        self.ui.textEdit_2.setText(unicode('','cp949'))
                        for inn in self.dirnames:
                            self.ui.textEdit_2.append(unicode(inn,'cp949'))
        
app = QtGui.QApplication(sys.argv)
myapp = myform()
myapp.show()
app.exec_()