Development/Tutorials/Using Qt Designer (ko)

From KDE TechBase


KDE에서의 Qt Designer 유저 인터페이스

이 튜트리얼에서는 당신의 KDE 프로젝트 안에 Qt Designer로 생성된 유저 인터페이스를 프로그램적으로 어떻게 추가하는 지에 대해 설명한다.

In this tutorial, we will explore how to programatically insert user interfaces (UIs) created with Qt Designer, into your KDE project.


UI 디자인하기

Qt Designer는 직관적인 "드래그 & 드롭" 인터페이스를 사용하여, 유저 인터페이스를 쉽게 만드는 GUI 프로그램이다. 디자이너는 훌륭한 유저 메뉴얼을 가지고 있다. 이것은 Designer를 간단한 예제를 제공하는 섬세함을 가졌지만, 이 문서는 Designer 메뉴얼에서의 대부분 내용에서 벗어날 것이다.

Qt Designer is a graphical program which allows you to easily build user interfaces, using an intuitive "drag n drop" interface. Designer has its own excellent user documentation. It might make sense to provide a brief example of using Designer here, but for now this article will leave most of that to the Designer manual itself.

당신의 KDE 프로젝트에 UI 파일 추가하기

우리의 목적을 위해, Desinger 사용에서 가장 중요한 것은 생성된 *.ui이다. 이것은 machine-readable(그리고 human-readable!)한 방법으로 유저 인터페이스가 인코딩된 간단한 XML 파일이다.

For our purposes, the most important part of using Designer is the *.ui file that it creates. This is simply an XML file that encodes the user interface in a machine-readable (and human-readable!) way.

Designer로 "MyDialog"라고 이름 붙여진 UI를 만들어서, mydialog.ui라는 파일로 저장하였다고 상상해보자. 이것을 KDE 프로젝트에 추가하기 위해서는, 간단하게 CMakeList.txt파일에 다음과 같이 명령어를 추가하라.:

Let's imagine that you've created a UI named "MyDialog" with Designer, and saved it as the file mydialog.ui. To add this UI to your KDE project, simply add a command like the following to your CMakeLists.txt file:

kde4_add_ui_files(myapp_SRCS mydialog.ui)

모든 소소 코드 파일이 정의된 CMakeList.txt 파일에서 주요 블록의 이름을 "myapp_SRCS"로 바꿔라. 이것은 일반적으로 어플리케이션의 이름에 "_SRCS"가 붙여진다.

Replace "myapp_SRCS" with the name of the main block in your CMakeLists.txt file, defining all of the source code files. It is usually the name of your application, with "_SRCS" appended.

이것을 수행할 때, 빌드시스템은 mydialog.ui로 UI를 정의한 C++ 헤더파일을 자동 생성하기 위해, Qt 프로그램 uic를 수행할 것이다. 생성된 파일은 ui_mydialog.h로 이름붙여질 것이다.

When you do this, the build system will run the Qt program uic on mydialog.ui, to auto-generate a C++ header file that defines the UI. The generated file will be named ui_mydialog.h.

당신의 코드에서 UI 사용하기

ui_mydialog.h 파일은 "Ui_MyDialog"라는 클래스를 정의하며, Designer에서 클래스의 public 멤버로 생성된 모든 위젯을 포함한다. ui_mydialog.h 파일은 "setupUi(QWidget *parent)"라는 public 함수를 포함한다. "setupUi(QWidget *parent)"함수는 Designer에서 설정한 것에 따라서 모든 위젯을 생성하고, 속성을 설정하고, layout 매니저에 이것들을 추가한다.

The ui_mydialog.h file defines a class named "Ui_MyDialog", that contains all of the widgets you created in Designer as public members of the class. It also contains the public function "setupUi(QWidget *parent)", which instantiates all of the widgets, sets up their properties, and inserts them into layout managers, all according to what you specified in Designer.


setupUi()QWidget* 인자를 받는다는 것을 상기하라. 이 인지는 당신의 UI 안에 모든 위젯이 ㅊ가될 부모 컨테이너 위젯을 표현한다. 다른 말로 말하자면, Ui_MyDialog는 자체적으로 QWidget에서 상속되지 않는다, 그리고 이것은 자체적으로 toplevel 위젯을 가지고 있지 않다.. setupUi()를 호출할 때, toplevel 위젯을 설정해주어야만 한다. 이것이 가장 중요한 점이다.

Note that setupUi() takes a QWidget* argument. This argument represents the parent container widget, into which all of the widgets in your UI will be inserted. In other words, Ui_MyDialog is not itself derived from QWidget, and it does not contain a toplevel widget itself. You have to supply the toplevel widget when you call setupUi(). This is an important point.


더 중요한 의미의 세부사항 한 가지: Ui_MyDialog 클래스는 클래스를 위해 간단한 별명을 만드는 Ui namespace를 생성한다. 그러므로 같은 클래스에서 참조하기 위해 Ui::MyDialog를 사용할 수 있다.

One more important semantic detail: the Ui_MyDialog class also creates a Ui namespace, which simply creates an alias for the class. So you can use Ui::MyDialog to refer to the same class.


