티스토리 뷰

Pyqt5를 이용하여 GUI를 짜는 도중, 한 가지 어려움에 다다랐다.

QLabel에 Image를 넣어놓았다. Image를 클릭할 시 FileOpenDialog가 뜬 후, 사용자가 Image를 고르면 해당 이미지로 바뀌어야 하는 기능을 구현하여야 했다.

QLabel에는 clicked라는 속성이 없었고, 여러 MouseEvent가 있었지만 사용해보아도 원하는 방법이 아니었고, 에러가 많이 떴다. 해결안 또한 복잡했다.

 

그래서 구글에 검색을 하다보니 functools라는 모듈을 사용하는 방법이 나왔다.

코드는 아래와 같다.

...
	self.mainImg = QLabel(self) # main사진이 들어갈 Label
        self.mainImg.setObjectName('mainImg')
        self.mainImg.setMaximumSize(700, 500) # label 최대 width, height를 조절
        self.mainImg.setScaledContents(1) # Image를 label 크기에 맞게 조절. 1 : true, 0 : false. false인 경우, 이미지가 label 크기만큼만 나오고 잘린다.

        self.faceImg = QLabel(self) # 얼굴사진이 들어갈 Label
        self.faceImg.setObjectName('faceImg')
        self.faceImg.setMaximumSize(400, 400)
        self.faceImg.setScaledContents(1)

        self.detectedFaceImg = QLabel(self) # main에서 찾은 얼굴사진이 들어갈 Label
        self.detectedFaceImg.setMaximumSize(400, 400)
        self.detectedFaceImg.setScaledContents(1)

        # image Click Event 설정
        # self.WIDGET.mousePressEvent = functools.partial(Method, WIDGET)
        self.mainImg.mousePressEvent = functools.partial(MainWindow.fileOpenMethod, self.mainImg)
        self.faceImg.mousePressEvent = functools.partial(MainWindow.fileOpenMethod, self.faceImg)

...

    def fileOpenMethod(self, event):
        filename = QFileDialog.getOpenFileName(self, 'Open File', '/', 'Image Files (*.png *.jpg)')

        print('called by: ' + str(self.objectName()))
        print('fileName: ' + filename[0])

        if filename[0]: # 만약 파일을 골랐으면
            pixmap = QtGui.QPixmap(filename[0])
            self.setPixmap(QPixmap(pixmap))
            self.resize(pixmap.width(), pixmap.height())

        if(str(self.objectName()) == 'mainImg') :
            print('hahaha I find it')
            # 해당 파일 넘겨줘서 face recognition
...

현재 작성중인 파일의 일부분이다. mainImg와 faceImg에는 setObjectName()을 통해 이름을 넘겨주었다. 클릭 된 후에 함수에서 이름을 받아 구별한 뒤, 각각 다른 작업을 실행하기 위함이다.

중간의 self.mainImg.mousePressEvent = functools.partial(MainWindow.fileOpenMethod, self.mainImg) 부분이 바로 fileOpenMethod와 QLabel인 mainImg를 연결해주는 부분이다. MainWindow부분을 제거하고 self로 실행하게 된다면

TypeError: fileOpenMethod() takes 2 positional arguments but 3 were given

이라는 에러가 뜨게된다. fileOpenMethod는 2개의 인자를 받으나 3개의 인자가 왔다는 뜻이다. self랑 MainWindow의 차이는 뭔지 모르겠다. 참고로 MainWindow는 해당 Method가 선언되어있는 Class의 이름이다. 아마 조금 더 찾아보아야 할 것 같다.

(좌) Main화면, (우) FileDialog 팝업 화면
당연히 이미 등록한 사진을 변경하는것도 가능하다.

 

찾아보니 functools는 이렇게 실행하기 위함이 아닌, 많은 코드를 반복적으로 실행할 때 유용하게 사용하기 위해 사용한다고 한다.

아직 Python을 공부하며 진행하는 중이니 양해부탁드린다. 찾아보긴 하겠지만 혹시 QLabel Clickable에 대해 좀 더 좋은 코드로 구현하는 방법 등을 알고 계신다면 알려주시면 감사드리겠다.

 

해당 프로그램의 Git 링크를 공유한다.

https://github.com/gurdlwl/FaceFinder/blob/master/FaceFinder_Main.py

 

gurdlwl/FaceFinder

python dlib를 사용한 얼굴 인식 프로그램. Contribute to gurdlwl/FaceFinder development by creating an account on GitHub.

github.com

 

댓글
공지사항