Exemple greffons et connecteurs

The following is a simple example of using sockets and plugs. The method of communication between processes is deliberately kept very simple: The Plug writes its ID out to a text file named plug.id and the process with the socket reads the ID from this file. In a real program, you may want to use a more sophisticated method of inter-process communication.

Code source

File: socket.cc (For use with gtkmm 3, not gtkmm 2)

#include <iostream>
#include <fstream>
#include <gtkmm.h>
#include <gtkmm/socket.h>

using namespace std;

const char* id_filename = "plug.id";

void plug_added()
{
  cout << "A plug was added" << endl;
}

bool plug_removed()
{
  cout << "A Plug was removed" << endl;
  return true;
}

class MySocketWindow : public Gtk::Window
{
  public:
    MySocketWindow()
    {
      ifstream infile(id_filename);
      if (infile)
      {
        Gtk::Socket* socket = Gtk::manage(new Gtk::Socket());
        add(*socket);
        socket->signal_plug_added().connect(sigc::ptr_fun(plug_added));
        socket->signal_plug_removed().connect(sigc::ptr_fun(plug_removed));
        ::Window plug_id = 0;
        infile >> plug_id;
        infile.close();
        socket->add_id(plug_id);
      }
      else
      {
        Gtk::Label* label = Gtk::manage(
            new Gtk::Label(
              "Plug id file not found.\n Make sure plug is running."));
        add(*label);
        set_size_request(150, 50);
      }
      show_all();
    }
};

int main(int argc, char** argv)
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
  MySocketWindow win;
  app->run(win);
  return 0;
}

File: plug.cc (For use with gtkmm 3, not gtkmm 2)

#include <iostream>
#include <fstream>
#include <gtkmm.h>
#include <gtkmm/plug.h>
#include <glib/gstdio.h>

using namespace std;

const char* id_filename = "plug.id";

void on_embed()
{
  cout << "I've been embedded." << endl;
}

class MyPlug : public Gtk::Plug
{
  public:
    MyPlug() :
      m_label("I am the plug")
  {
    set_size_request(150, 100);
    add(m_label);
    signal_embedded().connect(sigc::ptr_fun(on_embed));
    show_all_children();
  }

  private:
    Gtk::Label m_label;
};


int main(int argc, char** argv)
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
  MyPlug plug;
  plug.show();

  ofstream out(id_filename);
  out << plug.get_id();
  out.close();
  cout << "The window ID is: " << plug.get_id() << endl;

  app->run(plug);

  // remove the ID file when the program exits
  g_remove(id_filename);
  return 0;
}

Cet exemple crée deux exécutables : socket et plug. L'idée est que socket ait une fenêtre d'application qui accueille un élément graphique issu du programme plug. Compte tenu de la manière dont cet exemple est conçu, plug doit être lancé avant que socket ne démarre. Pour voir cet exemple en action, exécutez les commandes suivantes dans l'ordre indiqué à partir du répertoire de l'exemple :

Lancez le programme plug et envoyez-le en arrière-plan (ou simplement utilisez un terminal différent) :

$ ./plug &

Après cette action, vous devriez voir s'afficher :

The window ID is: 69206019

puis lancez le programme socket :

$ ./socket

Après avoir lancé socket, vous devriez voir les sorties suivantes sur le terminal :

I've been embedded.
A plug was added

La première ligne correspond à la sortie du programme plug, après qu'il a reçu notification qu'il a été incorporé dans l'objet Socket. La deuxième ligne a été émise par l'objet socket en réponse au signal plug_added. Si tout a été effectuée comme indiqué ci-dessus, la fenêtre socket doit ressembler grosso modo à quelque chose comme :

Si, pour une quelconque raison, l'objet Socket ne peut pas recevoir l'objet Plug, la fenêtre ressemblera à :