프로그래밍 관련/PyQt

PyQt. 파일 불러오기 창. QFileDialog

존버매니아.임베디드 개발자 2021. 11. 7. 16:03
반응형

1. Default 예시코드 및 개요

파일 Load 하는 기능

QFileDialog 클래스를 사용하면 된다.

일단 기본코드는 아래와 같다.

 

아래 예시코드에서는 옵션에 대한 선택을 전혀 하지 않은 상태인데, 뒤에서 추가로 설명하겠지만

이것저것 다양한 옵션들이 있음

이 글의 제일 마지막에는 각종 옵션들까지 다 넣은 예시코드를 넣어두었음.

import sys
from PyQt5.QtWidgets import *

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUI()

    def setupUI(self):
        self.setGeometry(800, 200, 500, 300)

        btn1 = QPushButton("load",self)
        btn1.clicked.connect(self.btn_fun_FileLoad)      

    def btn_fun_FileLoad(self):        
        fname=QFileDialog.getOpenFileName(self)        
        print(fname[0])
        print(fname[1])
        

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mywindow = MyWindow()
    mywindow.show()
    app.exec_()

위 코드를 실행하여 Push Button을 누르면 다음과 같은 익숙한 파일 선택창이 뜬다.

이 때, Default로 선택되어있는 폴더 경로는 해당 파이썬 파일이 존재하는 폴더가 선택된다.

위 코드를 실행할 경우, Default로 열리는 경로( 그림의 1번) 는 해당 파이썬 파일이 존재하는 폴더이다.

또한 파일 확장자 필터는 Default로 All Files(그림의 2번) 로 선택된다.

 

여기서 파일 골라서 열기를 누르면 tuple[2] 형태의 아웃풋이 리턴된다.

tuple[0]에는 선택한 파일의 "풀 경로"가 str 타입로 담겨있으며 

tuple[1] 그림의 2번에 있는 필터 정보 인 All Files(*) 가 담겨있다.

 

예를 들어 위 그림에서 000_Test_memo.py 를 골라서 열기를 누르면

        print(fname[0])

        print(fname[1])

에 의해 실행결과는 아래와 같다. 

>>> D:/TempBlog/000_Test_memo.py
>>> All Files (*)

2. 추가 설명1. 파일을 고르지 않고 파일 선택창을 닫거나 취소 눌렀을때를 고려하자

    def btn_fun_FileLoad(self):        
        fname=QFileDialog.getOpenFileName(self)

        if fname[0]:
            print("파일 선택됨")
        else:
            print("파일 안 골랐음")

파일 선택창을 열었지만, 파일을 고르지 않고 취소버튼을 누르거나 꺼버린다고해서

return 값이 아예 없는게 아니다. 여전히 tuple[2] 형태로 아웃풋을 내보내지만

단지 안에 데이터가 비어있을 뿐이다.

 

위와 같은 코드를 사용해서 파일 선택을 안하고 그냥 꺼버리는 상황에 대한 예외처리를 해주면 된다.


3. 파일 선택시 확장자 필터 만들어주기

QFileDialog 객체를 생성할 때 생성자의 Argument에 따라서 다양한 옵션들을 줄 수 있는데

파일의 확장자제한을 주는 필터에 대한 설정을 할 수 있다.

;; <- 표시를 이용해서 다양한 종류의 필터타입을 추가할 수 있다. 아래 예시 코드와 그림보면 이해 가능 할 것임

그리고 PowerPoint(*.pptx *ppt) 에서 볼 수 있듯이 괄호안에서 서로 다른 확장자 간에는 띄어쓰기로 구분하는 점에 유의하자.

 

def btn_fun_FileLoad(self):        
        fname=QFileDialog.getOpenFileName(self,'','','All File(*);; PowerPoint(*.pptx *ppt) ;; MyFile(*.myfile)')

        if fname[0]:
            print("파일 선택됨 파일 경로는 아래와 같음")
            print(fname[0])
        else:
            print("파일 안 골랐음")

위 코드를 실행해보면 아래와 같다. 


4. QFileDialog.getOpenFileName 사용시 줄 수 있는 다양한 옵션들에 대하여

def getOpenFileName(parent: typing.Optional[QWidget] = ..., caption: str = ..., directory: str = ..., filter: str = ..., initialFilter: str = ..., options: typing.Union['QFileDialog.Options', 'QFileDialog.Option'] = ...) -> typing.Tuple[str, str]: ...

