본문 바로가기
IT

파이썬 - Qt 디자이너를 이용한 프로그램 만들기

by 소혜민 2025. 1. 30.
반응형

Qt Designer는 GUI를 마우스로 가져다 놓고 끌어서 조정하여 쉽게 만들 수 있는 툴입니다. 드래그 앤 드롭 방식이라고 흔히들 말하는 방법이죠. Qt Designer는 확장자가 .ui인 파일들을 만듭니다. 우리는 이렇게 만들어진 .ui를 PySide6에 들어 있는 툴 중의 하나인 pyside6-uic를 써서 .py로 변환을 해서 사용을 하게 될껍니다. 우선 다음의 경로에서 Qt Designer를 다운로드 받아서 설치를 하도록 합시다. 

 

https://build-system.fman.io/qt-designer-download

 

설치가 되었다면 Qt Designer를 이용해서 다음과 같은 화면을 만들어 보도록 합시다. 시작을 할 때, Dialog without button으로 시작을 해야 아무것도 없는 상태에서 내 마음대로 디자인을 할 수 있습니다. 마음대로 좌측에 있는 Widget Box에서 위젯들을 골라서 클릭을 한 채로 다이얼로그에 위치 시킵니다. 화면에 미리 보이는 글자를 입력할 수 있는 부분은 더블 클릭을 해서 글자를 입력할 수 있습니다. 버튼을 더블 클릭해서 ‘확인’ 또는 ‘Exit’과 같이 입력을 할 수 있습니다. 그리고 각 위젯들을 클릭하면 모두 5개의 점들이 보이는데 그 점들을 클릭해서 위젯의 크기도 마음대로 조절할 수 있습니다. 

 

 

위젯을 클릭하고 오른쪽의 Property Editor에서 objectName을 찾으시면 기본 이름이 어떻게 되어 있는지 확인을 할 수 있고 내가 원하는대로 바꿀 수도 있습니다. Push Button의 이름은 pbConfirm, Line Edit의 이름은 leName으로 바꿔주시기 바랍니다. 각각의 위젯은 어떤 이름을 줘도 상관이 없습니다. 하지만 프로그래머들은 나름의 규칙을 주어 이름을 주곤합니다. 왜냐하면 이름만 보고도 이 위젯이 어떤 위젯이고 어떤 역할을 하는 것인지 파악을 하기 위함입니다. 그래서 Push Button은 앞에 접두어 pb를 Line Edit은 le와 같이 접두어를 붙입니다. 그리고 기능을 더해서 pbConfirm, leName과 같이 말이죠. 

 

각각 디자인을 하고, 이름을 지정해 줬으면 메뉴에서 Form → Preview 혹은 Ctrl + R을 눌러 디자인한 GUI를 실행시켜 볼 수 있습니다. 앞의 그림에서도 디자인을 하고 실행을 시킨 화면을 볼 수 있습니다. Line Edit 위젯에는 입력을 해 볼 수 있습니다. 다만 그것까지만이죠. 확인 버튼을 누르거나 Exit 버튼을 눌러도 동작을 하지는 않습니다. 동작을 하는 부분은 우리가 코딩을 해 넣어야겠죠. 먼저 우리가 만든 UI를 first_ui라는 이름으로 저장을 합시다. 그리고 우리 프로젝트 폴더에 Ui라는 폴더를 만들고 넣어 둡니다. 복사를 했으면 파이참 터미널 창에서 다음과 같이 명령을 내려 .ui 파일을 .py 파일로 변환을 합니다. 

 

 008_pyside6.py

 

Ui 폴더에 들어 있는 first_ui.ui를 first_ui.py라는 파이썬 파일로 변환을 해 줍니다. 열어보면 화면에 보이는 것처럼 코딩이 되어 있는 것을 확인 할 수 있습니다. 아쉽지만 변환이 된 .py  파일은 실행을 시켜도 아무 동작을 하지 않습니다. 

 

이왕 변환된 .py 파일을 열었으니 어떻게 변환이 되었는지 살펴보도록 하겠습니다. 우선 import 아래를 보면 Class가 선언이 되어 있는데 이름이 Ui_Dialog로 되어 있습니다. 클래스 내부를 보면 두 개의 함수가 보이네요 setupUi() 함수와 retranslate()라는 함수 입니다. 좀더 살펴보면 setupUi() 함수에서 retranslate()라는 함수를 호출을 하고 있음도 확인하실 수 있습니다. setupUi()의 맨 하단부를 살펴보시면 됩니다. 자동으로 변환된 파일이니 변환된 상세한 내용은 보지 않겠습니다. 편하게 사용하기 위해서 만든 것인데 더 깊이 파고들면 알아야 할 내용들이 너무 많아질 것 같습니다. 

 

