Language/Python

Python 공부정리 - PyQt5 - 2

Tarel 2023. 2. 10. 17:17

지난 시간에 이어서 계속

 

# 기본 탬플릿
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class MyApp(QWidget):
    def __init__(self) -> None:
        super().__init__()
        self.initUI()

    def initUI(self):
    	# 여기에 함수 입력
    
    
    
        # 필수 설정
        self.setWindowTitle('제목 입력')
        self.setGeometry(300, 300, 300, 300)
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec_())

기본적인 템플릿을 만들어보았다.

이 템플릿에서, initUI 함수에 내용을 추가하는 형태로 작성하자

 

 

1. 툴바와 메뉴바

이번에는 툴바를 만들어보자

 

이 툴바에는 저장 기능과 종료 기능만을 넣을 것이고

메뉴바에도 종료 기능 만을 넣을 것이다.

 

또한 아래 이미지를 사용할 것이다.

 

 

def initUI(self):
    #종료
    actExit = QAction(QIcon('./Day09/exit.png'), 'Exit', self)
    actExit.setShortcut('Ctrl+Q')                   
    actExit.setStatusTip('앱 종료')
    actExit.triggered.connect(qApp.quit)

    #저장
    actSave = QAction(QIcon('./Day09/save.png'), 'Save', self)
    actSave.setShortcut('Ctrl+S')
    actSave.setStatusTip('저장')

    #메뉴바
    menubar = self.menuBar()
    menubar.setNativeMenuBar(False)#네이티브 메뉴바를 쓰지 않겠다는 말
    filemenu = menubar.addMenu('&File')
    filemenu.addAction(actExit)

    #툴바
    toolbar = self.addToolBar('MainToolBar') # 툴바 타이틀은 없어도 됨
    toolbar.addAction(actSave)
    toolbar.addAction(actExit)
    
    # GUI 화면 설정
    self.setWindowTitle('Bar Window') # 창의 타이틀 이름을 바꿈
    self.move(50, 50) # 처음 창의 위치를 선정, 0,0은 왼쪽 위, 기본값은 정 중앙
    self.resize(400, 200) # 창의 크기를 바꿈
    self.show()#핵심! 창을 출력

actExit는 종료 기능을, actSave는 저장 기능을 말한다.

단, 저장은 실제로 그 기능을 지원하지 않는다. (종료기능은 실제로 동작한다.)

각 변수에는 아이콘과 단축키를 지정해 주었다.

 

실행하면 보시다시피 툴바와 아이콘이 추가된 것을 볼 수 있다.

이 툴바는 좌측의 점선부분을 끌어서 위치를 바꾸어 줄 수 있다.

 

메뉴바에도 Exit가 추가된 것을 알 수 있다.

 

2. 콤보박스

이번엔 콤보박스를 만들어보자

콤보박스란, 선택하면 옵션리스트가 나오는 것을 말한다.

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        lblOption = QLabel('선택값 : ', self)
        lblOption.move(20, 20)
        
        cbOption = QComboBox(self)
        cbOption.addItem('Option 1')
        cbOption.addItem('Option 2')
        cbOption.addItem('Option 3')
        cbOption.addItem('Option 4')
        cbOption.addItem('Option 5')
        cbOption.move(20, 40)
        cbOption.activated[str].connect(self.onActivated)        

        # 이 밑은 필수 설정
        self.setWindowTitle('콤보박스')
        self.setGeometry(300, 300, 300, 300)
        self.show()

    def onActivated(self, text):
        self.lblOption.setText('선택값 :' + text)
        self.lblOption.adjustSize() # 글자수 만큼 라벨 넓이를 조정

여기서 중앙의 Option은 그냥 리스트다.

onActivated 함수는 콤보박스를 선택했을 때의 함수이다.

 

출력하면 이와같이 나오는 것을 알 수 있다.

 

 

 

3. 라인에디트

이번엔 글자를 넣는 공간을 만들어보자

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.lblResult = QLabel(self)
        self.lblResult.move(20, 20)
        
        txtInput = QLineEdit(self)
        txtInput.setEchoMode(2) #글자를 넣으면 페스워드 형태로 보인다
        txtInput.move(20, 40)
        txtInput.textChanged[str].connect(self.onChanged)
        
        #필수 설정
        self.setWindowTitle('라인에디트')
        self.setGeometry(300, 300, 300, 300)
        self.show()

    def onChanged(self, text):
        self.lblResult.setText('입력값 :' + text)
        self.lblResult.adjustSize() # 라벨 사이즈 자동

이 코드엔 글 입력기와 라벨 하나가 붙어있다.

setEchoMode 메소드를 사용하면 비밀번호처럼 입력된다.

onChanged 함수가 라벨을 나타내는 함수다.

 

이 코드를 실행하면 보시다시피 빈 칸 하나만 생기는 것을 알 수 있다.

라벨은 보이지도 않지만

글자를 입력하는 순간 라벨이 보인다.

 

 

