한국어
Qt
 

Qt Framework은 프로세스간 통신(IPC)을 위한 몇 가지 방법을 제공하는데 이 글에서는 Qt D-Bus에 대해 설명한다. 

 

D-Bus는 리눅스용으로 개발된 메세지 버스 시스템으로 RPC(Remote Procedure Call) 및 프로세스간의 통신(IPC) 방법으로 사용된다. 리눅스계열에서 주로 사용되며 꽤 오래 전에 윈도우에서도 사용할 수 있도록 포팅이 진행되었다. 

 

이 글에서는 윈도우즈 기반에서 Qt D-Bus를 사용, 설명할 것이므로 먼저 윈도우즈에서 D-Bus를 사용하기 위한 방법을 알아본다. 윈도우즈 기반에서 설명하긴하지만 Qt D-Bus는 리눅스건 윈도우즈건 플랫폼에 무관하게 사용할 수 있다. (D-Bus기본 개념은 이 글을 참조)

 

최신 소스코드(git://anongit.freedesktop.org/git/dbus/dbus)를 직접 컴파일 후 사용할 수 도 있고, 비공식이긴하지만 패키징된 설치파일을 다운로드받아 사용할 수 있는 방법이 있다.( 여기서는 오래된 버전이긴 하지만 간단히 비공식 설치파일을 다운로드 받아 설치한다.)

 

아래 주소를 방문하면 윈도우즈용 설치파일과 간단한 예제 응용프로그램도 다운로드 받을 수 있다. 윈도우즈용 설치파일을 다운로드 받아 설치한다.

https://code.google.com/archive/p/dbus-windows-installer/downloads

 

install_D-Bus.png

 

설치가 완료된 이후 C:\Program Files (x86)\D-Bus\bin 에는 dbus-daemon.exe을 포함한 몇가지 유틸리티도 설치되어 있다.

D-Bus_bin.png

 

D-Bus를 사용하려면 dbus-daemon이 실행되어 있어야 한다.

윈도우즈 명령 프롬프트(cmd)를 열어서 먼저 dbus-env.bat과 dbus-daemon --session 을 차례로 명령한다.

excute_dbus-daemon.png

 


 

이제 Qt D-Bus를 사용하기 위해 두개의 간단한 프로젝트를 생성한다. 프로젝트 폴더 구조는 다음과 같다.

lightsystem.png

 

하나는 on, off 상태에 따라 동작되는 light이고, 다른 하나는 이조명을 제어하는 switch 이다.

light.png switch.png

 

이 간단한 프로젝트들은 Qt D-Bus을 이용하여 light system으로 통합된다.

 

MyLight Class

MyLight객체는 상태를 나타내는 프로퍼티를 가지며 setter와 getter를 제공한다. 이 헤더파일은 D-Bus의 인터페이스로 사용될 것이다.

light.h

#include <QObject>

class MyLight : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool isOn READ getIsOn WRITE setIsOn NOTIFY lightChanged)

public:
    explicit MyLight(QObject *parent = nullptr);

    bool getIsOn() const;
    void setIsOn(bool isOn);

signals:
    void lightChanged();

public slots:
    void turnOn();
    void turnOff();

private:
    bool mIsOn;
};

 

Qt용 명령 프롬프트를 실행하고 아래와 같은 명령으로 interface xml파일을 생성할 수 있다.

qdbuscpp2xml light\light.h

 

출력된 내용을 복사해서 프로젝트의 inferface디렉토리에 light.xml 파일로 생성한다. 이 light.xml은 light에서 ADAPTOR로 사용되고 switch에서는 INTERFACE로 사용된다.

qdbuscpp2xml.png

 

light프로젝트 파일(.pro)에 아래 내용을 추가한다.

QT += dbus
CONFIG += c++11
 
DBUS_ADAPTORS += ../interface/light.xml

 

MyLight 생성자에서 MyLightAdaptor를 생성한다.(컴파일이 실행시에 light_adaptor.h파일이 만들어진다.)

light.cpp

#include "light.h"
#include "light_adaptor.h"


MyLight::MyLight(QObject *parent)
    : QObject(parent),
      mIsOn(false)
{
    // Create interface adaptor
    new MyLightAdaptor(this);
}


bool MyLight::getIsOn() const
{
    return mIsOn;
}


void MyLight::setIsOn(bool isOn)
{
    if(mIsOn != isOn){
        mIsOn = isOn;
        emit lightChanged();
    }
}


void MyLight::turnOn()
{
    setIsOn(true);
}


void MyLight::turnOff()
{
    setIsOn(false);
}

 

main.cpp에서는 D-Bus의 세션버스에 MyLight 객체 및 서비스를 등록한다.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtDBus>


#include <QtQml>
#include "light.h"


int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    // Create new instance
    MyLight myLight;

    engine.rootContext()->setContextProperty("myLight", &myLight);

    // Connect to session bus
    QDBusConnection connection = QDBusConnection::sessionBus();
    connection.registerObject("/light", &myLight);
    connection.registerService("cong.service.light");

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

 