그럼 우리가 만든 first_ui.py를 어떻게 활용하는지 살펴보도록 하겠습니다.




009_first_ui2.py

 

앞서 만들었던 008.pyside6.py에 비해서 두 줄이 추가되고 한 줄이 수정이 되었습니다. 3, 7번째 줄은 추가가 되었고 4번째 줄은 수정이 되었습니다. 차례대로 살펴보겠습니다. 먼저 세 번째 줄을 보면 다음과 같습니다.

 

 from first_ui import Ui_Dialog

 

first_ui.py에서 있는 Ui_Dialog라는 클래스를 import하라는 의미입니다. py는 빼고 파일명을 적어준 것입니다. 각각의 변수, 함수 등에 대해서 어디에서 만들어졌는지를 알고 싶다면 해당 위치에 커서를 놓으시고 Ctrl 버튼을 누른 상태에서 B 버튼을 누르시기 바랍니다. Ui_Dialog를 마우스로 클릭을 해서 커서(‘|’)가 깜박거리게 해 놓고 Ctrl + B를 누르시면 first_ui.py 파일이 자동으로 열리고 Ui_Dialog가 선언이 된 곳으로 이동을 하게 됩니다.

 

 class MainWindow(QMainWindow, Ui_Dialog):

 

우리가 만든 MainWindow라는 클래스를 선언하는 부분입니다. 내가 윈도우를 띄울 때 쓸 클래스의 이름은 mainWindow라는 것이고, 미리 만들어 놓은 윈도우를 가져다 쓰기 위해서 괄호 안에 클래스를 넣을 수 있습니다. 무엇을 기본으로 참고할 것이냐 하면 QMainWindow라는 PySide6.QtWidgets에서 이미 만들어 놓은 패키지인 QMainWindow를 사용해서 화면을 만들겠다는 의미입니다. 콤마 다음에 있는 것은 QMainWindow에서 만든 것을 기본으로 하되, 추가로 Ui_Dialog라는 클래스를 합쳐서 사용하겠다는 의미로 이해를 하면 됩니다.

 

 self.setupUi(self)

 

앞에 self가 붙어 있는 함수는 Ui_Dialog에 있거나 MainWindow에 있는 함수나 변수를 이야기 하는 것입니다. 앞에서 살펴본 바 대로 Ui_Dialog안에 setupUi라는 함수가 있습니다. 이 함수를 실행시킴으로 인해서 Qt Designer를 통해 만들고  py 파일로 만들었던 GUI를 화면에 그리는 동작을 하게 되는 것입니다. 

 

세 줄을 모두 확인해서 추가하고 수정을 하셨다면 실행이 잘 될 것입니다. Qt Designer에서 실행을 시켰던 것과 똑같은 화면이죠. 동작도 똑같고 버튼을 눌러도 별다른 반응을 하지 안는 것도 같습니다. GUI를 만들고 코딩을 통해서 우리가 만든 파이썬과 연결을 완료했습니다. 다시 한번 중요한 사항을 짚고 넘어가겠습니다. mainWindow = MainWindow()를 호출하면 다음 동작은 어떻게 될까요? MainWindow()라는 클래스가 실행이 되어야겠죠. 이때, 클래스라는 놈은 본인의 클래스 내에서 __init__라는 함수를 무조건, 자동적으로 호출하도록 설계가 되어 있습니다. 미리 약속된 함수라고 보시면 됩니다. 

 

GUI를 Qt Designer를 통해서 만들고 py라는 파이썬 파일로 만들고 코딩을 해서 실행까지 하는 것을 성공했으니 GUI에 있는 것들을 동작시켜볼 차례입니다. leName에 ‘홍길동’이라는 이름을 넣고 확인 버튼을 눌렀을 때, ‘홍길동 님 반갑습니다’라는 메시지를 터미널에 출력시키는 코딩을 해 보도록 하겠습니다. 

 

여기서 우리는 leName에 어떻게 텍스트를 넣는지 그리고 어떻게 참조를 할 수 있는지를 배울 것이고, 버튼의 경우 클릭을 했을 때 어떻게 그 동작을 인식할 수 있도록 코딩을 할 수 있는지를 배워 볼 것입니다. 






010_first_ui3.py

 

이번 코드에서 추가 된 것은 4 줄입니다. 먼저 코드를 보면 leName과 pbConfirm이라는 이름이 보일 것입니다. le는 lineEdit라는 위젯을 표현해 주기 위해서 pb는 Push Button을 표시해 주기 위해서 접두어로 붙였고, 그 다음은 각각 Name과 Confirm입니다. 이 두 개의 이름이 우리의 코드에서 사용이 되었습니다. 

 

 self.leName.setText("홍길동")

 

