파이썬 실습/검색프로그램 만들기

파이썬 GUI 파일검색 프로그램 만들기-파일크기 버전

파기차차 2022. 8. 17. 23:05
728x90
반응형
SMALL
728x90
ㅁ 개요
 
O 프로그램 소개
 

 - GUI 파일검색 프로그램은 파일크기 및 검색폴더를 지정후 검색 버튼을 누르면 해당 파일크기 보다 큰 파일들을 찾아주는 프로그램으로 검색한 폴더전체 크기도 함께 보여주고 최종적으로 결과를 저장하는 기능까지 구현한 프로그램입니다.

(본 블로그의 내용은 유튜브 동영상(파이썬 파일 검색 프로그램 만들기)에서 더욱 자세히 보실 수 있습니다.)

 

 

O 완성된 프로그램 실행 화면
 
 - 아래에서는  'D:/Download' 폴더내에서 파일크기가 100MB보다 큰파일을 검색 후 검색 결과를 보여줍니다.
 - 검색결과는 원하는 위치에 파일저장 버튼을 클릭하여 저장할 수 있습니다.

 

 


ㅁ 세부 내용
 
O 완성된 소스
 

>위의 완성된 UI프로그램은 실행파일과 동일한 폴더에 위치시킨 후 실행하시면 됩니다. 다만, 실행 시 소스 내의 디렉토리 경로는 실제 자신의 존재하는 경로로 변경해 주셔야 합니다.

 
 
# -*- coding: utf-8 -*-
import sys
import os
import time
from PyQt5.QtWidgets import *
from PyQt5 import uic, QtCore, QtGui, QtWidgets

form_class = uic.loadUiType("winsearch5.ui")[0]

