自作シグナル

概要

シグナルを自作してコネクトする。

テンプレートを使用してシグナルクラスを作成するのだが、

typedef sigc::signal< 戻り値, 第一引数, 第二引数, .... > シグナル名;

の様にtypedefしておくと便利である。 あとはメンバ変数として作成したシグナルを定義し、それをコネクトするだけでよい。

ソース

sig3.cpp

#include <gtkmm.h>
#include <iostream>

// 自作シグナルのtypedef
typedef sigc::signal< bool, int > SIG_MY_CLICK;

class MyButton : public Gtk::Button
{
    int m_number;
    SIG_MY_CLICK m_sig_my_click;

public:

    MyButton( const Glib::ustring& label, int number )
        : Gtk::Button( label ),  m_number( number ){}

    SIG_MY_CLICK sig_my_click(){ return m_sig_my_click; }

protected:

    virtual void on_clicked(){

        Gtk::Button::on_clicked();

        // 自作シグナルのemit
        if( m_sig_my_click.emit( m_number ) ) Gtk::MessageDialog( "push button1" ).run();
    }
};


class MainWin : public Gtk::Window
{
    Gtk::HBox m_hbox;
    MyButton m_b1, m_b2, m_b3;

public:
    MainWin();

private:

    // 自作シグナル用のハンドラ
    bool on_my_click( int number );
};


MainWin::MainWin() :
    m_b1( "button1", 1 ),
    m_b2( "button2", 2 ),
    m_b3( "button3", 3 )
{
    // 自作シグナルとハンドラのコネクト
    m_b1.sig_my_click().connect( sigc::mem_fun( *this, &MainWin::on_my_click ) );
    m_b2.sig_my_click().connect( sigc::mem_fun( *this, &MainWin::on_my_click ) );
    m_b3.sig_my_click().connect( sigc::mem_fun( *this, &MainWin::on_my_click ) );

    m_hbox.pack_start( m_b1 );
    m_hbox.pack_start( m_b2 );
    m_hbox.pack_start( m_b3 );

    add( m_hbox );
    show_all_children();
}


// 自作シグナル用のハンドラ
bool MainWin::on_my_click( int number )
{
    std::cout << "click " << number << std::endl;

    if( number == 1 ) return true;
    return false;
}


int main( int argc, char *argv[] )
{
    Gtk::Main kit( argc, argv );
    MainWin mainwin;
    Gtk::Main::run( mainwin );

    return 0;
}


コンパイル

必要なコンパイルオプションは pkg-config を使って取得する。

g++ sig3.cpp -o sig3 `pkg-config gtkmm-2.4 --cflags --libs`

結果