파이썬 실습/GUI,윈도우 FTP(파일전송)프로그램 만들기

파이썬 GUI/윈도우 FTP(파일전송) 프로그램 만들기 - 3.로그인-2)로컬디렉토리목록보기

파기차차 2022. 12. 3. 08:33
728x90
반응형
SMALL
반응형
ㅁ 개요

 

O 프로그램 소개
 

 

 - 이번 프로그램은 이전글(2022.11.29 - [분류 전체보기] - 파이썬 GUI/윈도우 FTP(파일전송) 프로그램 만들기 - 2.사전 준비 작업)에 이은 4번째 글로 준비된 FTP서버에 로그인 후 로컬PC에 파일과 폴더를 리스트하는 트리뷰에 대하여 설명합니다.

(본 블로그의 내용은 유튜브 동영상(파이썬 GUI Window FTP(파일전송) 프로그램 만들기-3.로그인-2)(GUI/Window FTP program by Python-3.login-2))에서 더욱 자세히 보실 수 있습니다.)

 

 

 

 

**본 프로그램은 아래 깃허브 사이트의 소스를 참고하여 작성하였으며, 세부내용은 아래 사이트를 참고하여 주시기 바랍니다.
[출처] 깃허브, f.tea.p | 작성자 armut
https://github.com/armut/f.tea.p

 

 

 

 

 

O 완성된 프로그램 실행 화면
 

 

 - 최종 완성된 프로그램의 결과화면은 아래와 같습니다.

(1) 아래와 같이 프로그램을 실행시키고 ftp서버에 접속하면 왼쪽 하단 트리뷰에 현재 접속한 디렉토리를 기준으로 그 하위의  폴더와 파일 목록을 보여줍니다.

(아래에서는 기본 디렉토리가 "D:\100-1 Study\710_Wikidocs\210_wikiDocsAutoBitcoin\620_유튜버&블로그\20221113_파이썬ftp클라이언트만들기\5.GUI_윈도우버전\2.로컬디렉토리목록" 입니다.)

 

 

 


 

O 시작전 준비 사항

 

 

 - 이번글을 실습하기 위해서는 이전글(2022.11.29 - [분류 전체보기] - 파이썬 GUI/윈도우 FTP(파일전송) 프로그램 만들기 - 2.사전 준비 작업)에서 설명한 ftp서버를 준비하셔야 합니다.

 


 

ㅁ 세부 내용
 
O 완성된 소스

 

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

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

class FTPClass():
    __instance = None

    @staticmethod
    def tea():
        if not FTPClass.__instance:
            raise Exception("FTPClass를 먼저 인스턴스화 해야 합니다.")
        return FTPClass.__instance

    @staticmethod
    def reset():
        FTPClass.__instance = None

    def __init__(self, banana):
        if FTPClass.__instance:
            raise Exception("인스턴스가 이미 존재합니다.")
        FTPClass.__instance = banana


