지난 포스팅은...
이번 시간부터는: QtDesigner로 윈도우 메모장 클론코딩
아무리 마음가는대로 튜토리얼을 짓는다지만, 이렇게 해도 되나 싶기는 합니다. 원래는 디자이너 가볍게 잡고 Qt+Matplotlib 시각화나, Qt+Pandas 스프레드시트 쪽으로 진행하고 싶었는데, 너무 밑천을 일찍 드러내는 거 아닌가 싶어 이렇게 결정하게 되었습니다. 요즘 잘 풀리는 일이 하나도 없는데 이거라도 제 마음대로 풀어가고 싶습니다. 그래도 혹시 이 튜토리얼 시리즈가 완성되기 전에 미리 방문해서 의견 주시는 분들 계시면.. 적극적으로 의견반영하고 싶습니다.
이번 포스팅부터 진행하는 시리즈는 바로 메모장!
윈도우메모장 클론코딩입니다. 입문자 입장에서 작게 시작하고 윈도우메모장을 따라하면서 아쉬운 부분 하나씩 보완한 후에, 말미에 가서는 파이썬으로 재미있는 단축문자열이나 서식, 치환 기능을 추가해볼까 합니다. 아주 재미가 있을 것 같아요~
제 실행환경은,
기존 포스팅을 쭉 따라오셨던 분들은 저와 같은 파이참(프로/커뮤니티 무관) 등의 IDE를 사용하고 계실 거고요. 저는 현재기준 파이썬 3.9.2 64비트 버전으로 프로젝트폴더 안에 가상환경(venv)을 만든 후 PySide6만 설치해둔 상태입니다. PySide6 버전은 6.0.2예요. 마이너버전이 달라도 큰 차이는 없을 것으로 생각합니다.
QtDesigner 실행하기
QtDesigner는 파이참에서 터미널 여시고(Alt-F12) "pyside6-designer" 입력후 엔터를 치시면 됩니다.
QtDesigner 프로그램이 열렸습니다.
화면 가운데에 새 폼을 선택하는 팝업이 떠 있습니다.
새 폼에서 Main Window를 더블클릭하여 열어봅시다.
이번 포스팅에서는 "메뉴바"만 완성하고 마치겠습니다. 윈도우 메모장도 옆에 같이 한 번 열어봅시다.
시작버튼을 누르고 메모장 탐색 - 엔터키로 실행
이렇게 메모장을 열어보았습니다.
각 메뉴를 하나씩 열어보겠습니다.
파일(F)
새로 만들기(&N)
새 창(&W)
열기(&O)...
저장(&S)
다른 이름으로 저장(&A)...
-
페이지 설정(&U)...
인쇄(&P)...
-
끝내기(&X)
편집(E)
실행 취소(&U)
-
잘라내기(&T)
복사(&C)
붙여넣기(&P)
삭제(&L)
-
Bing으로 검색(&S)...
찾기(&F)...
다음 찾기(&N)
이전 찾기(&V)
바꾸기(&R)...
이동(&G)...
-
모두 선택(&A)
시간/날짜(&D)
서식(O)
자동 줄 바꿈(&W)
글꼴(&F)...
보기(V)
확대하기/축소하기
확대(&I)
축소(&O)
확대하기/축소하기 기본값 복원
상태 표시줄(&S) [checkable]
도움말(H)
도움말 보기(&H)
피드백 보내기(&F)
-
메모장 정보(&A)
이렇게 캡쳐 및 타이핑해 두고 메뉴를 복붙해 넣으면 훨씬 수월합니다. (이유는 직접 해 보시면 바로 아실 거예요ㅎ)
디자이너로 돌아와서, 5개 대메뉴 완성하기
위의 메뉴만 디자이너로 그대로 옮겨와보겠습니다. 상단의 "파일" 이미지를 보면서 그대로 따라합니다. 아래 영상을 참고하여 파일, 편집, 서식, 보기 및 도움말 등 5개의 대메뉴를 완성해 주시기 바랍니다.
파일 메뉴 완성하기
또 상단의 "파일" 이미지를 보면서 그대로 하위메뉴를 작성해 주시기 바랍니다. 아래 영상을 참고하셔도 좋습니다. 현재 디자이너의 버그 때문인지, 서브메뉴에 한글입력이 되지 않습니다. 다만, 한글 붙여넣기(Ctrl-V)는 가능한데, 그 때문에 메모장이나 에디터 등에 적어두고 복붙작업을 하고 있습니다. 해결방법 아시는 분은 제발 좀 알려주세요ㅜ
또한 QtDesigner에서 Ctrl-r을 누르면 미리보기창이 열립니다. "파일"메뉴만 완성하고 나서 미리보기(Ctrl-r)를 실행해봅시다.
이렇게 편집, 서식, 보기 및 도움말까지 차근차근 완성해봅시다.
막히는 부분은 없겠지만, 약간 응용할 부분이 두 개 있는데,
1. 보기의 확대축소메뉴 생성시 하위의 하위메뉴 추가해야 함(아래 영상 참고)
2. 보기의 상태표시줄 메뉴는 속성편집기에서 checkable에 체크해야 함(아래 영상 참고)
그러면 "파일"메뉴 작성한 방식 그대로 편집~도움말까지 작성해보시기 바랍니다.
편집메뉴 완성한 모습
서식메뉴 완성한 모습
보기메뉴 완성한 모습
도움말메뉴 완성한 모습
여러분도 다 입력하셨나요? 미리보기(Ctrl-r)을 해보겠습니다.
프로젝트 루트 폴더에 notepad폴더를 만들고, notepad_mainwindow.ui로 저장해봅시다.
자, 이제 메뉴바의 틀이 완성되었습니다. 기왕 하는 거 빡세게 끊지 말고 가봅시다.
이번에는 단축키 정의하기
Alt-f,o 이런 식으로 말고, 메모장에 보면 아예 단축키가 정의된 메뉴들이 있죠.
정의하는 방법은 간단합니다. 디자이너 창에서, 메뉴를 선택한 후, 속성편집기의 shortcut에 단축키를 직접 입력하면 됩니다. 짧은 영상으로 보여드리겠습니다.
단축키를 다 정의하셨으면, 이제 원래의 메모장과 메뉴바 비교를 한 번 해보겠습니다.
QtDesigner 메모장
윈도우10 메모장
아쉽게도 QtDesigner의 단축키 문자열이 좌측정렬되어 있네요. 윈도우10 메모장의 단축키는 우측정렬 되어 있고요. 이건 디자이너에서 변경하기 어려운 부분이네요. 다음 포스팅에서 파이참으로 넘어가서 우측정렬 할 수 있는 방법을 알려드리겠습니다. (참고한 스택오버플로 게시물을 아래 남겨두니, 성미급하신 분들은 방문 바랍니다.)
단축키도 전부 입력하셨으면, 미리보기로 다시 확인해보겠습니다.
아쉬운 부분이 또 하나 나왔네요. 윈도우메모장은 "Ctrl+더하기", "Ctrl+빼기"라고 직관적인 표현을 쓴 데 반해 우리 QtDesigner메모장은 Ctrl++, Ctrl+- 이렇게 예쁘지 않은 표현을 쓰게 되었네요. 이 부분은 저도 검색해보고 알려드리겠습니다. (윈도우메모장도 뜯어보니까 소소하게 신경을 쓴 부분이 많이 보이네요ㅎ)
단축키도 다 입력했습니다. 그럼 다음 포스팅에서는 텍스트위젯을 추가한 후 이것저것 뚝딱거려봅시다.
이번 포스팅은 여기서 마칩니다. 행복한 하루 되세요!
참고한 자료
이만 줄임.
[부록] pyside-uic 관련 팁 3가지
[팁1]커맨드프롬프트에서 uic를 쓰지 않고 파이썬 코드를 확인하는 방법!
QtDesigner메뉴 중, "폼(O)-Python 코드 보기(P)..." 메뉴를 선택해봅시다.
아뿔싸, 오류팝업이 뜹니다.
조만간 조치될 내용 같지만 우리가 미리 조치해봅시다.
현재 uic.exe는 bin폴더가 아니라 상위폴더인 PySide6에 들어 있어요. PySide6 폴더에서 bin이라는 폴더를 생성하고 PySide6 폴더의 uic.exe 파일을 복사해서 bin 폴더 안에 넣으면 끝.
다시 "파이썬 코드보기"를 실행해봅시다.
상단에 아이콘 세 개는 각각 "저장", "전체복사" 및 "찾기"입니다.
커맨드프롬프트에서 uic를 굳이 해주지 않아도 파이썬 코드로 바로 추출이 가능하군요?
[팁2] ui파일을 .py로 변환하지 않고 바로 파이썬으로 불러오는 방법(PySide6)
PyQt5의 경우 uic라는 서브모듈이 있어서 uic.loadUi("mainwindow.ui") 식으로 ui파일을 불러올 수 있었습니다. 물론 PySide6에도 이에 해당하는 모듈이 있는데, 모듈명이 약간 다릅니다.
아래 코드를 참고해 주시기 바랍니다.
from PySide6.QtWidgets import QApplication
from PySide6.QtUiTools import QUiLoader
loader = QUiLoader()
app = QApplication()
window = loader.load("notepad_mainwindow.ui", parentWidget=None)
window.show()
app.exec_()
이런 식으로 불러올 수 있습니다. ui파일을 업데이트한 후에도 별도의 변환이 필요없다는 장점이 돋보입니다. 근데 문제가 하나 있어요. 이렇게만 사용하면 클래스를 상속받거나 재정의하는 방식을 사용할 수 없기 때문에 별도의 로직을 파이썬에서 추가하기가 어려워 보입니다. 기껏해야 setWindowTitle 변경하는 정도?
[번외] PyQt5에서 ui파일을 불러오는 방식은...
저는 PyQt5의 팬이었지만, 어떤 이유 때문에 PySide6로 완전히 마음을 돌렸습니다. 그래도 PyQt5에서 사용하던 방식을 적어두고 싶군요. 참고하시기 바랍니다. (사실 이렇게 배운 습관이 강하게 남아서, 아직 PySide가 불편하게 느껴집니다;)
from PyQt5 import QtWidgets
from PyQt5 import uic
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
uic.loadUi("mainwindow.ui", self)
app = QtWidgets.QApplication()
window = MainWindow()
window.show()
app.exec()
혹은,
from PyQt5 import QtWidgets
from PyQt5 import uic
form_class = uic.loadUiType("mainwindow.ui")[0]
class MainWindow(QtWidgets.QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
app = QtWidgets.QApplication()
window = MainWindow()
window.show()
app.exec()
일반적으로 이렇게 두 가지 방식으로 불러올 수 있습니다. PyQt에서는요.
[팁3] ui파일을 불러온 후 커스텀이벤트를 추가하는 방법(PySide6)
PyQt5에서는 loadUi, loadUiType 등을 통해 ui파일로도 다중상속이 가능했는데, PySide는 PyQt와는 약간 다른 철학을 가져가는 느낌입니다. 아래의 코드를 한 번 읽어주시기 바랍니다.
class Circle(QWidget):
def paintEvent(self, event):
painter = QPainter(self)
painter.setPen(self.pen)
painter.setBrush(QBrush(self.color))
painter.drawEllipse(event.rect().center(), 20, 20)
# ...
loader = QUiLoader()
loader.registerCustomWidget(Circle)
circle = loader.load('circle.ui')
circle.show()
# ...
QUiLoader.load로 ui파일을 불러오고, 별도의 이벤트 메서드는 registerCustomWidget 으로 따로 정의하는 방식입니다.
직관적이기도 하고 코드도 장황하지 않을 것 같은 좋은 느낌이네요. 저도 아직 사용해보지 않았어요;; (출처 : QUiLoader — Qt for Python)
하여튼 이렇게 다양한 방식이 있으니 이것저것 시도해보시고 가장 선호하는 방식을 찾으시면 좋겠습니다. 저는 그나마 1번이 가장 덜 생소한데, PySide6 관련 포스팅을 올리는 김에, 커스텀이벤트를 추가하는 PySide6만의 방식을 이번에 한 번 연습해보고 싶네요.
국내 유일의 파이썬+한컴오피스 업무자동화 입문강의
'GUI 튜토리얼 > PySide6 # Qt의 원조가 돌아왔다!' 카테고리의 다른 글
1. PySide6 메모장 만들기 - 위젯 추가하기 (5) | 2021.04.01 |
---|---|
1. PySide6의 QtDesigner를 사용해봅시다. (2) | 2021.03.29 |
0. PySide6의 시그널-슬롯 활용예제: 다른 위젯을 슬롯으로 연결하기 (5) | 2021.03.28 |
댓글