MainWindow 클래스는 QMainWoindow와 UI_Dialog를 모두 포함한다고 배웠습니다. 그러니 우리가 만든 UI_Dialog내의 QLineEdit 위젯인 leName 역시 같은 MainWindow 클래스 내에 있으므로 self.leName과 같이 참조를 할 수 있을 것입니다. QLineEdit은 키보드로 입력을 받아 들일 수 있는 위젯이기 때문에 텍스트를 담고 있습니다. 이 텍스트 값은 지정할 때 사용하는 함수는 setText() 함수 있습니다. 이 함수에 매개변수로 출력하고 싶은 텍스트를 지정하면 되는 것입니다. 

 

 self.pbConfirm.clicked.connect(self.confirmButton)

 

pbConfirm은 QPushButton입니다. 당연하게도 버튼이니 클릭을 하는 동작을 우리가 알 수가 있어야겠죠? 어떤 프로그램에서 버튼을 누르면 단순한 동작을 하는 경우도 있지만 여러가지 동작을 복합적으로 하는 경우도 있습니다. 예를 달자면 버튼을 눌렀는데 “프로그램을 종료하시겠습니까?”와 같은 메시지와 함께 확인을 누르면 프로그램을 종료하는 경우가 있겠습니다. 이것은 아주 간단한 예가 될 것이고 버튼을 눌렀을 때 새로운 프로그램이 뜨는 복잡해 보이는 동작을 하는 경우도 있습니다. 그래서 버튼이 눌렸을 때 특정한 동작을 수행할 함수가 연결이 되도록 해야 합니다. 그래서 버튼이 눌렸을 때는 특정한 함수를 연결이 되도록 connect라는 함수를 써서 새로운 함수와 연결을 해 주게 됩니다. pbConfirm이라는 QPushButton이 Click 되었을 때, connect() 함수 안에 있는 함수를 호출하라는 의미입니다. 즉, pbConfirm이 눌리면 self.confirmButton() 함수가 호출이 되는 것입니다.

 

 def confirmButton(self):

      print(self.leName.text() + " 님 반갑습니다")

 

pbConfirm이 클릭 되었을 때, 호출이 되는 함수 confirmButton() 함수 입니다. 우리가 이미 알고 있는 print() 함수인데 매개변수가 새롭습니다. leName의 text() 함수를 이용해서 text()를 읽어오고 뒤에 “ 님 반갑습니다”를 더해서 터미널에 출력을 하는 코드입니다. 프로그램을 실행시킨 후에 바로 확인 버튼을 누른다면 “홍길동 님 반갑습니다”를 출력하게 될 것입니다. 다른 이름을 leName에 입력하고 확인 버튼을 눌러보세요.

 

터미널에만 값을 출력하는 것보다 GUI를 이용해서 정보를 출력하면 어떨까요? 아마도 가장 많이 사용하는 윈도우 중의 하나가 다음과 같은 메시지 박스가 아닐까 싶습니다.

 

 

우리는 GUI를 Qt Designer를 이용해서 파워포인트를 사용해서 문서를 만들듯이 쉽게 만들었습니다. 그런데 이런 메시지 박스를 만들려면 어떻게 해야할까요? 필요할 때 마다 Qt Designer를 이용해서 만들 수 있겠죠? 윈도우 제목으로는 “파이썬 수업”과 같이 만들고 윈도우의 좌측에 느낌표 아이콘을, 메시지의 제목은 “수강 신청”, 사용자에게 묻는 내용은 “파이썬 RPA 과목을 수강하시겠습니까?” 그리고 버튼 세개는 모두 QPushButton을 이용해서 만들면 될 것 같습니다. 

 

그런데 말입니다. 메시지 박스는 사용 용도가 상당히 많습니다. 사용자에게 알려주거나, 또는 의견을 물어보거나 선택을 요구할 때 등등

너무나 많은 경우에 사용을 합니다. “프로그램을 종료하시겠습니까?”, “파일이 저장되지 않았습니다. 그냥 끝내시겠습니까?”, “에러가 발생하여 프로그램의 재시작이 필요합니다” 이 모든 것들이 메시지 박스를 이용해 사용자와 대화를 합니다. 이와 같이 빈번하게 많이 사용하는 것들을 매번 만들어 사용한다면 상당히 많은 종류의 메시지 박스를 만들어야 할 것 같습니다. 그래서 고맙게도 대부분의 GUI를 제공하는 패키지 또는 라이브러리에서 기본으로 제공을 해 줍니다. 메시지 박스 뿐만 아니라 파일 오픈 윈도우나 파일 저장 윈도우 역시도 많이 사용하기 때문에 제공을 해 주죠. 

 

