[megoldva]Egyszerű GTK+ program

Fórumok

Sziasztok,

Szeretnék egy olyan grafikus alkalmazást írni, ami felhasználói név és hoszt megadása után nyit egy gnome terminált a következő formában:
gnome-terminal -t HOSTNAME -e "ssh USERNAME@HOSTNAME"

Eddig ennyire jutottam:


#include <gtk/gtk.h>

static void connect()
{
    /*IDE MIT ÍRJAK?*/
}

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

  GtkWidget *window;
  GtkWidget *table;

  GtkWidget *label_username;
  GtkWidget *label_hostname;
  GtkWidget *label_empty;

  GtkWidget *value_username;
  GtkWidget *value_hostname;
  GtkWidget *button_connect;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_title(GTK_WINDOW(window), "Connect to SSH");
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);

  table = gtk_table_new(3, 2, FALSE);
  gtk_container_add(GTK_CONTAINER(window), table);

  label_username = gtk_label_new("Username");
  label_hostname = gtk_label_new("Hostname");
  label_empty = gtk_label_new("");



  gtk_table_attach(GTK_TABLE(table), label_username, 0, 1, 0, 1, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  gtk_table_attach(GTK_TABLE(table), label_hostname, 0, 1, 1, 2, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  gtk_table_attach(GTK_TABLE(table), label_empty, 0, 2, 2, 3, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  value_username = gtk_entry_new();
  value_hostname = gtk_entry_new();
  button_connect = gtk_button_new_with_label ("Connect");

  gtk_table_attach(GTK_TABLE(table), value_username, 1, 2, 0, 1, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  gtk_table_attach(GTK_TABLE(table), value_hostname, 1, 2, 1, 2, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
 gtk_table_attach(GTK_TABLE(table), button_connect, 1, 3, 2, 3, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);

  gtk_widget_show(table);

  gtk_widget_show(label_username);
  gtk_widget_show(label_hostname);
  gtk_widget_show(label_empty);

  gtk_widget_show(value_username);
  gtk_widget_show(value_hostname);
  gtk_widget_show(button_connect);

  gtk_widget_show(window);
  g_signal_connect (button_connect, "clicked", G_CALLBACK (connect), NULL);

  g_signal_connect(window, "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  gtk_main();

  return 0;
}

Lehet, hogy teljesen rosszul csináltam eddig is, sem C, sem C++ ismeretem nincs.

Minden segítséget előre is köszönök!

Hozzászólások

1) A [code] blokk sokat tud segiteni.
2) Hogy mit irj? Nezd meg a GTK doksit, eleg jo. Ki kell nyerni a usernevet, meg a hostnevet a megfelelo nevu buttonbol (amit vagy kiteszel global variablebe, vagy egyeb modon elerhetove teszel a callback szamara - de szerintem kezdetnek a global jo lesz), osszerakod a megfelelo parancssort, aztan system(). g_strconcat() hasznos lesz majd ekozben.

--
|8]

<code> != [ code ]

Pedig baromi egyszeru a megoldas, de segitek, errefele nezelodj, itt rogton az elso oldalon ott van, hogyan lehet egy text widgetbol lekerni a szoveget. Aztan mar csak ossze kell rakni belole a parancsot (lasd a tippet az elozo hozzaszolasomban), es meg is vagy.

Globalissa ugy teszed, hogy kiviszed main()-bol, a 'globalis' terbe. Valahogy igy:


GtkWidget *value_username;
GtkWidget *value_hostname;

int 
main (int argc, char *argv[])
{
  ...
}

--
|8]

Javítottam a formázáson, változókat a megfelelő helyre tettem.

Az általad linkelt lapot megnéztem, de azzal nem jutottam túl sokra.

Ennyit sikerült még hozzáadnom:


static void connect()
{
    const gchar *username;
    username = gtk_entry_get_text(GTK_ENTRY(value_username));
    const gchar *hostname;
    hostname = gtk_entry_get_text(GTK_ENTRY(value_hostname));
}

Hogy tudom legalább kiíratni a változókat, hogy tudjam, hogy egyáltalán megkapják az értéket?

g_print nem megy, ez a hiba:
gtk.c:13: warning: passing argument 1 of ‘g_print’ makes pointer from integer without a cast
/usr/include/glib-2.0/glib/gmessages.h:230: note: expected ‘const gchar *’ but argument is of type ‘gchar’
gtk.c:13: warning: format not a string literal and no format arguments

g_print (username); g_print (hostname);

Es mint emlitettem, az elso kommentemben ott van, hogy mely fuggvennyel lehet ezeket egyszeruen osszefuzni, hogy megkapd a parancsot, amit kesobb atadhatsz system()-nek.

Le van irva minden, amit hasznalnod kell, a tobbi mar a te dolgod ;)

