2015 ソフトウェア設計及び演習用の班Wiki

チャットウィンドウのプログラム

#include <gtk/gtk.h>

typedef struct main_dialog_type{
  GtkWidget *window;
  GtkWidget *hbox;
  GtkWidget *vbox;
  GtkWidget *button;
  GtkWidget *scrolled_window1;
  GtkWidget *scrolled_window2;
  GtkWidget *entry;
  GtkWidget *canvas;
}MainDialog;

int i = 1;
 

// enterを押した時に呼ばれる関数
static void
cb_entry (GtkEntry *entry, gpointer data);

// buttonを押した時に呼ばれる関数
static void
cb_button (GtkButton *button, gpointer data);

// cb関数からテキストと構造体widgetsを受け取ってcanvasへ表示
static void
cairo_output (gpointer data, const gchar *text);


int main(int argc, char **argv)
{
  // widgetをまとめた構造体変数
  MainDialog widgets;
  
  gtk_init (&argc, &argv);

  widgets.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (widgets.window), "chat");
  gtk_widget_set_size_request(widgets.window, 600, 500);
  gtk_container_set_border_width (GTK_CONTAINER (widgets.window), 10);
  g_signal_connect(G_OBJECT(widgets.window),"destroy",
		   G_CALLBACK(gtk_main_quit),
		   NULL);


  widgets.vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (widgets.window), widgets.vbox);

 
  // キャンバスウィジェット作成、配置
  widgets.scrolled_window1 = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW 
				      (widgets.scrolled_window1),
				      GTK_SHADOW_ETCHED_OUT);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widgets.scrolled_window1),
  				 GTK_POLICY_AUTOMATIC,
  				 GTK_POLICY_AUTOMATIC);
  gtk_box_pack_start (GTK_BOX (widgets.vbox), 
		      widgets.scrolled_window1, TRUE, TRUE, 0);
  widgets.canvas = gtk_drawing_area_new ();
  gtk_container_add(GTK_CONTAINER(widgets.scrolled_window1), 
		    widgets.canvas);


  // entryウィジェット作成、配置
  widgets.scrolled_window2 = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW 
				      (widgets.scrolled_window2),
				      GTK_SHADOW_ETCHED_IN);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (widgets.scrolled_window2),
				 GTK_POLICY_AUTOMATIC,
				 GTK_POLICY_AUTOMATIC);
  gtk_box_pack_start (GTK_BOX (widgets.vbox), 
		      widgets.scrolled_window2, FALSE, FALSE, 20);
  widgets.entry = gtk_entry_new ();
  g_signal_connect (G_OBJECT (widgets.entry), "activate",
		    G_CALLBACK (cb_entry), &widgets);
  gtk_container_add(GTK_CONTAINER(widgets.scrolled_window2), 
		    widgets.entry);

  
  // 送信ボタン作成、配置
  widgets.hbox = gtk_hbox_new (FALSE, 0);
  gtk_box_pack_start (GTK_BOX (widgets.vbox), widgets.hbox, FALSE, FALSE, 0);
  widgets.button = gtk_button_new_from_stock(GTK_STOCK_APPLY);
  gtk_box_pack_end (GTK_BOX (widgets.hbox), widgets.button, FALSE, FALSE, 0);
  g_signal_connect(G_OBJECT (widgets.button),
		   "clicked",
		   G_CALLBACK (cb_button),
		   (gpointer)&widgets);

  gtk_widget_show_all (widgets.window);
  gtk_main ();

  return 0;
}



static void
cb_entry (GtkEntry *entry, gpointer data)
{
  const gchar *text;

  // *textをEntryのtext格納先と指定する
  text = gtk_entry_get_text (((MainDialog *) data) -> entry);

  cairo_output (data, text);
}

static void
cb_button (GtkButton *button, gpointer data)
{
  const gchar *text;

  // *textをEntryのtext格納先と指定する
  text = gtk_entry_get_text(GTK_ENTRY (((MainDialog *) data) -> entry));

  cairo_output (data, text);
}

static void
cairo_output (gpointer data, const gchar *text)
{
  GtkWindow *drawable = (((MainDialog *) data) -> canvas) -> window;
  cairo_t *cr;
  char buf[256];

  // bufに*textの文字列を格納する
  sprintf(buf, "%s", text);

  cr = gdk_cairo_create (drawable);
  // 文字色
  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
  // font
  cairo_select_font_face (cr, "VL ゴシック",
			  CAIRO_FONT_SLANT_ITALIC,
			  CAIRO_FONT_WEIGHT_NORMAL);
  // 文字出力位置
  cairo_move_to (cr, 5.0, 25.0 * i);
  // 文字サイズ
  cairo_set_font_size (cr, 17);
  cairo_show_text (cr, buf);

  i++;

  cairo_destroy (cr);
}
  • main関数
    • widgets構造体
      • 呼び出したコールバック関数内でさらに関数を呼び出すので、引数の数の関係でウィジェットを構造体にまとめてしまった
    • canvas:cairoを使ったメッセージを描画する為のスペース
    • entry:メッセージ入力する
    • button:送信ボタン
  • cb_entry関数
    • Enterを押したときに呼び出される
    • widgets構造体を受け取る
    • textとwidgets構造体をcairo_output関数へ渡す
  • cb_button関数
    • buttonを押したときに呼び出される
    • widgets構造体を受け取る
    • textとwidgets構造体をcairo_output関数へ渡す
  • cairo_output関数
    • canvasにテキストを出力するための関数
    • textとwidgets構造体を受け取る
    • 文字のフォントやサイズなどを設定

※通信機能にかかわる部分はそのうち
※スクロールがうまく働いていない。入力した文字数に対応させたいから普通にスクロールウィンドウに配置しただけでは難しいかもしれない


最終更新日:2015/06/09 00:53:07