Part I: Basic Qt – Ch01. Laying Out Widgets 본문

Programming/C++/Qt

Part I: Basic Qt – Ch01. Laying Out Widgets

halatha 2008. 7. 31. 11:51

Laying Out Widgets

In this section, we will create a small example application that demonstrates how to use layouts to manage the geometry of widgets in a window and how to use signals and slots to synchronize two widgets. The application asks for the user's age, which the user can enter by manipulating either a spin box or a slider.

부분에서, 우리는 윈도우에서 위젯의 위치 구조를 관리할 레이아웃을 어떻게 사용하고 개의 위젯을 동기화시키기 위해 시그널과 슬롯을 어떻게 이용하는지 보여줄 작은 예제 어플리케이션을 만들 것이다. 어플리케이션은 사용자의 나이를 요구하는데, 사용자는 스핀 박스나 슬라이더를 조작해 입력을 있다.

The application consists of three widgets: a QSpinBox, a QSlider, and a QWidget. The QWidget is the application's main window. The QSpinBox and the QSlider are rendered inside the QWidget; they are children of the QWidget. Alternatively, we can say that the QWidget is the parent of the QSpinBox and the QSlider. The QWidget has no parent itself because it is being used as a top-level window. The constructors for QWidget and all of its subclasses take a QWidget * parameter that specifies the parent widget.

어플리케이션은 개의 위젯으로 구성된다: QSpinBox, QSlider QWidget. QWidget 어플리케이션의 윈도우이다. QSpinBox QSlider QWidget 내부에 있게된다; 그것들은 QWidget 자식들이다. 달리 말해, 우리는 QWidget QSpinBox QSlider 부모라고 말할 있다. QWidget 최고 계층 윈도우로서 이용되기 때문에 자신의 부모는 갖지 않는다. QWidget 구성과 서브 클래스들은 부모 위젯을 표현하는 QWidget * 인자를 취한다.

Figure 1.4. The Age application

사용자 삽입 이미지
Here's the source code:

여기 소스코드가 있다:

 1 #include <QApplication>
 2 #include <QHBoxLayout>
 3 #include <QSlider>
 4 #include <QSpinBox>
 5 int main(int argc, char *argv[])
 6 {
 7     QApplication app(argc, argv);
 8     QWidget *window = new QWidget;
 9     window->setWindowTitle("Enter Your Age");
10     QSpinBox *spinBox = new QSpinBox;
11     QSlider *slider = new QSlider(Qt::Horizontal);
12     spinBox->setRange(0, 130);
13     slider->setRange(0, 130);
14     QObject::connect(spinBox, SIGNAL(valueChanged(int)),
15                      slider, SLOT(setValue(int)));
16     QObject::connect(slider, SIGNAL(valueChanged(int)),
17                      spinBox, SLOT(setValue(int)));
18     spinBox->setValue(35);
19     QHBoxLayout *layout = new QHBoxLayout;
20     layout->addWidget(spinBox);
21     layout->addWidget(slider);
22     window->setLayout(layout);
23     window->show();
24     return app.exec();
25 }

 

Lines 8 and 9 set up the QWidget that will serve as the application's main window. We call setWindowTitle() to set the text displayed in the window's title bar.

8 9행은 어플리케이션의 윈도우로서 동작하는 QWidget 설정한다. 우리는 윈도우 타이틀 바에 출력되는 문자를 설정하기 위해 setWindowTitle() 호출한다.

Lines 10 and 11 create a QSpinBox and a QSlider, and lines 12 and 13 set their valid ranges. We can safely assume that the user is at most 130 years old. We could pass window to the QSpinBox and QSlider constructors, specifying that these widgets should have window as their parent, but it isn't necessary here because the layout system will figure this out by itself and automatically set the parent of the spin box and the slider, as we will see shortly.

10, 11행은 QSpinBox QSlider 생성하고, 12, 13행은 유효한 범위를 설정한다. 우리는 사용자가 기껏해야 130살이라고 가정할 있다. 우리는, 위젯들이 window 부모로서 가져야 한다고 표시하기 위해, window QSpinBox QSlider 구성에 넘겨줄 있지만, 우리가 것처럼, 레이아웃 시스템은 스스로 이것을 알아내고 자동으로 스핀 박스와 슬라이더의 부모를 설정할 것이기 때문에 여기서 필요는 없다.

The two QObject::connect() calls shown in lines 14 to 17 ensure that the spin box and the slider are synchronized so that they always show the same value. Whenever the value of one widget changes, its valueChanged(int) signal is emitted, and the setValue(int) slot of the other widget is called with the new value.