4. 다이얼 로그

버튼을 누르면 창이 뜨고, 그 창에 입력한 값을 받아오도록 하자

 

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.btnDlg = QPushButton('Dialog', self)
        self.btnDlg.move(20, 20)
        self.btnDlg.clicked.connect(self.onClicked)

        self.txtInput = QLineEdit(self)
        self.txtInput.move(20, 50)

        #필수 설정
        self.setWindowTitle('다이얼로그')
        self.setGeometry(300, 300, 300, 300)
        self.show()

    def onClicked(self):
        text, ok = QInputDialog.getText(self, '인풋다이얼로그', '이름을 적으세요')

        if ok:
            self.txtInput.setText(text)

이번것도 크게 어려운 것은 없다.

 

다만 onClicked 함수에선 총 두가지를 받아오는데

text는 입력한 내용을, ok는 승인 여부가 담긴다.

즉, 다이얼로그 버튼을 누르면 창이 뜨는데, 여기다 글을 입력하면 입력내용은 text에 담기고

확인 버튼을 눌렸다면 ok에 true가 담긴다.

 

다이얼로그에 문자열을 입력하고 ok를 누르면 이렇게 내용이 들어간다.

 

5. 이미지 넣기

 

아래 이미지를 넣어보자

 

넣어볼 고양이 이미지

파일이름은 cat.png로 하고 실행파일과 같은 경로에 넣어주자

 

def initUI(self):
    # 이미지 사이즈 강제 변경 .scaledToWidth(w)
    pixmap = QPixmap('./Day10/cat.png').scaledToWidth(800)

    lblImage = QLabel(self)
    lblImage.setPixmap(pixmap)
    lblSize = QLabel(str(pixmap.width()) + 'x' + str(pixmap.height()))
    lblSize.setAlignment(Qt.AlignmentFlag.AlignCenter) # Qt.AlignCenter 가능

    vbox = QVBoxLayout(self)
    vbox.addWidget(lblImage)
    vbox.addWidget(lblSize)

    self.setLayout(vbox)

    # 필수설정
    self.setWindowIcon(QIcon('./Day09/iot.png'))
    self.setWindowTitle('이미지 위젯')
    self.show()

pixmap은 고양이사진 파일의 경로고

lblImage는 이미지를 배치하기 위한 변수이며

그 아래 lblSize는 이미지의 크기를 나타내는 변수로  없어도 상관없다.

출력하면 고양이가 잘 나오는 것을 알 수 있다.

 

6. 파일 불러오기

텍스트 파일을 불러와보자

이건 코드가 꽤나 길다.

 

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.textEdit = QTextEdit(self)
        self.setCentralWidget(self.textEdit)
        self.statusBar()
        
        openFile = QAction(QIcon('open.png'), '&Open', self)#아이콘이 없어서 안뜸
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('파일 열기')
        openFile.triggered.connect(self.onClicked)

        menubar = self.menuBar()
        menubar.setNativeMenuBar(False)
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)

        #필수 설정
        self.setWindowTitle('라인에디트')
        self.setGeometry(300, 300, 300, 300)
        self.show()

    def onClicked(self):
        fname = QFileDialog.getOpenFileName(self, '파일열기', './')
        if fname[0]:
            file = open(fname[0], 'rt', encoding='utf-8')
            with file:
                data = file.read()
                self.textEdit.setText(data)        
            file.close()
        QMessageBox.about(self, '성공', '로드했습니다.')

    def closeEvent(self, event) -> None:
        reply = QMessageBox.question(self, '종료', '저장하지 않은 정보가 날아갑니다.<br> 종료합니까?',
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept() # 프로그램 종료
        else:
            event.ignore() # 프로그램 계속

initUI 함수에서, 첫부분은 메모장 프로그램처럼 텍스트를 입력할 수 있는 공간을 가져온 것이다.

 

openFile 변수에서, 아이콘을 불러오도록 하고 있지만 우리가 따로 아이콘을 다운받지 않았기 때문에 아이콘은 출력되지 않는다.

또한 파일 열기 기능에 단축키 Ctrl+O를 부여하고 파일을 열 때, 상태창에 '파일 열기'가 뜨도록 한다.

 

기본함수 외에도 onClicked함수와 closeEvent함수가 있는데

이는 Open 버튼을 눌렀을 때의 이벤트와

또, 창을 끌 때의 이벤트를 말한다.

출력해보면 텍스트를 쓸 수 있는 창이 나오는데

 

File을 클릭하면 이렇게 Open이 나오고 여기에 마우스를 올리면 상태창에 '파일 열기' 메시지가 나타난다.

 

 

파일 열기를 누르면 이와같이 파일을 여는 창이 뜨고

 

파일을 로드하면, 이렇게 파일이 가져와지면서 성공했다는 메시지가 뜬다.

 

 

파일을 끄려고 할 경우, 이렇게 경고메시지가 뜨는 것을 볼 수 있다.