사실 필터 옵션 외에도 다양한 추가 설정들을 할 수 있는데, 그것은 getOpenFileName 메소드의 Function Definition을

보면 대강 이해가 가능 할 것이다.

 

한 가지 알아둘 것은, 메소드 Definition에 파라미터가 아래와 같이 6개가 있는데

꼭 6개를 다 적을 필요는 없다는 것이다. 

parent, caption , directory, filter, initialFilter, options 

이름을 보면 대강 각 파라미터의 용도가 뭔지 알 수 있을 것이다. 우선은 

아래 예시와 실행결과를 통해 알아보자.

fname=QFileDialog.getOpenFileName(self,"File Load",'D:/ubuntu/disks','Text File(*.txt);; PPtx file(*ppt *pptx)' )

 

첫번째 옵션은 파일오픈창의 이름

두번째 옵션은 파일오픈창이 열릴때 Default로 열리는 경로 및 파일이름

세번째 옵션은 필터 정보이다.

 

두번째 옵션과 관련된 유의사항

1) 두번째 옵션에서 폴더 경로를 적을 때 \(역슬레시) 표시를 쓰면 에러가 뜬다.

위 예시처럼 D:\ubuntu\disks 폴더를 고르고 싶으면

역 슬레시가 아니라 슬래시를 사용하거나, 혹은 역슬래시를 두개 붙여 써야한다.

D:\ubuntu\disks  <-(x)

D:/ubuntu/disks  <-(O)

D:\\ubuntu\\disks  <-(O)

D:\ubuntu\disks  <-(x)   (역슬레시 1개만 쓰면 에러로 인식함)
D:/ubuntu/disks  <-(O)   (슬레시 1개를 사용)
D:\\ubuntu\\disks  <-(O) (역슬레시 2개를 사용)

2) 두번째 옵션에서 나타내는게 꼭 폴더경로만을 의미하진 않는다.

아예 디폴트로 파일까지 지정이 가능함 (아래 그림참조)

3.그리고 , 만약 지정한 경로가 해당 pc에서 존재하지 않을 경우, 에러가 뜨는게 아니라

최대한 가능한 부분까지만 이동된다.

 

 

 무슨 말이냐면 

 만약에 경로를 D:/leap/Test 라고 적었는데, 

 해당 pc에 만약 leap 이라는 폴더가 없다면

 D: 까지만 선택되서 열릴 것이고

 만약 leap이라는 폴더는 있는데 Test 라는 폴더가 없다면

 D:/leap 까지만 열린다는 소리다.

 


위 예시에서는 안적었지만

네번째 옵션은

여러개의 필터 옵션중에 디폴트로 선택되는 걸 뭘로 할건지 고르는 것이고.

 

 

다섯번째 옵션은

좀 더  추가적인 내용들이 많이 있는데 나도 공부를 안해서 잘 모르겠다.

옵션 관련해서는 아래와 같은 선택사항들이 있음

class QFileDialog(QDialog):

    class Option(int):
        ShowDirsOnly = ... # type: QFileDialog.Option
        DontResolveSymlinks = ... # type: QFileDialog.Option
        DontConfirmOverwrite = ... # type: QFileDialog.Option
        DontUseSheet = ... # type: QFileDialog.Option
        DontUseNativeDialog = ... # type: QFileDialog.Option
        ReadOnly = ... # type: QFileDialog.Option
        HideNameFilterDetails = ... # type: QFileDialog.Option
        DontUseCustomDirectoryIcons = ... # type: QFileDialog.Option

이런 저런 옵션들 다 넣은 예시코드

import sys
from PyQt5.QtWidgets import *

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUI()

    def setupUI(self):
        self.setGeometry(800, 200, 500, 300)

        btn1 = QPushButton("load",self)
        btn1.clicked.connect(self.btn_fun_FileLoad)      

    def btn_fun_FileLoad(self):        
        fname=QFileDialog.getOpenFileName(self,"File Load",'D:/ubuntu/disks/swap.disk','All File(*);; Text File(*.txt);; PPtx file(*ppt *pptx)', 'PPtx file(*ppt *pptx)' )

        if fname[0]:
            print("파일 선택됨 파일 경로는 아래와 같음")
            print(fname[0])
        else:
            print("파일 안 골랐음")
        

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mywindow = MyWindow()
    mywindow.show()
    app.exec_()
반응형