이제 실질적으로 생성된 UI를 코드에서 사용한다. Qt 메뉴얼은 ui-files를 사용하는 방법의 3가지를 보여준다. 여기에서는 직접 접근(direct approach)에 대해서만 다룬다. 목표는 ui-file의 UI를 포함한 KDialog를 생성하는 것이다. 먼저 KDialog에서 MyDialog를 파생시켜야한다. 그리고 Ui::MyDialog 타입의 멤버 변수를 추가한다. 헤더파일인 "mydialog.h"파일의 모습은 다음과 같다.

Now, on to actually using the generated UI in your code. The Qt documentation shows three ways of how to use ui-files; here only the direct approach is discussed. The goal is to create a KDialog which embeds the UI from the ui-file. First, we have to subclass MyDialog from KDialog and add a member variable of type Ui::MyDialog. The header file of "mydialog.h" looks like the following:

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <KDialog>

// ui-file에서 자동적으로 생성된 헤더파일을 include한다.
#include "ui_mydialog.h"

class MyDialog : public KDialog
{
    Q_OBJECT
    public:
        MyDialog( QWidget *parent=0 );
        ~MyDialog();

    private slots:
        void slotButtonClicked();

    private:
        // ui으로의 접근자. Desinger 안에서 모든 설정된 
        // gui 요소들을 접근할 수 있다.
        // mydialog.ui가 "myButton" 버튼을 포함한다면, 
        // cpp 파일에서 ui.myButon으로 접근할 수 있다.
        Ui::MyDialog ui;
};

#endif

이제 "mydialog.cpp" 안에 있는 MyDialog의 구현을 살펴볼 것이다.

Now we are going to look at the implementation of MyDialog, which is in the file

"mydialog.cpp".

#include <KLocale>
#include <KMessageBox>

// 다이얼로그의 헤더파일 include
#include "mydialog.h"

MyDialog::MyDialog( QWidget *parent )
: KDialog( parent )
{
    QWidget *widget = new QWidget( this );

    //  유저 인터페이스를 생성한다. 부모 위젯은 "widget"이다.
    ui.setupUi(widget); // this is the important part

    // 모든 gui요소를 가진 widget을 다이얼로그의 메인 위젯으로 
    // 설정한다.
    setMainWidget( widget );

    // 다른 KDialog 옵션들
    setCaption( i18n("This is my Dialog window!") );
    setButtons( KDialog::Close );

    // UI에서 위젯들을 사용하여 시그널/슬롯 연결을 시험해본다.
    // UI 요소들을 참조할 때에는, "ui."으로 prefix해야 
    // 한다는 것을 상기하라.
    connect( ui.myButton, SIGNAL( clicked() ),
             this, SLOT( slotButtonClicked() ) );
}

MyDialog::~MyDialog()
{
}

void MyDialog::slotButtonClicked() 
{
    KMessageBox::information( this, 
                              i18n("You pressed the button!" ),
                              i18n( "Hooray!" ) );
}

#include "mydialog.moc"

기본적으로, 새로운 Ui::MyDialog를 생성하고, MyDialog의 생성자 안에서 ui.setupUi(widget)를 호출한다. 이것은 주어진 위젯 안의 Ui 요소를 배치한다. 그리고 부모 위젯을 KDialog의 메인 위젯으로 설정한다. 종종 "m_"로 prefix하는 것과 같이, "ui."를 그것들의 이름에 prefix함으로써 UI 요소의 모두와 상호작용할 수 있다.

So, basically, we create a new Ui::MyDialog and then call ui.setupUi(widget) in the constructor of MyDialog. This places the UI elements into the given widget. Then we set the parent-widget as the KDialog's main widget. We can then interact with all of the UI elements by prepending "ui." to their names, just like it is often done with the prefix "m_".

Final Thoughts

이 튜트리얼에서 처음에는 파일과 클래스들의 단계들은 위압하는 것처럼 보일지도 모른다. 그러나 여기에 준비된 naming 스키마는 좋은 직관적인 특징을 가진다.: 직접 수정되어질(텍스트 또는 Designer로) 소스코드 파일들은 같은 스키마로 모두 이름 붙여진다.:

The cascade of files and classes in this tutorial may seem daunting at first, but the naming scheme layed out here has one nice intuitive feature: the source code files that you will be editing directly (either as text or with Designer) are all named with the same scheme:

  • mydialog.ui: Designer로 만들어진 유저 인터페이스.
  • ui_mydialog.h: Qt 유저 인터페이스 컴파일러인 uic로 자동 생성된다.
  • mydialog.h/cpp: 다이얼로구 구현 파일
  • mydialog.ui: the user interface, created with Designer
  • ui_mydialog.h: auto-generated by uic, Qt's user interface compiler
  • mydialog.h/cpp: the dialog implementation

단계를 짧게 요약자면,

  1. mydialog.ui을 생성하고,
  2. mydialog.h/cpp을 생성한다.
  3. mydialog.h안에 Ui::MyDialog ui 변수를 추가한다.
  4. ui.setupUi(widget);를 호출한다.
  5. ui.로 ui 요소들을 접근한다.

The steps in short are

  1. create mydialog.ui
  2. create mydialog.h/cpp
  3. add variable Ui::MyDialog ui; in mydialog.h
  4. call ui.setupUi(widget);
  5. access the ui elements with ui.

Qt 메뉴얼

Qt 메뉴얼은 어플리케이션에서 컴포넌트 사용하기에 대한 좋은 내용을 가지고 있다.

The Qt documentation contains a good article about Using a Component in Your Application.