14~17행에 있는 개의 QObject::connect() 호출은 스핀 박스와 슬라이더가 동기화되어 항상 같은 값을 나타내는 것을 확실하게 한다. 하나의 위젯의 값이 변할 때마다, 그것의 valueChanged(int) 시그널이 나오고, 다른 위젯의 setValue(int) 슬롯이 새로운 값과 함께 호출된다.

Line 18 sets the spin box value to 35. When this happens, the QSpinBox emits the valueChanged(int) signal with an int argument of 35. This argument is passed to the QSlider's setValue(int) slot, which sets the slider value to 35. The slider then emits the valueChanged(int) signal, because its own value changed, triggering the spin box's setValue(int) slot. But at this point, setValue(int) doesn't emit any signal, since the spin box value is already 35. This prevents infinite recursion. Figure 1.5 summarizes the situation.

18행은 스핀 박스의 값을 35 설정한다. 이것이 발생할 , QSpinBox valueChanged(int) 시그널을 int 인자 35 함께 내보낸다. 인자는 QSlider setValue(int) 슬롯에게 건내지고, 슬라이더 값을 35 설정한다. 슬라이더는 다음에 valueChanged(int) 스핀 박스의 setValue(int) 슬롯을 발생시키는 시그널을 내보낸다, 왜냐하면 자신의 값이 바뀌었기 때문이다. 그러나 시점에서, setValue(int) 어떤 시그널도 내보내지 않는다, 왜냐하면 스핀 박스의 값은 이미 35이기 때문이다. 이것은 무한 재귀를 막는다. 그림 1.5 현상이 요약되어 있다.

Figure 1.5. Changing one widget's value changes both

사용자 삽입 이미지
In lines 19 to 22, we lay out the spin box and slider widgets using a layout manager. A layout manager is an object that sets the size and position of the widgets that lie under its responsibility. Qt has three main layout manager classes:

19~22행에서, 우리는 스핀 박스와 슬라이더 위젯들을 레이아웃 관리자를 이용해 위치시킨다. 레이아웃 관리자는 자신이 담당한 위젯의 크기와 위치를 설정하는 개체이다. Qt 개의 주요한 레이아웃 관리자 클래스들을 갖는다:

The call to QWidget::setLayout() on line 22 installs the layout manager on the window. Behind the scenes, the QSpinBox and QSlider are "reparented" to be children of the widget on which the layout is installed, and for this reason we don't need to specify an explicit parent when we construct a widget that will be put in a layout.

QWidget::setLayout() 22행에서 호출하는 것은 윈도우에 레이아웃 관리자를 설치한다. 뒤에서는, QSpinBox QSlider 레이아웃이 설치된 위젯의 자식이 되도록 "나타내는" 것이고, 이런 이유로 레이아웃에 놓이는 위젯을 구성할 명시적인 부모를 표시할 필요가 없다.

Figure 1.6. The Age application's widgets

사용자 삽입 이미지
Even though we didn't set the position or size of any widget explicitly, the QSpinBox and QSlider appear nicely laid out side by side. This is because QHBox-Layout automatically assigns reasonable positions and sizes to the widgets for which it is responsible, based on their needs. The layout managers free us from the chore of hard-coding screen positions in our applications and ensure that windows resize smoothly.

비록 우리가 어떤 위젯의 크기나 위치를 명시적으로 설정하지 않아도, QSpinBox QSlider 나란히 놓여서 표현된다. 이것은 QHBox-Layout, 필요에 따라, 자동으로 그것이 담당하는 위젯들에게 적절한 위치와 크기를 할당하기 때문이다. 레이아웃 관리자는 우리의 어플리케이션에 힘들게 스크린의 위치를 코딩하는 잡일로부터 우리를 자유롭게 하고 윈도우의 크기 변경을 부드럽게 한다.

Qt's approach to building user interfaces is simple to understand and very flexible. The most common pattern that Qt programmers use is to instantiate the required widgets and then set their properties as necessary. Programmers add the widgets to layouts, which automatically take care of sizing and positioning. User interface behavior is managed by connecting widgets together using Qt's signals and slots mechanism.

Qt 유저 인터페이스를 만드는 접근 방법은 이해하기 쉽고 매우 유연하다. Qt 프로그래머들이 사용하는 가장 공통적인 패턴은 필요한 위젯들을 나타내고 다음에 필요에 따라 그것들의 특성을 설정하는 것이다. 프로그래머들은 위젯을, 자동적으로 크기와 위치를 관리하는, 레이아웃에 더한다. 유저 인터페이스 동작은 Qt 시그널과 슬롯 동작 장치를 사용해 함께 위젯들을 연결하는 것에 의해 관리된다.

Comments