スタートWt

WtとはC++で書かれたC++用のWebアプリケーションフレームワークです。

APIWidget-centricであり、デスクトップGUIアプリケーションのようにしてWebアプリケーションを書くことができます。
Wt, C++ Web Toolkit — Emweb


EventハンドリングにはQtなどのようにSignal-Slotを使用しています。この抽象化された仕組みをJavascript用に具象化したJSignal, JSlotというものもあり、Javascriptとも連携できるようになっています。


インストール方法やサンプルは公式サイトを参照していただくとして、僕も簡単なWtのサンプルを書いてみました。

Timer.h

#ifndef TIMER_H
#define TIMER_H

#include <Wt/WApplication>
#include <Wt/WComboBox>
#include <Wt/WJavaScript>
#include <Wt/WText>

class Timer
:   public  Wt::WApplication
{
public:
    Timer(Wt::WEnvironment const &env);

private:
    void    set_intervals();
    void    set_timer_id(std::string const &id);
    void    add_entry   (size_t interval_as_millsec);
    
    void    interval_changed        ();
    void    calling                 ();

private:
    Wt::JSignal<void>           callback_;
    Wt::JSignal<std::string>    set_timer_id_;
    Wt::JSlot                   timer_;
    Wt::WComboBox               *interval_;
    Wt::WText                   *time_;
    std::string                 timer_id_;
};


#endif  //TIMER_H


Timer.cpp

#include <ctime>
#include <string>

#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>

#include <Wt/WBreak>

#include "./Timer.h"

Timer::Timer(Wt::WEnvironment const &env)
    :   Wt::WApplication(env)
    ,   callback_(this, "callback")
    ,   set_timer_id_(this, "set_timer_id")
{
    new Wt::WText("select interval : ", root());

    interval_ = new Wt::WComboBox(root());
    set_intervals();
    interval_->activated().connect(this, &Timer::interval_changed);

    new Wt::WBreak(root());

    time_ = new Wt::WText(root());
    
    callback_.connect(this, &Timer::calling);
    set_timer_id_.connect(this, &Timer::set_timer_id);
}

void Timer::set_intervals()
{
    size_t ivs[] = { 10, 20, 50, 100, 200, 500, 1000 };
    BOOST_FOREACH(const size_t iv, ivs) {
        add_entry(iv);
    }
    interval_->setCurrentIndex(0);
}

void Timer::add_entry(size_t interval_as_millsec)
{
    interval_->addItem(
            Wt::WString(
                boost::lexical_cast<std::string>(interval_as_millsec) ) );
}


void Timer::calling()
{
    time_t tm;
    time(&tm);

    time_->setText(ctime(&tm));     
}

void Timer::set_timer_id(std::string const &id)
{
    timer_id_ = id;
    std::cout << "timer id was changed to : " << id << std::endl;
}

void Timer::interval_changed()
{
    std::cout << "interval changed : " << interval_->currentText() << std::endl;

    std::string const code =
        "function() {"
            "clearInterval(" + timer_id_ + ");"
            "var id = setInterval("
                "function() {" +
                    callback_.createCall() + ";"
                "}" + "," +
                interval_->currentText().narrow() +
            ");" +
            set_timer_id_.createCall("id") +
        "}";

    timer_.setJavaScript(code);
    timer_.exec();
}

Wt::WApplication *createApplication(Wt::WEnvironment const &env)
{
    return new Timer(env);
}

int main(int argc, char **argv)
{
    return Wt::WRun(argc, argv, &createApplication);
}


これを

gcc -o Timer.wt -Wall -g Timer.cpp -lstdc++ -lwt -lwthttp -lboost_signals

このようにビルドして、

./Timer.wt --docroot . --http-address localhost --http-port 8080

とすると、localhost:8080にWtのビルトインサーバーであるwthttpでアプリケーションが立ち上がります。


ちなみにこのサンプルは、ブラウザのJavascriptでinterval毎にSignalを出して、サーバーでそのSignalを受け取るとWt::WTextのデータを更新してブラウザ画面上の時刻を更新するというものになっています。