[Qt] GUI with Qt : QMainWindow
QMainWindow
QMainWindow
- QWidget 을 상속받은 하나의 클래스
- QWidget 을 기반으로 메뉴/상태표시줄/툴바 등 자주 쓰는 Window 형태를 미리 구현해 둔 클래스
- 라즈베리파이에서 QWidget 을 썼을 때 QtDesigner와 Python 코드가 호환 문제 (버그)가 존재하지만, QMainWindow에서는 호환이 잘 된다!!
- https://doc.qt.io/qtforpython-6/PySide6/QtWidgets/QMainWindow.html#qmainwindow
QWidget VS QMainWindow 비교
[QWidget 클래스 이용]
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.main()
def main(self):
self.setWindowTitle("Qt GUI App")
self.setGeometry(0, 0, 300, 300)
self.vlay = QVBoxLayout(self)
self.btn1 = QPushButton("Top")
self.btn2 = QPushButton("Bottom")
self.vlay.addWidget(self.btn1)
self.vlay.addWidget(self.btn2)
self.vlay = QVBoxLayout(self)
해당 객체는 self = win을 상위 객체로 두기 때문에,
해당 객체를 생성하면 win창에 바로 나타나게 된다.
class MyApp(QWidget): → class MyApp(QMainWindow):
하지만, 다음과 같이 QMainWindow를 상속받도록 하면 win창에 아무것도 나타나지 않는다.
그 이유는 QMainWindow가 다음과 같은 구조로 이루어져 있기 때문이다.
따라서, QMainWindow를 사용할 때는 setCentralWidget() 메서드를 사용하여 각각에 대한 위젯을 설정해주어야 한다.
[QMainWindow 이용]
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
self.main()
def main(self):
self.setWindowTitle("Qt GUI App")
self.setGeometry(0, 0, 300, 300)
self.vlay = QVBoxLayout()
self.btn1 = QPushButton("Top")
self.btn2 = QPushButton("Bottom")
self.vlay.addWidget(self.btn1)
self.vlay.addWidget(self.btn2)
mainWidget = QWidget()
mainWidget.setLayout(self.vlay)
self.setCentralWidget(mainWidget)
위와 같이, QMainWindow의 CentralWidget 으로 mainWidget을 등록해줌으로써
버튼이 win창에 뜨도록 하였다.
(setCentralWidget()으로는 layout등록이 불가하기 때문에 별도로 mainWidget()을 만들어 등록한 것을 알 수 있다.)
QMainWindow - Central Widget 설정
#QMainWindow 사용하기
#QMainWidnow 는 CentralWidget 영역에 Widget을 배치해야 한다.
#여러 개의 Widget을 배치하기 위해 레이아웃을 이용해 Design 후, CentralWidget 에 레이아웃을 등록한다.
from PySide6.QtWidgets import *
#QMainWindow class 를 상속받은 MyApp Class
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
self.main()
def main(self):
self.setWindowTitle("Qt GUI App")
self.setGeometry(0, 0, 300, 300)
self.vlay = QVBoxLayout()
self.btn1 = QPushButton("Top")
self.btn2 = QPushButton("Bottom")
self.vlay.addWidget(self.btn1)
self.vlay.addWidget(self.btn2)
#QWidget() 객체 생성
mainWidget = QWidget()
#Qwidget 객체에 수평배치 레이아웃을 등록한다.
mainWidget.setLayout(self.vlay)
#QMainWindow의 CentralWidget 으로 mainWidget을 등록한다.
#CentralWidget은 1개의 Widget만 등록이 가능하다.
self.setCentralWidget(mainWidget)
if __name__ == '__main__':
app = QApplication()
win = MyApp()
win.show()
app.exec()copy
▶ App에 위젯 등록하기
setCentralWidget(QWidget 객체)
- QMainWindow의 CentralWidget 으로 mainWidget을 등록한다.
- CentralWidget은 1개의 Widget만 등록이 가능하다.
- QWidget() 인스턴스만 등록 가능하다.
QMainWindow - Status Bar 설정
#QMainWindow 의 StatusBar 사용하기
#QMainWindow 에는 StatusBar 를 다루기 위한 메서드들이 정의되어 있다.
#StatusBar() : statusBar 객체 생성
#.showMessage() : statusBar에 메시지를 출력한다.
from PySide6.QtWidgets import *
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
self.main()
def main(self):
self.setWindowTitle("Qt GUI App")
self.setGeometry(0, 0, 300, 300)
self.vlay = QVBoxLayout()
self.btn1 = QPushButton("Top")
self.btn2 = QPushButton("Bottom")
self.vlay.addWidget(self.btn1)
self.vlay.addWidget(self.btn2)
mainWidget = QWidget()
mainWidget.setLayout(self.vlay)
self.setCentralWidget(mainWidget)
#statusBar() 객체 생성
self.bar = self.statusBar()
#statusBar에 메시지 출력
self.bar.showMessage("BBQ")
if __name__ == '__main__':
app = QApplication()
win = MyApp()
win.show()
app.exec()
▶ statusBar 객체 생성
statusBar()
▶ statusBar에 메시지 출력
Bar객체.showMessage("text")
Menu Bar & QAction
# QMainWindow 의 Menu Bar 사용하기
# Menu Bar를 생성하고, QAction을 등록한다.
# QAction은 slot 함수를 등록해, User가 원하는 동작을 수행할 수 있다.
# QAciont은 단축키를 등록해 쉽게 조작이 가능하다.
from PySide6.QtWidgets import *
from PySide6.QtGui import *
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
self.main()
def main(self):
self.setWindowTitle("Qt GUI App")
self.setGeometry(0, 0, 300, 300)
self.vlay = QVBoxLayout()
self.lbl = QLabel("KFC")
self.btn = QPushButton("클릭")
self.btn.clicked.connect(self.click)
self.vlay.addWidget(self.lbl)
self.vlay.addWidget(self.btn)
mainWidget = QWidget()
mainWidget.setLayout(self.vlay)
self.setCentralWidget(mainWidget)
# menuBar객체 menu 생성, menuBar() 는 QMainWindow 에 멤버함수
self.menu = self.menuBar()
# menuBar 에 File 메뉴 추가, &를 붙이면 단축키 사용이 가능하다. Alt+F
self.menuFile = self.menu.addMenu("&File")
# menuBar 에 Edit 메뉴 추가, &를 붙이면 단축키 사용이 가능하다. Alt+E
self.menuEdit = self.menu.addMenu("&Edit")
# QAction() 객체 생성, 단축키 사용
self.openAction = QAction("&Open", self)
# openAction 과 open() 를 연결, Open 메뉴 클릭 시, open() 호출
self.openAction.triggered.connect(self.open)
# 키보드 단축키 추가, Ctrl+O 누르면 Open 메뉴 선택
self.openAction.setShortcut(QKeySequence("Ctrl+O"))
# menuFile 에 openAction 객체 등록, File 메뉴 클릭 시, Open 메뉴 창이 나타난다.
self.menuFile.addAction(self.openAction)
def open(self):
self.lbl.setText("Open 선택")
def click(self):
self.lbl.setText("클릭")
if __name__ == '__main__':
app = QApplication()
win = MyApp()
win.show()
app.exec()
⭐&뒤에는 상태바, 메뉴의 이름이 들어간다!
이때, 단순히 이름만 작성하지 않고 &을 붙이면 단축키가 설정된다.
따라서 위와 같이 코드를 작성한 뒤,alt + F 를 누르면 "File" 상태바가 트리거 되고,alt + E 를 누르면 "Edit" 상태바가 트리거 된다.
■ menuBar 생성
# menuBar객체 menu 생성, menuBar() 는 QMainWindow 에 멤버함수
self.menu = self.menuBar()
# menuBar 에 File 메뉴 추가, &를 붙이면 단축키 사용이 가능하다. Alt+F
self.menuFile = self.menu.addMenu("&File")
# menuBar 에 Edit 메뉴 추가, &를 붙이면 단축키 사용이 가능하다. Alt+E
self.menuEdit = self.menu.addMenu("&Edit")
```
QAction 객체 생성
```
# menuFile 에 openAction 객체 등록, File 메뉴 클릭 시, Open 메뉴 창이 나타난다.
self.menuFile.addAction(self.openAction)copy
▶ 메뉴바 객체 생성
menuBar()
▶ 메뉴바 객체에 메뉴 등록
Bar객체.addMenu("메뉴이름")
▶ 메뉴에 Action 등록
Bar객체.addAction()(QAction객체)
■ QAction 생성
# QAction() 객체 생성, 단축키 사용
self.openAction = QAction("&Open", self)
# openAction 과 open() 를 연결, Open 메뉴 클릭 시, open() 호출
self.openAction.triggered.connect(self.open)
# 키보드 단축키 추가, Ctrl+O 누르면 Open 메뉴 선택
self.openAction.setShortcut(QKeySequence("Ctrl+O"))
# menuFile 에 openAction 객체 등록, File 메뉴 클릭 시, Open 메뉴 창이 나타난다.
self.menuFile.addAction(self.openAction)
def open(self):
self.lbl.setText("Open 선택")
def click(self):
self.lbl.setText("클릭")copy
▶ 🚨QtGui 패키지 import 해야 한다.
from PySide6.QtGui import *
▶ QAction 객체 생성
QAction()
▶ 동작 함수 등록
QAction객체.triggered.connect(연결함수)
▶ 단축키 등록
QAction객체.setShortcut(QkeySequence("단축키"))
💡 [참고] Modal vs Modaless
- Modal 창
- 최상위 창만 사용 가능 ( 하위 창 제어 불가 )
- exec() 사용
- ex) 메모장의 저장 창을 띄우면, 메모창 글씨를 수정 불가
- Modaless 창
- 모든 창 사용 가능
- show() 사용
- ex) 메모장의 바꾸기 창은 하위 창 글씨를 수정할 수 있다