QWidget
기본 개념
QWidget 모든 위젯의 기반 클래스이다. QWidget은 가장 기본적인 Draw와 이벤트 처리 기능만 제공하기에 이를 상속받아 필요한 추가 기능들을 구현해놓은 클래스들이 존재한다.
보편적으로는 데스크톱 프로그램을 제작할 때 메인 프레임은 QWidget을 상속받은 QMainWindow를 기본으로 사용하고, 실제 UI 컨텐츠를 표시하기 위해서 QWidget을 central widget으로 사용한다. 그리고 QDialog는 팝업창처럼 사용되며 이는 수락, 거부 등의 버튼과 잘 작동하도록 하는 기능이 존재한다.
또한 QWidget이 직접적인 기능을 제공 하지 않은 추가적인 예는 QWidget에 글꼴 속성이 존재하지만, 직접 사용하지 않고 QLabel, QPushButton, QTabWidget과 같이 실제 UI 기능을 제공하는 하위 클래스가 많이 존재하는 형식이다.
만약 QWidget만으로 QMainWindow처럼 메뉴바나 툴바를 구성하고 싶다면 가능은 하지만, 수동으로 레이아웃을 설정해주어야 하기 때문에 불편한 점이 존재한다.
모든 위젯은 직사각형이며 z-order로 정렬된다. 위젯은 부모 위젯과 그 앞에 있는 위젯에 의해 클리핑된다. 부모 위젯에 포함되지 않은 위젯을 창(window)라고 한다. (부모가 없는 위젯을 창이라고 한다). 일반적으로 창에는 프레임과 제목 표시줄이 있지만, 적절한 window 플래그를 사용하여 이러한 장식 없이 창을 만들 수도 있다. QT에서는 QMainWindow와 QDialog의 다양한 서브클래스가 가장 일반적인 창의 유형이다.
생성자
모든 위젯의 생성자는 하나 또는 두 개의 표준 매개변수를 받는다.
explicit QWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
`QWidget *parent = nullptr`은 위젯의 부모를 지정하는 것이다. 기본값인 nullptr로 두면 새 위젯은 창(top-level window)이 되고, 그렇지 않다면 특정 위젯을 부모로 둔 자식이 된다. 이는 부모의 Geometry에 의해 제약을 받는데, 두 번째 매개 변수에 `Qt::Window`로 창 플래그로 지정한다면 부모의 Geometry에 제약받지 않을 수 있다. 즉, 부모에 종속은 되어있지만 GUI 계층 구조상 별도의 top-level-window로 취급된다.
Top-Level and Child Widgets
부모 위젯이 없는 Widget은 언제나 독립적인 창이며 이를 top-level widget이라 한다. 이러한 위젯의 경우, setWinodwTitle()과 setWindowIcon()은 각각 제목바와 아이콘을 설정한다.
창이 아닌 위젯은 부모 위젯 내부에서 표시되는 자식 위젯이다. Qt의 대부분 위젯은 주로 자식 위젯으로 유용하게 사용된다.에를 들어, 버튼을 top-level window로 표시할 수 있긴 하지만, 대부분의 사람들은 QDialog의 형태처럼 다른 위젯 안에 버튼을 배치하는 것을 선호할 것이다.

위 그림은 다양한 QGridLayout에서 제공하는 레이아웃에서 다양한 자식 위젯들을 보유하는데 사용되는 QGroupBox 위젯을 보여준다. QLabel 자식 위젯은 전체크기를 나타내기 위해 윤곽선을 그려 다이어그램에 표시해놓았다.
QWidget을 사용하여 자식 위젯을 보유하려면 일반적으로 부모 QWidget에 레이아웃을 추가해야 한다.
Layout Management
Qt 레이아웃 시스템은 위젯 내에서 자식 위젯을 자동으로 정렬하여 사용 가능한 공간을 잘 활용할 수 있도록 방법을 제공한다.
Qt는 레이아웃 관리를 위한 클래스의 집합을 포함한다. 해당 클래스들은 어플리케이션의 UI에서 위젯을 배치하는 방법을 설명한다. 이러한 레이아웃들은 사용 가능한 공간이 변경되면 위젯을 자동으로 배치하고 크기를 조정하여 UI를 일관되게 계속 사용할 수 있도록 도와준다.
모든 QWidget 서브클래스들은 레이아웃을 사용하여 자식들을 관리할 수 있다. QWidget::setLayout() 함수는 위젯에 레이아웃을 적용한다. 이런 식으로 위젯에 레이아웃이 적용되면 다음 작업을 담당한다:
- 자식 위젯들의 위치 지정
- 창에 적합한 기본 크기
- 창에 적합한 최소 크기
- 크기 조정 처리
- 콘텐츠 변경 시 자동 업데이트
- 자식 위젯의 글꼴 크기 텍스트 또는 다른 기타 컨텐츠
- 자식 위젯 숨기기 또는 표시하기
- 자식 위젯 제
Qt의 레이아웃 클래스는 C++ 코드를 위해 설계되어 측정값을 픽셀 단위로 지정할 수 있어 쉽게 이해하고 사용할 수 있다. Qt 위젯 디자이너를 사용하여 생성된 form에 대해 생성된 코드도 레이아웃 클래스를 사용한다. 일반적으로 UI 개발에 수반되는 컴파일, 링크, 실행 사이클을 피할 수 있어서 Qt 위젯 디자이너는 폼 디자인을 실험할 때 유용하게 사용할 수 있다.
Qt의 레이아웃 클래스 종류는 다음 링크에서 확인 가능하다:
https://doc.qt.io/qt-6/layout.html#qt-s-layout-classes
Centeral Widget
QMainWindow에서는 어플리케이션의 UI를 제작하기 위한 프레임워크를 제공한다. Qt는 QMainWindow와 메인 창을 관리하기 위한 연관된 클래스를 가지고 있다. QMainWindow는 자체 레이아웃을 가지고 있으며, 이 레이아웃에 QToolBar, QDockWidget, QMenuBar, QStatusBar를 추가할 수 있다.

중앙 위젯(Central Widget)이라는 용어는 QMainWindow에서 나온 용어이며, 메뉴바나 상태바 등을 제외하고 실제 UI가 렌더링 되는 위젯을 의미한다. 중앙 위젯과 비중앙 위젯 간에 동작의 차이가 있지는 않다.
참고 자료
- https://www.reddit.com/r/Qt5/comments/8z3fnz/qmainwindow_vs_qwidget_vs_qdialog/
- https://stackoverflow.com/questions/3298792/whats-the-difference-between-qmainwindow-qwidget-and-qdialog
- https://www.reddit.com/r/QtFramework/comments/15khud3/when_use_qwidget_and_when_use_qmainwindow/
- https://stackoverflow.com/questions/54749161/what-is-the-rule-for-choosing-central-widget-in-qmainwindow-and-why-is-it-imp
- https://doc.qt.io/qt-6/qmainwindow.html