--
|8]

Sikerült.

Ez lett a végleges változat eddig:


#include <gtk/gtk.h>

GtkWidget *value_username;
GtkWidget *value_hostname;

static void connect()
{
  const gchar *username;
  username = gtk_entry_get_text(GTK_ENTRY(value_username));
  const gchar *hostname;
  hostname = gtk_entry_get_text(GTK_ENTRY(value_hostname));
  const gchar *command;
  command = g_strconcat("gnome-terminal -t ", hostname, " -e \"ssh ", username, "@", hostname, "\"", NULL);
  system(command);
}


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

  GtkWidget *window;
  GtkWidget *table;

  GtkWidget *label_username;
  GtkWidget *label_hostname;
  GtkWidget *label_empty;

  GtkWidget *button_connect;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_title(GTK_WINDOW(window), "Connect to SSH");
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);

  table = gtk_table_new(3, 2, FALSE);
  gtk_container_add(GTK_CONTAINER(window), table);

  label_username = gtk_label_new("Username");
  label_hostname = gtk_label_new("Hostname");
  label_empty = gtk_label_new("");

  gtk_table_attach(GTK_TABLE(table), label_username, 0, 1, 0, 1, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  gtk_table_attach(GTK_TABLE(table), label_hostname, 0, 1, 1, 2, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  gtk_table_attach(GTK_TABLE(table), label_empty, 0, 2, 2, 3, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  value_username = gtk_entry_new();
  gtk_entry_set_text (GTK_ENTRY (value_username), "az_en_felhasznaloi_nevem");
  
/*  gtk_entry_set_text(GtkEntry *value_username, const gchar *username_text);*/
  value_hostname = gtk_entry_new();
  button_connect = gtk_button_new_with_label ("Connect");

  gtk_table_attach(GTK_TABLE(table), value_username, 1, 2, 0, 1, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
  gtk_table_attach(GTK_TABLE(table), value_hostname, 1, 2, 1, 2, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
 gtk_table_attach(GTK_TABLE(table), button_connect, 1, 3, 2, 3, 
      GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);

  gtk_widget_show(table);

  gtk_widget_show(label_username);
  gtk_widget_show(label_hostname);
  gtk_widget_show(label_empty);

  gtk_widget_show(value_username);
  gtk_widget_show(value_hostname);
  gtk_widget_show(button_connect);

  gtk_widget_show(window);
  g_signal_connect (button_connect, "clicked", G_CALLBACK (connect), NULL);

  g_signal_connect(window, "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  gtk_main();

  return 0;
}

Van pár dolog még, amit még bele akarok rakni, de ellátja azt a feladatot, amiért elkezdtem írni.

Nagyon szépen köszönöm a segítséget!

Nem igazán válasz, de ha csak egy terminált akarsz nyitni, akkor miért nem csinálod meg egy bash scripttel?

Az oka egyedül annyi, hogy így kényelmesebb.
A legtöbb szerverhez egy felhasználói nevet használok, de nem minegyikhez. Hogy milyen szerverekhez csatlakoztam azt is látni akarom a megnyitott terminálablakok fejlécén. Szkriptet vagy megírom úgy, hogy felhasználói neveket rendelem a hosztokhoz, vagy pedig mindig megadom paraméterben. Az első változat azért nem jó, mert akkor lesz egy baromi hosszú szkriptem, amit karban kell tartani, második eset meg azért, mert lusta vagyok annyit gépelni minden egyes bejelentkezésnél.
GTK+-s progi pont azért jó számomra, mert az esetek nagy részében csak átírom a hosztnevet, és már csatlakozom is.

Erdekes egyszer en is irtam egy hasonlo programot, ahol szerver elereseket taroltam, es combo kivalasztas alapjan vagy terminal-ban vagy nautilus-ban nyitogatta a szervereket. Aztan sosem fejeztem be.
Nem tudom mennyire elavult, libgnome-ban voltak gnome_execute_* fuggvenyek. Ha tisztan gtk+ alkalmazasra vagysz, akkor a mar emlitett system().