011_messagebox.py

 

쉽고 편하게 그리고 간단하게 사용하기 위해서 showMsgBox() 함수를 만들었고 그 함수를 호출하는 예를 위에서 볼 수 있습니다. 앞의 메시지 박스와 함께 함수 호출에서 넘기는 순서를 보면 더더욱 쉽게 이해가 가능하겠죠?

“파이썬 수업”은 setWindoTitle() 함수에, “수강 신청”은 setText() 함수에, “파이썬 RPA 과목을 수강하시겠습니까?”는 setInformativeText() 함수에, QMessageBox.Information은 setIcon() 함수에, 그리고 Ok, Discard, Cancel 버튼은 “|”를 통해서 더하고 setStandardsButtons() 함수에, 마지막으로 QMessageBox.Ok는 setDefaultButton() 함수에 각각 넘겨서 메시지 박스를 그립니다. 

마지막 setDefaultButton()에는 하나의 버튼만 매개변수로 넘길 수 있는데 메시지 박스가 실행이 되었을 때 어느 버튼에 포커스가 맞춰져 있는지를 정하는 함수입니다. 실행을 해서 메시지 박스가 나타나면 버튼 중에서 테두리가 진회색이 아니라 파란색으로 되어 있는 버튼이 있습니다. 그 버튼이 Default로 설정이 된 버튼이고 그 상태에서 스페이스 바를 누르면 마우스로 해당 버튼을 클릭한 것과 같은 효과를 가져옵니다. 마우스 없이도 실행을 시킬 수 있도록 디자인이 되어 있기 때문입니다. 버튼간의 포커스를 옮기기 위해서는 키보드의 방향키나 Tab 키를 이용해서 옮길 수 있습니다. 그리고 실행을 위해서는 스페이스바나 엔터키를 사용할 수 있습니다. 

 

다음은 우리가 사용할 수 있는 옵션에 대해서 알아 보겠습니다. setIcon() 함수는 메시지 박스 좌측에 어느 아이콘을 출력할 것인지를 넘겨 주는 값입니다. 여기에 우리가 줄 수 있는 종류의 아이콘은 다음과 같습니다. 아이콘의 이름을 다음과 같이 바꿔가면서 제대로 동작하는지 확인해 보시기 바랍니다.

 

 

다음은 setStandardsButtons() 함수에 “|”를 이용해서 넣을 수 있는 버튼의 종류를 알아볼까요?

 

  QMessageBox.Ok
  QMessageBox.Open
  QMessageBox.Save
  QMessageBox.Cancel
  QMessageBox.Close
  QMessageBox.Discard
  QMessageBox.Apply
  QMessageBox.Reset
  QMessageBox.RestoreDefaults
  QMessageBox.Help
  QMessageBox.SaveAll
  QMessageBox.Yes
  QMessageBox.YesToAll
  QMessageBox.No
  QMessageBox.NoToAll
  QMessageBox.Abort
  QMessageBox.Retry
  QMessageBox.Ignore

 

정말로 많은 수의 버튼들이 이미 정의가 되어 있네요. 여기서 원하는 버튼들을 순서대로 “|”를 이용해서 매개변수로 넘겨주면 됩니다. 

 

 return msgbox.exec()

 

exec() 함수에 의해서 앞에서 정의한 모든 내용들이 메시지 박스에 실행이 되어 화면에 나타납니다. 그리고 exec() 함수는 사용자가 어떤 버튼을 눌렀는지 되돌려 줍니다. 그렇게 받은 값을 다시 return을 이용해 showMsgBox()를 호출한 곳으로 되돌려 줍니다. 여기서 되돌려 받는 값은 바로 앞의 테이블에서 본 버튼 이름과 동일하게 됩니다. 

따라서 사용자가 예를 들어 Yes 버튼을 눌렀다고 하면 return 값은 QMessageBox.Yes가 반환이 되는 것입니다. 이런 return 값에 의해서 우리는 사용자가 어떤 버튼을 눌렀는지 확인할 수 있고 그것을 기반으로 코딩을 할 수 있습니다. 

 

예를 들어 Yes, No 버튼이 두 개가 있는 메시지 박스의 경우 코딩은 다음과 같이 될 수 있습니다.




012_messagebox2.py

 

여기서도 처음 보여드리는 if 문이 나오네요. if ~ elif ~ else 구문입니다. 여러 가지의 경우를 비교해 보려고 할 때, 자주 사용하는 구문이고 elif는 필요한 수 만큼 나올 수 있다는 것 알아주시기 바랍니다.



반응형

댓글