class MyWindow(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.pushButton.clicked.connect(self.searchFile)
        self.toolButton.clicked.connect(self.selectFolder)
        self.toolButton_2.clicked.connect(self.selectSaveFile)
        self.pushButton_2.clicked.connect(self.saveFile)

    def searchFile(self):
        global folder_size_total

        folder_size_total = 0

        if self.lineEdit_2.text():
            folder = self.lineEdit_2.text()
        else:
            folder = 'F:/Download'

        if self.lineEdit.text():
            file_size_input = self.lineEdit.text()
            if int(file_size_input) < 1000:
                print("파일 검색 사이즈가 너무 작습니다.(1000 bytes 이상)")
                self.textEdit.setText("파일 검색 사이즈가 너무 작습니다.(1000 bytes 이상)")
                self.clickMethod()
            else:
                self.textEdit.clear()
                try:
                    for (path, dirs, files) in os.walk(folder):
                        for file in files:
                            try:
                                filename = os.path.join(path, file)
                                file_size = os.path.getsize(filename)
                                if file_size > int(file_size_input):
                                    print("파일명 : ", filename, "\t", "파일크기 : ", file_size, "\n")
                                    self.textEdit.append(str(filename) + "\t" + str(file_size) + " bytes")
                                folder_size_total += os.path.getsize(filename)
                            except FileNotFoundError:
                                pass
                        time.sleep(0.1)
                    time.sleep(0.1)
                    self.textEdit.append("\n폴더전체크기 : " + str(folder_size_total) + " bytes")

                    print(folder, "폴더전체크기 : ", folder_size_total, " Bytes")
                except KeyboardInterrupt:
                    sys.exit()

        else:
            self.textEdit.setText("파일 크기를 입력해 주세요.(1000 bytes 이상)")

    def selectFolder(self):
        directory = str(QtWidgets.QFileDialog.getExistingDirectory())
        self.lineEdit_2.setText('{}'.format(directory))

    def selectSaveFile(self):
        savefilename = QFileDialog.getSaveFileName(self, "Save File")
        print(type(savefilename))
        self.lineEdit_3.setText('{}'.format(savefilename[0]))

    def saveFile(self):
        savefilename = self.lineEdit_3.text()
        readfile = self.textEdit.toPlainText()
        if savefilename and readfile:
            print(type(savefilename))
            try:
                with open(savefilename, 'w+', encoding='utf8') as out:
                    out.write(readfile + "\n")
                out.close()
                self.clickMethod2()
                self.lineEdit_3.setText("")
            except:
                print("파일이 저장되지 않고, 에러가 발생하였습니다.")
        else:
            QMessageBox.about(self, "경고!!", "검색 결과가 없거나, 저정할 파일을 지정하지 않았습니다.")

    def clickMethod(self):
        QMessageBox.about(self, "주의!!", "파일 검색 사이즈가 너무 작습니다. (1000 bytes 이상)")

    def clickMethod2(self):
        QMessageBox.about(self, "파일저장!!", "파일이 저장되었습니다.")

app=QApplication(sys.argv)
window = MyWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")
 
O 핵심 내용
 

1. form_class = uic.loadUiType("winsearch5.ui")[0] : 유저가 만든 UI를 로드하여 form_class변수에 할당

2. app=QApplication(sys.argv) : app객체 생성

3. class MyWindow(QMainWindow, form_class): QMainWindow 모듈은 PyQt5.QtWidgets 패키지에서 가져옴

4. window = MyWindow() : 생성자의 self는 window를 전달받음, 여기서 self는 MyWindow 클래스 그 자신을 의미

5. widow.show() : 창을 한번만 띄움

6. app.exec_() : app객체를 실행, exec_()함수의 내장 루프로 계속 창이 뜨게 만듦

7. self.setupUi(self) : form_class를 UI로 사용하겠다라는 의미

8. self.pushButton.clicked.connect(self.searchFile) : pushButton클릭시 searchFile함수 호출(먼저 Qt Desiner로 PushButton을 UI작업 후 코딩해야 에러가 없음)

9. file_size_input = self.lineEdit.text() : Qt Desiner의 lineEdit에서 입력받은 값을 file_size_input 변수에 저장

10. self.textEdit.setText("파일 검색 사이즈가 너무 작습니다.(1000 bytes 이상)") : Qt Desiner의 textEdit에 경고문구 안내

11. QMessageBox.about(self, "주의!!", "파일 검색 사이즈가 너무 작습니다. (1000 bytes 이상)") : 경고창 형태로 메시지 박스를 띄움

12. for (path, dirs, files) in os.walk(folder): 검색할 폴더에서 경로명, 하위디렉토리명, 파일명을 리스트로 각 각 path, dirs, files에 저장

13. filename = os.path.join(path, file) : 경로 + 파일명으로 filename변수에 저장

14. file_size = os.path.getsize(filename) : 위(13번) 파일의 크기를 file_size변수에 저장

15. self.textEdit.append(str(filename) + "\t" + str(file_size) + " bytes") : Qt Desiner의 textEdit에 append로 filename과 file_size를 추가해줌

16. folder_size_total += os.path.getsize(filename) : 검색폴더의 전체 크기를 구하기 위하여 if문 밖에 getsize()함수를 이용하여 파일들의 크기를 누적으로 더해줌

17. time.sleep(0.1) : 프로그램이 먹통되지 않도록 일정 시간 쉬게 해줌

 


O 기본 내용

-app객체를 생성 후 MyWindow클래스를 window에 할당하고, 윈도우를 띄운 후(window.show()) 지속적으로 실행(app.exec_())하게 만듦(즉 GUI 창을 띄움)

 

 

1.파일 크기를 입력받는 폼 생성(lineEdit)

2.검색결과를 보여줄 텍스트에디트 생성(textEdit)

3.검색을 실행할 검색 버튼 생성(pushButton)

 

 

1.파일크기가 너무 작은 경우 검색 시 파일들이 너무 많기 때문에 시스템 성능에 영향을 줄 수 있으므로 파일 크기를 제한(1000 bytes)하는 로직을 구현하고,

2.파일크기를 너무 작게 입력하면 경고창을 띄움(textEdit와 clickMethod() 두가지 방법으로 구현)

 

 

이번 프로그램에서 가장 중요한 내용으로

- 'for (path, dirs, files) in os.walk(folder):' 이 표현은 매주 중요하며, 검색할 폴더에서 경로명, 하위디렉토리명, 파일명을 리스트로 각 각 path, dirs, files에 저장 후 검색 결과(파일경로, 파일명, 파일 크기 및 전체 폴더 사이즈)를 결과 창에 보여준다

 

 

 

-툴 버튼(...)을 눌러 경로를 지정 후 검색할 수 있도록 toolButton이 클릭되면 실행할 selectFolder함수를 정의한다.

 

-selectFolder()함수는 toolButton이 클릭되면 경로 선택을 위한 창을 띄고, 그 창에서 폴더 선택시 directory변수에 경로를 저장 후 두번째 라인에디터(lineEdit_2)에 선택한 폴더의 경로를 입력한다

 

 

-검색결과를 저장하기 위해 파일 저장을 위한 툴버튼(...)과 푸시버튼(파일저장)을 생성하고 기능을 실행할 함수를 정의 한다.

 

 

-결과저장을 위해 툴버튼을 클릭하고, 저장할 파일명을 지정한 후 파일저장 버튼을 클릭하면 '파일저장' 메시지 창과 함께 파일이 지정된 파일명으로 저장된다.

 

 

-결과창의 내용(self.textEdit.toPlainText())을 읽어서 readfile변수에 넣고, 사용자가 지정한 파일명(savefilename)을 쓰기 모드로 열어서 write하고 라인에디트(lineEdit_3.setText(""))를 초기화 한다.

 


ㅁ 정리
 
O 우리가 배운 내용
 
 - GUI환경에서 검색할 수 있도록 다양한 기능들을 살펴보았습니다.
 - 이를 응용하여 키워드 검색, 파일내용 검색 등을 구현하는데 도움을 받을 수 있습니다.
- 파일 등을 찾을때 'for (path, dirs, files) in os.walk(folder):' 와 같은 표현은 자주 사용되는 표현이므로 알아두시면 좋습니다.
 

 

위의 내용이 유익하셨다면, 좋아요와 구독 부탁드립니다.

 

 

감사합니다.

 

 

728x90
반응형
LIST