class LoginWindow(QtWidgets.QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setFixedSize(820,900)
        self.setWindowIcon(QIcon("pagichacha.png"))
        self.setupUi(self)

        self.lineEdit_5.returnPressed.connect(self.ftpConnect)
        self.pushButton.clicked.connect(self.ftpConnect)


    def ftpConnect(self):
        global result

        HOST = self.lineEdit.text()
        ID = self.lineEdit_4.text()
        PW = self.lineEdit_5.text()
        # PORT = int(self.lineEdit_6.text())

        FTPClass.reset()
        ret = FTPClass(FTP(HOST))
        print(ret,"+++++++++++++++++ 1")

        FTPClass.tea().encoding = 'utf-8'
        result = FTPClass.tea().login(ID, PW)
        print(result)

        if result and result.split(' ')[0] == '230':
            print("로그인 성공!!")
            # self.textEdit_2.setText(result+"로그인 성공!!")
            self.myWindow = MyWindow()
            self.myWindow.show()
            self.close()
        else:
            print("Something went wrong.")
            # self.textEdit_2.setText("로그인 실패!!!!, ID/PW 등을 정확히 입력했는지 확인해 보시기 바랍니다.!")


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

        self.local_path =  None
        self.remote_path = None

        self.setFixedSize(820,900)
        self.setWindowIcon(QIcon("pagichacha.png"))
        self.setupUi(self)

        if result and result.split(' ')[0] == '230':
            self.textEdit_2.setText(result+"로그인 성공!!")
        else:
            self.textEdit_2.setText(result+"로그인 실패!!")

        self.populate_local()

    def populate_local(self):
        self.local_path = os.getcwd() # 현재 디렉토리를 가져옴
        print(self.local_path,"++++ 1")
        self.fs_model = QtWidgets.QFileSystemModel() #파일시스템 모델의 객체 생성
        print(self.fs_model,"++++ 2")
        self.fs_model.setRootPath(self.local_path) # 현재 디렉토리를 루트로 설정
        print(self.fs_model.setRootPath(self.local_path),"++++ 3")
        self.treeView.setModel(self.fs_model) #트리뷰 설정
        print(self.treeView.setModel(self.fs_model),"++++ 4")
        self.treeView.setRootIndex(self.fs_model.index(self.local_path)) # 트리뷰의 루트를 현재 디렉토리로 지정
        print(self.treeView.setRootIndex(self.fs_model.index(self.local_path)),"++++ 5")
        print('local_path:', self.local_path)


app=QApplication(sys.argv)
# window = MyWindow()
window = LoginWindow()
window.show()
print("Before event loop")
app.exec_()
print("After event loop")

 

O 소스 다운로드 및 실행
 
 - 소스파일 다운로드 후 cmd 또는 파워쉘 등에서 아래와 같이 실행하시기 바랍니다.
( '1.FTPClient2_C.ui' 파일은 실행 파일(1.testConnect4.py)과 동일한 경로에 위치 시켜야 합니다.)
 > python 1.testConnect4.py

 

 


 
 
O 소스 분석

 

- 아래 소스 분석 내용 중 1~17번 항목은 이전과 동일하며, 18~22만 항목만 새로 추가 되었습니다.

 

1.form_class = uic.loadUiType("1.FTPClient2_C.ui")[0] <-- qt disigner로 만든 UI를 사용하겠다.
2.class FTPClass(): <-- ftp서버 연결을 위한 클래스 선언
3.@staticmethod <-- 다른 클래스에서 사용 가능하도록 staticmethod 키워드를 사용(이 키워드 아래에 정의된 함수를 다른 클래스에서 사용 가능)

4.
@staticmethod
def tea(): <-- 인스턴스를 리턴
    if not FTPClass.__instance:
        raise Exception("FTPClass를 먼저 인스턴스화 해야 합니다.")
    return FTPClass.__instance

 

5.
@staticmethod
def reset(): <-- 인스턴스를 'None'로 설정
    FTPClass.__instance = None

 

6.
def __init__(self, banana): <-- 클래스의 인스턴스 초기화
    if FTPClass.__instance:
        raise Exception("인스턴스가 이미 존재합니다.")
    FTPClass.__instance = banana

 

7.
class LoginWindow(QtWidgets.QMainWindow, form_class):
    self.setupUi(self) <-- form_class UI를 사용하겠다

8.self.lineEdit_5.returnPressed.connect(self.ftpConnect) <-- lineEdit_5(패스워드) 입력 후 엔터 시 ftpConnect()함수 호출
9.self.pushButton.clicked.connect(self.ftpConnect) <-- pushButton(연결버튼) 클릭 시 ftpConnect()함수 호출
10. HOST = self.lineEdit.text() <-- lineEdit(호스트)의 값을 읽어서 HOST변수에 저장(아래 해설 동일함)
11.ID = self.lineEdit_4.text()
12.PW = self.lineEdit_5.text()
13.FTPClass.reset() <-- LoginWindow클래스 내에서 다른 클래스(FTPClass)의 함수를 직접 호출(@staticmethod로 선언해줘서 가능), 인스턴스를 'None'로 설정
14.ret = FTPClass(FTP(HOST)) <-- ftp서버에 연결
15.FTPClass.tea().encoding = 'utf-8' # 서버 접속 후 디렉토리 또는 파일명이 한글이면 깨지는 것을 방지
16.result = FTPClass.tea().login(ID, PW) <-- 연결된 ftp서버에 로그인 시도

17.
if result and result.split(' ')[0] == '230': <-- 서버쪽 리턴 값이 '230' 이면 로그인 성공
    print("로그인 성공!!")
    self.textEdit_2.setText(result+"로그인 성공!!") <-- 화면에 '로그인 성공' 메시지 출력
else:
    print("Something went wrong.")
    self.textEdit_2.setText("로그인 실패!!!!, ID/PW 등을 정확히 입력했는지 확인해 보시기 바랍니다.!")

 

18.

def ftpConnect(self):
    global result <-- 다른 클래스에서 result변수를 사용하기 위해 global 키워드 사용

 

19.

if result and result.split(' ')[0] == '230':
    print("로그인 성공!!")
    # self.textEdit_2.setText(result+"로그인 성공!!")
    self.myWindow = MyWindow() <-- MyWindow클래스의 myWindow인스턴스 생성
    self.myWindow.show() <-- myWindow인스턴스의 show()함수로 새창을 띄움
    self.close() <-- 기존 창은 close

 

20.
class MyWindow(QtWidgets.QMainWindow, form_class):
    if result and result.split(' ')[0] == '230':
        self.textEdit_2.setText(result+"로그인 성공!!") <-- 새창에 로그인 메시지를 보여주기 위해 MyWindow클래스에 넣어줌
    else:
        self.textEdit_2.setText(result+"로그인 실패!!")

 

21.self.populate_local() <-- 초기화 함수에서 populate_local()함수 호출

 

22.
def populate_local(self):
    self.local_path = os.getcwd() <-- 현재 디렉토리를 가져옴
    self.fs_model = QtWidgets.QFileSystemModel() <-- 파일시스템 모델의 객체 생성
    self.fs_model.setRootPath(self.local_path) <-- 현재 디렉토리를 루트로 설정
    self.treeView.setModel(self.fs_model) <-- 트리뷰 설정
    self.treeView.setRootIndex(self.fs_model.index(self.local_path)) <-- 트리뷰의 루트를 현재 디렉토리로 지정
    print('local_path:', self.local_path)

 


 

O 주요 내용

 

 

1. ftp서버를 실행 후 아래 그림에서 보듯이 ftp서버의 IP를 확인합니다.

 

 

2. (1)프로그램 실행 후 위에서 확인한 ftp서버의 IP를 (2)호스트에 입력하고 (3)아이디, (4)패스워드를 입력 후 엔터 또는 (5) '연결' 버튼을 클릭 후 아래 창에 (6)정상적으로 로그인 되었다는 메시지('로그인 성공')가 뜬다면, 잘 실행된 것입니다.

 

그리고 왼쪽 하단 (7)트리뷰에 로컬PC의 현재 디렉토리의 폴더와 파일 목록이 나온다면 정상적으로 실행된 것입니다.

 

 

 

3. 다른 클래스(MyWindow 클래스)에서 사용하기 위해 result변수를 global 키워드로 정의합니다.

이후 로그인에 성공하면 MyWindow클래스의 인스턴스(myWindow)를 생성하고, 이 인스턴스의 show()함수로 새창을 띄웁니다.

새창이 떳으니 기존창은 필요없으므로, self.close()<-- 이 코드로 기존 창을 close 해줍니다.

 

 

 

4. 새창인 MyWindow클래스에서 로그인 성공/실패 메시지를 보여주기 위해 위에서 global로 선언된 result변수를 가져와서, 텍스트에디트(textEdit_2)에 뿌려줍니다.

 

그리고 나서, 왼쪽 하단의 트리뷰에 현재 디렉토리 기준으로 하위 폴더와 파일목록을 보여주기 위해서 populate_local()함수를 호출합니다.

 

이 함수는 현재 디렉토리를 가져와서, 현재 디렉토리를 루트(기본)디렉토리로 설정한 후, 트리뷰를 만들고, 튜리뷰의 루트를 현재 디렉토리로 지정하여 그 하위 폴더와 파일을 뿌려줍니다.

(만일 98라인의 'self.treeView.setRootIndex(self.fs_model.index(self.local_path))' <-- 이 코드가 생략되면 기본 드라이브(C, D 드라이브 등)가 표시 됩니다.)

 

 

 

 

 

5. 위의 2번에서 실행한 모습(파일들)과 동일하게 탐색기에서도 확인할 수 있습니다.

 

 

 

 

 

 

 


 

ㅁ 정리
 
O 우리가 배운 내용
 
 - 오늘은 FTP서버에 로그인하는 기능 중 로컬PC의 폴더와 파일을 리스팅하는 부분을 만들어 보았습니다.
 
 
 
 - 오늘 우리가 배운 내용을 간단히 정리해 보면 아래와 같습니다.
 
 > 1. ftpConnect()함수에서 로그인 성공 시 MyWindow클래스의 인스턴스(myWindow) 생성 및 새창 띄우고 기존창 close
 > 2. MyWindow클래스의 init함수에서 populate_local()함수 호출
 > 3. populate_local()함수에서 로컬PC의 폴더와 파일을 보여주기 위한 트리뷰 설정
 
 

 

오늘은 여기까지이며, 위의 내용이 유익하셨다면, 좋아요와 구독 부탁드립니다.

 

 

감사합니다.

728x90
반응형
LIST