이제 light를 컴파일 및 실행하고 서비스가 정상적으로 등록되어 있는지 확인하기 위해서  QDBusViewer를 실행 해 본다. (Qt가 설치된 곳에 있다.)

Qt D-Bus는 기본 D-Bus 컨셉을 유지하면서도 D-Bus의 저수준 API를 캡슐화하여 Qt 개발자에게 익숙한 시그널, 슬롯, 프로퍼티 개념을 제공하고 있다. Method를 각각 더블클릭해서 light가 on, off됨을 확인 할 수 있다.

QDBusViewer.png

 

switch프로젝트 파일(.pro)에는 아래 내용을 추가한다.

QT += dbus
CONFIG += c++11
 
DBUS_INTERFACES += ../interface/light.xml

 

LightController Class

controller객체는 조명을 제어하기위한 on, off 인터페이스만 제공하고 private멤버인 D-Bus의 interface 객체를 가진다.

lightcontroller.h

#include <QObject>

#include "light_interface.h"

class LightController : public QObject
{
    Q_OBJECT
public:
    explicit LightController(QObject *parent = nullptr);

private:
    local::MyLight *theLight;

public slots:
    void turnOn();
    void turnOff();
};

 

생성자에서 세션버스에 등록된 서비스 및 오브젝트 path의 interface를 생성한다.

lightcontroller.cpp

#include "lightcontroller.h"


LightController::LightController(QObject *parent) : QObject(parent)
{
    theLight = new local::MyLight("cong.service.light", "/light",
                                            QDBusConnection::sessionBus(), this);
}


void LightController::turnOn()
{
    theLight->turnOn();
}


void LightController::turnOff()
{
    theLight->turnOff();
}

 

LightController객체를 생성하고 qml에서 사용할 수 있도록 한다.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "lightcontroller.h"


int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    LightController controller;
    engine.rootContext()->setContextProperty("controller", &controller);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

 

switch를 컴파일 및 실행하고 on, off 버튼을 클릭해보자!

jwplayer

이 글과 연관된 다른 글
  1. [2019/06/30] GDBus 튜토리얼(GDBus tutorial) by makersweb (2603)
  2. [2018/03/12] pydbus 바인딩을 이용하여 서비스 데몬과 D-Bus통신 by makersweb (549)
  3. [2018/03/07] Ubuntu Linux에서 dbus-c++바인딩 D-Bus 테스트 by makersweb (3129)
  4. [2015/02/28] [IPC]D-Bus 소개 by makersweb (24751)
번호 제목 글쓴이 날짜 조회 수
공지 Qt프로그래밍(QtQuick) Beginner를 위한 글 읽는 순서 운영자 2019.01.05 10892
77 [Qt News] Qt for Python을 위한 기술 비전 j2doll 2019.08.20 638
76 열거형(enum)을 QML에서 사용하는 방법과 문자열(QString)로 얻기 makersweb 2019.08.20 635
75 [Qt News] Qt 6 기술 비전 (Technical vision for Qt 6) [2] j2doll 2019.08.08 568
74 [Qt News] Qt6 Git 개발 초기 단계 시작하기 j2doll 2019.08.02 851
73 [Qt] Google Play의 향후 요구 사항을 준수하는 방법 [2] j2doll 2019.07.29 532
72 Qt기반의 오픈소스 프로젝트들 - 2 운영자 2019.07.21 744
71 QML, 이미지, 폰트등을 바이너리 리소스로 만들기 makersweb 2019.06.24 1125
70 Qt Creator에서 임베디드 장치로 deploy설정(Custom Process Step) file makersweb 2019.06.15 695
69 Qt Quick Controls 2사용 및 스타일 설정 file makersweb 2019.06.07 1999
68 QML 강좌 - 동적 Listing (ListView) file makersweb 2019.06.01 2887
67 QtInstallerFramework로 온라인 설치프로그램(Online Installer)만드는 방법 [4] file makersweb 2019.05.28 684
66 QtCreator Design으로 GUI만들기 (QML로 만드는 Hello World -2) file makersweb 2019.05.26 3248
65 QML에서 멀티 스레드(multithreading) 프로그래밍 file makersweb 2019.05.25 795
64 QtSerialPort를 사용한 시리얼(Serial)통신 makersweb 2019.05.21 2476
63 Qt기반의 오픈소스 프로젝트들 makersweb 2019.05.15 1522
62 Q_D매크로와 d-pointer file makersweb 2019.05.07 281
61 가상키보드(Qt Virtual Keyboard)를 사용하는 방법 [17] file makersweb 2019.05.03 2021
» Windows에서 Qt D-Bus를 사용하여 프로세스간 통신(IPC) file makersweb 2019.05.02 973
59 QML과 QtQuick 모듈 개념과 기본 타입들 makersweb 2019.04.26 4940
58 QML 전역 객체 (Global Object) file makersweb 2019.04.10 379