Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

C++ GUI 라이브러리 소개: Qt & Nana

2017 여름 프로그 세미나

  • Als Erste(r) kommentieren

C++ GUI 라이브러리 소개: Qt & Nana

  1. 1. A Brief Overview of C++ Cross-Platform GUI Libaries: Qt and Nana 2017 Summer PROG Seminar KNU School of Computer Science and Engineering http://cafe.daum.net/knuprog
  2. 2. 순서 • 서론 • 개요 • 한계 • GUI 프로그램의 특징 • 라이브러리(소개, 설치 과정, 특징, 레이아웃, 문제점) • Qt • Nana • 종합 • 공통점 • 차이점
  3. 3. 개요 • C/C++은 강력한 언어이나, 다양한 플랫폼 위에서 작동하는 GUI 툴킷이 표준 라이브러리에 없음 • 다른 언어로 작성한 GUI 모듈을 C/C++ 핵심 모듈와 연결하는 것(binding)은 까다로움 • WinAPI나 MFC 같은 구형 라이브러리를 대체할 수 있을 만한 GUI 라이브러리가 필요함 • 따라서 open source로 공개된 C++ cross- platform GUI toolkit 라이브러리 두 가지를 알아보고, 용도에 맞게 활용하고자 함
  4. 4. 한계 • 시간 관계상, 많은 라이브러리를 다루지 못함 • 최근까지 commit이 활발하고, 서로 비교하기 쉬운 라이브러리 두 개를 다룸 • Cross-platform이지만, Windows 10과 Visual Studio 2015 Community 기준으로만 진행함 • 최신 버전인 VS2017은 라이브러리 x86 build 결과물이 compile error를 유발하는 치명적인 버그가 있어서 쓰지 않았음 • VS2010 같은 구 버전은 최신 C++ 표준을 제대로 구현하지 못하므로, 최소 VS2015를 권장함
  5. 5. GUI 프로그램의 특징 • 이벤트 주도 프로그래밍(event-driven program- ming)으로 개발된다. • 외부와 비동기적인 입출력(asynchronous I/O)이 이루어지는 대화형(interactive) 프로그램에 쓰인다. • 이벤트 주도 프로그래밍의 구성 요소로는 event, event loop, event handler가 있다.
  6. 6. GUI 프로그램의 특징 • Event: 프로그램에 의해 감지·처리되는 동작이나 사건 • Event loop: 계속 대기하는 루틴으로, event를 수집하고 event handler로 보냄 • Event handler(listener): 특정 event를 받아 처리하는 역할을 하는 함수 GUI Components, Keyboard, Mouse or etc. Event Handler Event Event Event Loop
  7. 7. Qt에 대한 간략한 소개 • The Qt Company에서 개발하는, C++ 기반의 open source cross-platform 프레임워크이다. • 방대한 라이브러리와 통합 개발 환경(IDE)을 포함한 거대한 프레임워크이다. • 라이브러리에는 GUI뿐만 아니라, network, web view, SQL DB, serial port, XML/JSON parser 등이 있다. • 오랜 역사와 많은 사용자 덕분에, 정보를 얻기 쉽다.
  8. 8. Qt에 대한 간략한 소개 • 모듈(GUI 포함)의 추상화가 잘 되어 있어, 상당히 많은 플랫폼을 타깃으로 개발할 수 있다. • Windows 10/8/7 • Linux(X11) • macOS • Embedded Linux • Windows Store App (UWP), Windows RT, etc. • Android API Level 16 • 이외에도 비공식적으로 지원하는 여러 플랫폼 • PyQt(Python porting) 등 다른 언어와도 붙여 쓸 수 있다.
  9. 9. Qt에 대한 간략한 소개 • Qt Designer를 통해, 데스크탑 UI를 WYSIWYG(What You See Is What You Get) 방식으로 빠르게 만들 수 있다. • Qt Creator라는 자체 통합 개발 환경(IDE)과 연동된다. • 참고로 이 IDE에서는 MinGW로 개발하는 게 정신건강에 이롭다. XML 파일로 저장되어, 나중에 C++ 클래스 객체로 변환된다.
  10. 10. Qt에 대한 간략한 소개 • 오픈 소스(Open source) 라이선스와 상용(Commerical) 라이선스로 나뉜다. • GPL v2/v3는 같이 사용된 모든 소스 코드를 공개(또는 그러한 수준의 방식)해야 한다(open source). • LGPL v3는 동적 링크 라이브러리(DLL) 방식 등의 특정 조건을 따르면 소스 코드를 공개하지 않아도 된다(closed source). • Qt의 상용 라이선스는 일정 금액을 지불하고 자유로이 쓸 수 있다. 데스크탑/모바일 개발의 경우 개발자 수(seat)와 기간에 따라서, 임베디드 기기의 경우 기기 running 로열티까지 합쳐 부과된다.
  11. 11. Qt의 GUI 관련 모듈 • Qt Core: 모든 Qt 애플리케이션에 기본으로 포함된다. • 각종 컨테이너와 순회자(iterator) 구현을 포함한다. • Qt Widgets: C++ 기반의 GUI 클래스 모음이며, UI 요소들로 데스크탑 프로그램을 만드는 데 쓰인다. • Native한 GUI를 C++ 코드로 구성할 수 있다. • 앞으로 비중 있게 다룰 모듈이다. • Qt WebEngine: Google Chrominum 프로젝트의 일부로서, 웹 코드를 구현한다. • HTML5/CSS/JavaScript를 이용한 애플리케이션 UI 개발을 지원한다.
  12. 12. Qt의 GUI 관련 모듈 • Qt QML: Qt Quick 모듈에서 사용하는 언어 (Qt Quick Markup Language) 모듈이다. • Qt WebEngine에 포함된 JavaScript 엔진인 V8을 사용하며, OpenGL, Vulkan 등을 renderer로 쓴다. • QML에 JavaScript를 활용하여, 생산성이 상당히 높고, 미려한 반응형 UI를 구성하기 용이하다. • JavaScript 기반이므로, 메모리 자원을 많이 소비하고, 로딩 시간을 지체하는 등, 성능이 꽤 떨어진다. 특히 debug할 때 속이 터질 수도 있다. • C++로 개발되어, C++ 코드와의 binding을 지원한다. • QML은 많이 쓰이지만, C++와 많이 동떨어져 있다.
  13. 13. Qt를 활용하는 기업들 • LG전자: 스마트 TV에 들어가는 리눅스 기반 자체 OS인 webOS에 Qt WebEngine을 활용한다. • Medec: 40년 이상의 마취학 솔루션 워크스테이션 개발 업체로서, Qt QML을 이용하여 S/W를 개발한다. https://youtu.be/f7en65HkjeQ
  14. 14. Qt를 활용하는 기업들 • AMD: 그래픽카드 설정 및 게임 영상 녹화 S/W인 Radeon Software에 Qt QML로 UI를 제공한다. • 블리자드 엔터테인먼트: 블리자드의 PC 게임에 대한 설치·실행·업데이트를 수행하는 블리자드 앱(Battle.net 앱)에 Qt QML과 Qt WebEngine을 사용한다. https://youtu.be/CdvZeQfhWXo
  15. 15. VS2015에 Qt 설치하기 1. Qt open source 다운로드 페이지 (www.qt.io/download-open-source)에서 Qt Offline Installers를 Windows로 고른다. 이 작은 곳을 클릭한다!
  16. 16. VS2015에 Qt 설치하기 2. 일본(JP)의 대학 사이트 링크에서 다운로드한다. (원래는 스웨덴의 대학 사이트가 기본으로 잡힌다!)
  17. 17. VS2015에 Qt 설치하기 3. 다운로드가 끝나면, 설치 파일을 실행한다. (2.28GB)
  18. 18. VS2015에 Qt 설치하기 4. 설치 프로그램에서 component로 ‘msvc2015 32-bit’와 ‘msvc2015 64-bit’를 선택한다. x86(32-bit)으로만 build할 계획이라면, 64-bit는 필요 없다.
  19. 19. VS2015에 Qt 설치하기 5. Visual Studio 2015 Community를 실행하여, ‘도구’ - ‘확장 및 업데이트’ 메뉴로 들어간다.
  20. 20. VS2015에 Qt 설치하기 6. 왼쪽 패널에서 ‘온라인’을 선택하고, 오른쪽 위에 있는 검색 창에 ‘Qt’를 입력하고 엔터를 누른다. 검색 결과에 있는 ‘Qt Visual Studio Tools’를 다운로드한다.
  21. 21. VS2015에 Qt 설치하기 7. 확장 기능의 설치가 끝나면, VS2015가 재시작된다. 디렉터리 설정을 위해, ‘Qt VS Tools’ - ‘Qt Options’ 메뉴로 들어간다.
  22. 22. VS2015에 Qt 설치하기 8. Qt Options 창에서 [Add]를 눌러 ‘Path’에 ‘(Qt 폴더)Qt(버전)(버전)msvc2015(_64)’를 추가한다. 64비트 버전이 있다면, 똑같이 반복한다. 폴더를 선택하면, 이름은 자동으로 입력된다.
  23. 23. VS2015에 Qt 설치하기 9. Visual Studio 2015 Community에서 [새 프로젝트]를 누르고 ‘Visual C++’ - ‘Qt’ - ‘Qt GUI Application’을 선택한다.
  24. 24. VS2015에 Qt 설치하기 10. Qt GUI Application Wizard에서 원하는 Qt 모듈을 선택한다. 여기서는 그냥 [Next]를 누르면 된다.
  25. 25. VS2015에 Qt 설치하기 11. 자동 생성되는 클래스 이름은 물론, 헤더 파일(.h)과 소스 파일(.cpp) 등의 이름까지 설정할 수 있다. 설정 후 [Finish]를 누르면 된다.
  26. 26. VS2015에 Qt 설치하기 12. main.cpp만으로, 간단한 예제 코드를 컴파일한다. (이벤트를 발생시키려면, 좀 더 긴 코드가 필요하다.) 이 코드로 컴파일한 파일은 아직 실행할 수가 없다! #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QLabel> int main(int argc, char* argv[]) { QApplication app(argc, argv); QMainWindow mainWin; auto lab = new QLabel("Hello, <b>Qt</b>!", &mainWin); mainWin.resize(160, 30); mainWin.show(); return app.exec(); }
  27. 27. VS2015에 Qt 설치하기 13. Qt의 특정 DLL 파일을 복사하면, release 파일이나 debug 파일을 실행할 수 있다.(dynamic build) 아래 DLL 파일들을 ‘(Qt 폴더)Qt(버전)(버전) msvc2015(_64)’에서 ‘(솔루션 폴더)Win32(|x64) Release(|Debug)’로 복사해야 한다. (‘(d)’가 붙는 것은 debug 전용 DLL 파일) • pluginsplatformsqwindows(d).dll → (실행 파일 폴더)platforms • binQt5Core(d).dll; binQt5Gui(d).dll; binQt5Widgets(d).dll → (실행 파일 폴더)
  28. 28. VS2015에 Qt 설치하기 아래 release 전용 DLL 파일들을 합치면, 14.5 MB에 육박하지만, 정작 실행 파일은 27 KB밖에 되지 않는다.
  29. 29. Qt Widgets의 자세한 특징 • The meta-object system을 통해 widget들을 관리한다. • Meta-object는 부가적인 데이터(meta data)를 담은 객체이다. • QObject에 대한 subclass(derived class)의 instance는 신호를 주고 받고, 자동으로 파괴된다. • RTTI(RunTime Type Indentification: 런타임 타입 식별)가 가능하다. 즉 런타임에도 해당 클래스의 정보를 관리한다. • MOC(Meta-Object Compiler)를 사용하여, 소스 코드로부터 컴파일 타임에 객체들의 정보를 읽어들인다. • Signals and slots mechanism이 작동하도록 한다.
  30. 30. Qt Widgets의 자세한 특징 • Signals and slots을 활용하여 event와 event handler를 구현한다. • The meta-object system에 의해 widget의 signal들과 slot들이 관리된다. • 특정 signal을 보내면(emit), slot으로 지정된 함수가 호출된다. • Signal을 보낸 객체와 slot이 호출된 객체는 단방향 통신을 하게 된다. (call-back이 아님)
  31. 31. Qt Widgets의 자세한 특징 • QObject::connect()를 통해 signal과 slot을 연결한다. • 예전 방식은 MOC를 통해 signal과 slot의 이름을 문자열로 변환하여 런타임에 비교하는 과정을 거친다. • 새로운 방식은 slot이 아닌 함수는 물론이고, 각종 함수자 (functor)와 람다 표현식(lambda expression)을 사용할 수 있어, 직관적이고 편리하다. // 예전 방식(문자열 변환) connect(but, SIGNAL(clicked()), this, SLOT(close())); // Qt 5에 도입된 새로운 방식 connect(but, &QPushButton::clicked, this, &QtPractice::close); connect(but, &QPushButton::clicked, [this] { this->close(); });
  32. 32. Qt Widgets 예제 • MOC의 작동 방식 때문에, 헤더 파일(.h)과 구현 파일(.cpp)을 분리해야 한다. • The meta-object system이 정상적으로 작동하게 하기 위해, 정해진 매크로를 써야 한다. // main.cpp #include "QtPractice.h" #include <QtWidgets/QApplication> int main(int argc, char* argv[]) { QApplication a(argc, argv); QtPractice w; w.show(); return a.exec(); } // QtPractice.h #pragma once #include <QtWidgets/QMainWindow> #include <QtWidgets/QLabel> #include <QtWidgets/QPushButton> class QtPractice : public QMainWindow { Q_OBJECT // QObject subclass에 필수적인 매크로 public: explicit QtPractice(QWidget *parent = nullptr); };
  33. 33. Qt Widgets 예제 // QtPractice.cpp #include "QtPractice.h" #include <QtWidgets/QVBoxLayout> QtPractice::QtPractice(QWidget *parent) : QMainWindow(parent) { resize(200, 150); auto place = new QWidget; auto vLayout = new QVBoxLayout; // 세로 레이아웃 auto lab = new QLabel(QStringLiteral( uR"(<span style="font-size: 24pt; color: green;">안녕, <b>Qt</b>!</span>)" )); // HTML 태그를 그대로 사용할 수 있음(rich text) vLayout->addWidget(lab); auto but = new QPushButton(QStringLiteral(u"나가기")); connect(but, &QPushButton::clicked, this, &QtPractice::close); vLayout->addWidget(but); place->setLayout(vLayout); setCentralWidget(place); }
  34. 34. Bonus: Qt QML 예제 • Qt Creator에서 개발 환경 설정을 마친 후, Qt Quick 프로젝트를 생성해야 한다. • qml.qrc 파일에 QML 파일들의 위치가 저장된다. • C++ 프로그램의 main() 함수는 아래와 같이 자동으로 생성된다. #include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); }
  35. 35. Bonus: Qt QML 예제 import QtQuick 2.6 import QtQuick.Controls 2.2 import QtQuick.Window 2.3 ApplicationWindow { id: window width: 200; height: 100; visible: true color: "transparent" flags: Qt.FramelessWindowHint | Qt.Window Rectangle { width: 200; height: 100; color: "#800000FF" Text { text: '<span style="color: white;">Hello,<b>QML</b>!</span>' font.pixelSize: 32; textFormat: Text.RichText } Button { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom text: "Quit" onClicked: { window.close(); } // JavaScript } } }
  36. 36. Qt 참고 서적 • 사실 Qt 프레임워크는 단시간에 설명하는 것조차 힘들 정도로 방대함 • 국내에도 Qt 5의 각종 모듈에 대해 자세히 다룬 서적이 있음(보유 중) • 중앙도서관 대출 가능 “Qt 5 프로그래밍 가이드”, 김대진 지음, 2014, 성안당
  37. 37. Qt의 문제점(QML 제외) • Qt 고유의 비표준 문법과 구현을 사용한다. • 표준 C++와 거리가 먼 매크로와 외부 도구들이 쓰여, 가독성과 명확성을 떨어뜨리는 결과를 낳는다. • The meta-object system을 구현하기 위해 쓰이는 MOC는 C++ 컴파일러와 독립적으로 작동하여, 컴파일 시간을 훨씬 더 길게 만든다. • 구식 connect()는 signal이나 slot 이름에 오탈자가 있어도, 컴파일 타임에 오류를 잡아내지 못한다. • 자체 IDE인 Qt Creator가 한국어를 제대로 처리하지 못한다.
  38. 38. Qt의 문제점(QML 제외) • Qt Core 모듈이 자체 구현 컨테이너와 순회자 (iterator)를 정의한다. • 대부분 C++ STL(Standard Template Library)에 있는 것을 재정의한다. (QList<T>, QVector<T>, QSet<T>, QMap<Key,T>, etc.) • STL 스타일과 Java 스타일의 순회자를 따로 제공한다. • 기존 C++ 프로그래머가 적응하기 힘들게 만들고, 다른 코드나 라이브러리와 어울리지 않는다(특히 Boost). • Qt Widgets 모듈만 쓰고 싶어도 강제적으로 포함되어, 결과물의 용량을 늘리게 된다. • 이미 자체 알고리즘 모듈인 Qt Algorithm은 폐기 예정 (deprecated)이다.
  39. 39. Qt의 문제점(QML 제외) • LGPL v3 라이선스의 제한이 크게 존재한다. • GPL 대신 쓸 수 있는 open source 라이선스이다. • 동적 링크 라이브러리(DLL: Dynamic Link Library)를 사용할 것이 거의 강제된다. 즉 의존성(dependency)이 생기는 dynamic build만 써야 하는 상황이 된다. • 사용자의 해킹과 역공학(reverse engineering)을 허용해야 하므로, 임베디드 기기 사용이 거의 불가능하다. • 무거운 DLL 파일을 계속 함께 배포해야 한다. • DLL 파일의 사용이 메모리 자원을 많이 소모하는 것은 물론이고, 프로그램의 로딩 시간도 늘어나게 한다. • 따라서 작은 실행 파일을 만드는 프로젝트에는 부적합하다.
  40. 40. Nana에 대한 간략한 소개 • 현재 중국인 프로그래머 Jinhao의 주도로 활발히 진행 중인 open source 프로젝트이다. • Modern C++ 스타일로 GUI 프로그래밍이 가능한 cross-platform 라이브러리이다. • Windows와 Linux(X11)을 지원한다. • Boost Software License로 배포된다. • MIT 계열의 라이선스로, 제한이 거의 없기 때문에, 상업적인 사유 소프트웨어에서도 비교적 자유롭게 쓸 수 있다. • 즉 static build를 하기 좋다.
  41. 41. VS2015에 Nana 설치하기 1. Nana project 사이트(nanapro.org)에 접속한다.
  42. 42. VS2015에 Nana 설치하기 2. SourceForge 링크에서 소스 파일을 내려받는다. (가볍기 때문에 바이너리 파일을 따로 제공하지 않음)
  43. 43. VS2015에 Nana 설치하기 3. Static Linkage 파일의 생성 방법을 고른다. (Bakefile, Codeblocks, VC 등 여러 가지) 여기서는 Visual C++ 2015를 사용할 것이다.
  44. 44. VS2015에 Nana 설치하기 4. Visual Studio 2015 Community의 솔루션을 열어, 프로젝트 설정(Alt+F7)을 한다. • Static build를 위해, 프로젝트 설정의 ‘C/C++’ - ‘코드 생성’ 탭에서 ‘런타임 라이브러리’로 release mode에서는‘다중 스레드(/MT)’를, debug mode에서는 ‘/MTd’를 선택한다. • Debug mode와 release mode에 따라 설정을 반복한다. 필요하다면, 명령어 집합(x86, x64)에 따라서도 반복한다.
  45. 45. VS2015에 Nana 설치하기 5. Visual Studio 2015 Community의 솔루션으로 debug와 release mode에서 일괄 build한다. • x86과 x64 포함, i5-6600 CPU에서 약 3분이 소요된다. • VC++를 통한 결과물은 .lib 확장자로 생성된다. (x86: 약 213 MB; x64: 약 253 MB)
  46. 46. VS2015에 Nana 설치하기 6. Visual Studio 2015 Community에서 [새 프로젝트]를 누르고 ‘Visual C++’ - ‘Win32’ - ‘Win32 프로젝트’를 선택한다.
  47. 47. VS2015에 Nana 설치하기 7. ‘응용 프로그램 설정’에서 ‘빈 프로젝트’를 고른다.
  48. 48. VS2015에 Nana 설치하기 8. 속성에서 Nana 라이브러리의 디렉터리에 대한 정보를 입력한다. • 앞에서 했던 것처럼, ‘런타임 라이브러리’로 ‘다중 스레드(/MT)’를 선택한다.(debug mode에서는 /MTd) • ‘VC++ 디렉터리’ 탭의 ‘포함 디렉터리’에 ‘(Nana 폴더)include’를, ‘라이브러리 디렉터리’에 ‘(Nana 폴더)buildbin’을 넣는다. 구분 기호는 콜론(‘;’)이다.
  49. 49. VS2015에 Nana 설치하기 • ‘링커’ - ‘입력’ 탭의 ‘추가 종속성’에 ‘nana_(…).lib’를 현재 mode에 맞는 것으로 골라 넣는다. 구분 기호는 콜론(‘;’)이다. • Debug mode와 release mode에 따라 설정을 반복한다. 필요하다면, 명령어 집합(x86, x64)에 따라서도 반복한다.
  50. 50. VS2015에 Nana 설치하기 9. 프로젝트 속성에서 시스템의 진입점 설정을 바꾼다. • ‘링커’ - ‘고급’의 ‘진입점’(entry)을 ‘mainCRTStartup’으로 설정한다. Win32에서는 WinMain()이 시작 함수이므로, 미설정 시 compile error가 난다. • main()을 기본으로 사용하게 바꿔야, 소스 코드가 platform independent하다.
  51. 51. VS2015에 Nana 설치하기 10. 간단한 예제를 실행해 본다. #include <nana/gui.hpp> #include <nana/gui/widgets/label.hpp> #include <nana/gui/widgets/button.hpp> int main() { using namespace nana; form fm; label lab{ fm, "<bold size=14>Hello, <blue>Nana C++ Library</>!</>" }; lab.format(true); button but{ fm, "Quit" }; but.events().click([&fm] { fm.close(); }); fm.div("vert <><<><weight=80% text><>><><weight=24 <><button><>><>"); fm["text"] << lab; fm["button"] << but; fm.collocate(); fm.show(); exec(); return 0; }
  52. 52. Nana의 자세한 특징 • Modern C++ 스타일로 작성된 라이브러리이다. • Modern C++ 표준 스타일은 C++ 프로그래머가 적응하기 쉽고, 생산성이 더 높으며, 다른 코드와 잘 어울리고, 표준을 준수하는 모든 컴파일러에서 사용할 수 있다. • STL 컨테이너를 재사용하기 좋다. • Renderer가 native하고 필요한 모듈만 들어 있어, 결과물의 크기가 작다. 또한 static build가 쉽다. • OS의 native API를 사용하므로, overhead가 적다. • Static build를 할 경우, 배포할 때 DLL 파일이 필요 없고, 프로그램의 startup 시간이 아주 짧다.
  53. 53. Nana의 자세한 특징 • 정적 객체를 통해 GUI component를 생성한다. • C++ 프로그래머가 이해하기 쉽고, 객체가 파괴될 때 자원이 언제 반환되는지도 명확하다. • 동적 할당 객체에 비해, 현대적 디자인의 C++ 코드이다. class MyWindow : public nana::form { public: MyWindow(); private: nana::place place_{ *this }; nana::label lab_hello_{ *this, u8"<bold size=14>안녕, <blue>Nana C++ Library</>!</>" }; nana::button but_quit_{ *this, u8"나가기" }; }; 부모의 window handle을 참조 타입으로 받는다.
  54. 54. Nana의 자세한 특징 • Event handling이 깔끔하다. • C++의 함수자(functor)와 람다 표현식(lambda expression)을 완벽하게 지원한다. • Qt의 connect()에 비해, 훨씬 더 간결한 문법을 사용한다. but_quit_.events().click([this](const arg_click&) { this->lab_hello_.caption( u8"<bold red size=14>사실 나가기 버튼이 아니다!</>"); }); this->events().unload([this](const arg_unload& arg) { msgbox mb{ *this, u8"프로그램 종료", msgbox::yes_no }; mb.icon(msgbox::icon_question); mb << u8"정말로 나가시겠습니까?"; arg.cancel = (mb() == msgbox::pick_no); });
  55. 55. Nana의 레이아웃 개요 • nana::place를 통해, 마치 HTML처럼 구성할 수 있다. • div() 메서드의 인자로 field들로 된 문자열을 넣는다. • Field는 한 쌍의 부등호(‘<>’)로 이루어지며, 다른 field를 포함할 수 있다(nested). 빈 field는 허용 공간을 꽉 채운다. • 특정 field에 식별자(identifier)로 이름을 지정할 수 있다. nana::form fm; nana::place plc{ fm }; plc.div( "vert” ”<>” “< <> <weight=80% text> <> >” “<>” “<weight=24 <> <button> <> >” ”<>“ ); Fields Names of fields
  56. 56. Nana의 레이아웃 개요 • 매우 직관적인 방식으로 field에 widget을 추가한다. • operator[]나 field() 메서드를 이용하여, nana::place::field_reference 객체(대리자)를 얻는다. • 위 객체에 operator<<를 사용하여, field의 identifier에 맞는 widget을 추가한다. • collocate() 메서드로 field들을 결합한다. • div()의 인수 문자열은 Div-Text라는 문법을 사용한다. plc["text"] << lab; plc["button"] << but; plc.collocate(); fm.show(); 실제로는 proxy(대리자)를 이용하지만, 그걸 알 필요는 없음
  57. 57. Nana의 Div-Text 레이아웃 • 기본적으로 field들은 수평으로(horizontally) 배치된다. • vert 키워드를 사용하면, field들을 수직으로(vertically) 배치할 수 있다. std::array<button, 4> buts{ { { fm, u8"버튼" }, { fm, u8"버튼" }, { fm, u8"버튼" }, { fm, u8"버튼" } } }; plc.div("<buts>"); for (const auto& but : buts) plc["buts"] << but; plc.div("<vert buts>"); for (const auto& but : buts) plc["buts"] << but;
  58. 58. Nana의 Div-Text 레이아웃 • grid 키워드를 사용하면, 격자 모양의 레이아웃 field를 만들 수 있다. • grid=[3,2]는 3열 2행의 격자 레이아웃을 뜻한다. std::array<button, 6> buts{ fm, fm, fm, fm, fm, fm }; plc.div("<grid=[3,2] buts>"); for (int i = 0; i < 6; i++) { buts[i].caption(std::to_string(i)); plc["buts"] << buts[i]; } 이 밖의 내용은 Nana 홈페이지에서 확인할 수 있다.
  59. 59. Nana 예제 https://github.com/lazyahasil/text_overseer
  60. 60. Nana의 문제점 • 라이브러리 개발자와 이용자의 수가 적다. • 정보를 구하기 힘들기 때문에, 오류가 발견되거나 문제가 발생했을 때, 빨리 해결하기가 쉽지 않다. • 아는 사람이 적어, 다른 사람과 협업으로 사용하기 힘들다. • 라이브러리 개발에 따른 기능적 안정성이 낮다. • 아직 핵심 기능만 개발된 상태이므로, 앞으로도 많은 부분들이 바뀌고 추가된다. • 라이브러리의 버전을 올렸을 때, 일부 기능이 제대로 작동하지 않을 수 있다. • 따라서 중대형 프로젝트에 적합하지 않다. • 한국어 입력기가 깔끔하지는 않다.
  61. 61. 종합: Qt와 Nana의 공통점 • Native Look and Feel이 가능하다. • Java의 GUI 같은 경우, 각 platform의 window와 어울리지 않는 모양이 일정하게 나타난다. • 다국어(Unicode)를 지원한다. • Qt는 16-bit unicode를 담는 QString 객체를 자체적으로 구현한다. QChar를 담는 컨테이너이다. • Nana는 UTF-8 문자열을 담는 std::string을 사용한다. 즉 STL 표준 컨테이너와 호환되며, ASCII 영문 문자열과도 호환된다. • 국제화(Internatinonalization)를 지원한다.
  62. 62. 종합: Qt와 Nana의 차이점 구분 라이선스 사용자 수 C++ 표준 준수 코드를 통한 UI 개발 도구를 통한 UI 개발 Widget 활용 가능성 작은 실행 파일 생성 + 배포 용이성 Qt Widgets GPL/LGPL/상용 많은 개인/기업 MOC 사용 생산성 낮음 Qt Designer 아주많은오픈소스 LGPL 적용시 매우 까다로움 Nana Boost S/L 적은 수의 개인 Modern C++ 생산성 높음 프로그램 없음 기본적인 것만 기본적으로 지원
  63. 63. 종합: Qt와 Nana의 차이점 • 결론 • 대부분의 경우에서 Qt가 여전히 유리하다. • 소규모 프로젝트나 간단한 form의 프로그램을 구성할 때는 Nana가 더 유리하다. • 배포에 있어서는 Nana가 Qt보다 훨씬 더 간단하다.

×