Bienvenido(a), Visitante. Por favor, ingresa o regístrate.
¿Perdiste tu email de activación?
26-09-2017, 00:31 (Martes)
Inicio Ayuda Reglas Buscar Ingresar Registrarse
Noticias:
Liberada wifislax64-1.1 version final para descargar

Videos Downloader




+  Seguridad Wireless - Wifi
|-+  General
| |-+  Programación (Moderador: vk496)
| | |-+  [TALLER] Interfaces gráficas con GTK+ y C
0 Usuarios y 1 Visitante están viendo este tema. « anterior próximo »
Páginas: [1] Ir Abajo Imprimir
Autor Tema: [TALLER] Interfaces gráficas con GTK+ y C  (Leído 7451 veces)
5.1
Colaborador
*
Desconectado Desconectado

Mensajes: 523


@352E31


Ver Perfil
« : 28-07-2015, 16:37 (Martes) »

ACLARACIONES
Antes de nada, me gustaría aclarar algunas cosas.
De entrada esto no pretende ser un curso, mis conocimientos no son los suficientemente avanzados para dar lecciones a nadie, por eso he decidido titularlo Taller, ya que lo único que pretendo aquí es compartir lo que he aprendido estos últimos meses, mis dudas y seguramente mis errores.
Soy un usuario autodidacta y me gusta la programación, pero no me considero un programador, no vivo de ello.
Desde mi punto de vista, hay dos formas de enfocar este taller, una sería pegaros una parrafada técnica, y la segunda desarrollar un programa desde el principio, que me parece una forma mucho más amena de aprender y con la cual obtendremos resultados inmediatos, así que me he decantado por esta segunda opción.
Voy a intentar explicarlo todo con el lenguaje menos técnico posible, aún así, si no sabes ni lo que es una variable quizá este taller no este enfocado para ti.
Aclarado estos punto empezamos.

INTRODUCCION
Lo que aquí haremos sera desarrollar un programa en C, con una GUI(Graphical user interface) basada en la biblioteca GTK (The GIMP Toolkit), estaría bien que echaras un vistazo a este enlace de Wikipedia para ayudar a entender que es GTK.
Simplificando, GTK es una biblioteca que contiene una serie de objetos (Widgets) que podemos usar para el desarrollo de nuestra GUI, un ejemplo de estos pueden ser Labels, Buttons, RadioButtons, CheckButtons, etc ...
Os dejo un enlace a la Galería de Widgets de GTK+3, de cara a que veáis todos los posibles objetos que podemos utilizar.
Básicamente se dividen en dos clases, una serian los contenedores, que como ya indica su nombre son objetos que contienen otros widgets, y la otra los Widgets con los que interactuamos en una GUI.
Por ejemplo, un Frame seria un contenedor que podría contener un botón, un label ... Echad un vistazo a la galería y lo tendréis más claro.
Si hay un interés por este taller y me quedan ganas, más adelante haremos otro con Bash + GtkDialog, algo muy útil también.
Bueno, ya he pegado la parrafada inicial, así que vamos a lo divertido Smiley

DESARROLLANDO UN PROGRAMA SENCILLO CON GTK + C
Para empezar este taller vamos a desarrollar un sencillo programa que me pidió USUARIONUEVO, se trata de una aplicación que nos calcule el tamaño de un diccionario, tiempo en procesarlo, y número de palabras en función de la cantidad de caracteres que queramos emplear y la longitud de la contraseña a descifrar.

A la hora de hablar del código, voy a estructurarlo en 4 partes :

  - Includes : Serían las declaraciones a otros ficheros necesarios en nuestro código.
  - Declaración de funciones : La parte donde declararemos cada una de las funciones que emplearemos.
  - Variables globales : Aquí declararemos las variables que usaremos desde las distintas funciones.
  - Las funciones : Las diferentes funciones que necesitaremos.

Bien, lo primero que necesitamos es un archivo en el cual escribiremos el código necesario y un editor de texto, en mi caso usare KWrite. Así pues, creamos un archivo de texto que renombraremos a dicciocalc.c y lo abrimos con el editor que elijamos.

Lo primero que tendremos que escribir, sera el include a las biblioteca GTK, por lo que la primera linea de nuestro código será :

Código:
#include <gtk/gtk.h>
Con esto le estaremos diciendo al compilador que incluya el archivo gtk.h en la compilación de nuestra aplicación.

A continuación vamos a empezar con la función main, la cual suele ser el punto de entrada en un programa escrito en C
Código:
int main(int argc, char *argv[])
{
}

Ahora empezamos a escribir el código de la función main. Cualquier programa que utilice GTK requiere de las siguiente linea de código inicial, la cual se encarga de inicializar la biblioteca GTK+
Código:
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
}

Una vez inicializado GTK podremos empezar a diseñar la interface, aunque de momento saltamos esto, y pasamos a las lineas en las que acaba el diseño de la interface y la mostramos en pantalla.
Código:
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);

// Codigo del diseño ....

gtk_widget_show_all (window);
gtk_main ();
}
Si os fijáis, estas dos últimas lineas que he añadido, lo que hacen es primero mostrar todos los widgets que hemos añadido y a continuación con la siguiente línea de código entra en un loop (bucle) esperando a las señales emitidas por los widgets para realizar la acción requerida.
Para aclarar esto os pongo un ejemplo, el programa se muestra en pantalla y entra en el loop (gtk_main), entonces nosotros apretamos un botón de la GUI, en ese momento se produce una señal (evento click) y se desarrolla la acción que hayamos definido al apretar ese botón.
Cuando conectemos señales a sus respectivas funciones lo veréis mucho más claro.

Bien, ahora empecemos a el diseño en sí de la interface. Lo primero que tenemos que añadir es la ventana padre (la de nivel superior), resumiendo es la ventana que contendrá el resto de los widgets.
En cuanto la creemos y compilemos veréis el resultado y lo tendréis claro a que me refiero.

En GTK, los widgets a usar hay que declararlos antes de usarlos, como haríamos con una variable de cualquier tipo. Si nosotros declaramos un Widget (o una variable) dentro de una función, sólo será accesible desde la propia función, y si queremos acceder al Widget (o la variable) desde una función diferente nos dará un error de compilación.
La solución a esto es declarar el Widget o variable en la zona que comente al principio, la de variables globales.
En el caso de la ventana padre, sólo accederemos a ella desde la función main, por lo que la declararemos dentro de esa función. Podemos declararla en cualquier parte del código antes de usarla, pero por mantener un orden todas las declaraciones dentro de una función las haremos al principio de esta.
Por lo tanto, nuestro código quedaría así :

Código:
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
// Esta es la línea que declara e inicializa el Widget llamado window
GtkWidget *window = NULL;

gtk_init(&argc, &argv);

// Codigo del diseño ....

gtk_widget_show_all (window);
gtk_main ();
}
Aclarar que el nombre del Widget declarado es window, simplemente por facilitar la comprensión del código, pero en realidad podemos llamarlo de cualquier manera, ya que no definimos el tipo de widget hasta que no lo creamos, recordad, de momento sólo estamos haciendo el paso previo a la creación, la declaración.

Una vez declarado, vamos a crear la ventana (window)

Código:
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
// Esta es la línea que declara e inicializa el Widget llamado window
GtkWidget *window = NULL;

gtk_init(&argc, &argv);

// EN ESTE BLOQUE DIBUJAMOS LA VENTANA PRINCIPAL
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
//Conecto la señal de cerrar ventana a cerrar el programa
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
// Le digo que al iniciar la ventana esté centrada en la pantalla
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);  
// Defino el título de la ventana
gtk_window_set_title (GTK_WINDOW (window), "DICCIOCALC");
// Defino el borde de la ventana
gtk_container_set_border_width (GTK_CONTAINER (window), 6);
// Defino el tamaño inicial (y será el mínimo)
gtk_widget_set_size_request(window, 350, 350);


// Resto del código de diseño ...

gtk_widget_show_all (window);
gtk_main ();
}

Bien, ahora paso a comentar linea por linea lo que hemos añadido

Código:
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
Aquí estamos diciendo que el widget que habíamos declarado anteriormente es el Widget Window, y que esta sera la ventana de nivel superior.
Código:
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
Esta línea es muy importante, estamos conectando la señal que se produce al cerrar la ventana (destroy) con la función "gtk_main_quit", esta es una función ya definida en la librería GTK, y lo que hace es finalizar el entrono GTK, ya que si no la finalizáramos quedarían procesos colgados cuando cerramos el programa.
De momento no explico más en profundidad el tema señales, cuando creemos la del botón para lanzar el proceso de calculo, ya me detendré en la explicación. De momento que os quede claro que la señal destroy es imprescindible añadirla al código.
La podríamos enlazar a una función que creemos nosotros y en esa función añadir el gtk_main_quit() , pero de momento para no liar la cosa lo dejamos como está.

Código:
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
Esta línea no requiere mucha explicación, le estamos diciendo que a la hora de mostrar la ventana lo haga en medio de la pantalla.

Código:
gtk_window_set_title (GTK_WINDOW (window), "DICCIOCALC");
Ahora definimos el título de la ventana, en este caso será el nombre que le queramos dar al programa, yo le he llamado DICCIOCALC, pero vamos, podéis poner el que queráis.

Código:
gtk_container_set_border_width (GTK_CONTAINER (window), 6);
La ventanas tienen un borde, y este puede ser del tamaño que nosotros queramos, yo le he puesto un borde de grosor 6, pero vamos, eso al gusto, probad diferentes grosores y lo veréis.

Código:
gtk_widget_set_size_request(window, 350, 350);
Aquí estamos definiendo el tamaño que tendrá la ventana, en principio si no añadimos esta línea, la ventana se ajusta al tamaño de los diferentes widgets que contenga.


Bueno,  hemos visto algunas de las posibilidades que tenemos a la hora de crear un widget Window, pero podemos definir muchas otras características de la ventana. Recomiendo ver la lista completa aqui.

Llegados a este punto ya podemos compilar nuestro programa y ver los primeros resultados.

Para compilarlo :

Código:
gcc dicciocalc.c -o dicciocalc `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`

Vamos a ejecutarlo
Código:
./dicciocalc

Deberíamos ver algo como esto :


Vale, ya tenemos lo que sería el inicio de cualquier programa basado en GTK, es decir, la inclusión de la biblioteca GTK, la función main con la declaración y la creación de la ventana principal.
Ahora es necesario un pequeño descanso para plantearse que necesitamos en nuestra interface.
Existen diseñadores de interfaces de GTK, como por ejemplo Glade, pero a mi no me acaba de convencer, aunque puede ser útil para hacer un diseño de como queremos que quede la interface.
En este caso, al ser una GUI sencilla lo podemos hacer imaginando o sobre el papel.
De entrada nos tenemos que plantear que objectos vamos a necesitar, en el caso de el programa que estamos desarrollando sería lo siguiente.

Yo lo he dividido en tres secciones, y para cada sección emplearemos un contenedor frame

Sección Longitud de la contraseña, a la que añadiremos un spin button con números.
Sección de juego de caracteres, a la que añadiremos diferentes check buttons, uno para las Mayúsculas, otro para Minúsculas, otro para Caracteres Numéricos y finalmente uno para otros caracteres. A este último también le añadiremos otro spin button con números para indicar la cantidad de otros caracteres a emplear.
Sección de contraseñas por segundo, a le que añadiremos un Entry de cara a introducir la cantidad de contraseñas por segundo que es capaz de procesar tu ordenador.
Por último, fuera de estas secciones con frames, añadiremos un boton de cara a lanzar el proceso para los cálculos, y tres labels que nos mostrarán los resultados de los cálculos.

Iremos añadiendo sección a sección y compilando de cara a que vayáis viendo los avances que hacemos ...
De cara a no estar posteando el código fuente a cada momento, todas las líneas de código a partir de ahora y hasta nuevo aviso irán a continuación de la linea "gtk_widget_set_size_request(window, 350, 350);" que es la que empleamos para definir el tamaño de la ventana.

Realmente, antes de empezar con la primera sección, he de puntualizar un detalle. En realidad lo primero que hemos de añadir a la ventana, es un vertical box (vbox), que es un contenedor invisible, pero que hace que los widgets añadidos al vbox se vayan agregando de forma vertical.
Si en un momento dado necesitamos que en una misma línea se añadan dos widgets de forma horizontal, añadiríamos un horizontal box (hbox) y a este le añadiríamos los widgets que deseamos. Lo iréis viendo más claro a medida que lo hagamos.

Entonces lo primero será añadir un vbox a la ventana creada, para ello lo primero sería definir el widget, por lo que a continuación de la línea donde declaramos el widget window debemos añadir la declaración del vbox.
Nos quedaría así ...

Código:
// Esta línea ya la pusimos antes
GtkWidget *window = NULL;
// A continuación añadimos
GtkWidget *vbox;

Bien, ya la tenemos declarada, ahora hay que crear y empaquetar el vbox

Código:
// Esta línea ya la teníamos
gtk_widget_set_size_request(window, 350, 350);
//Ahora a continuación
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);

Explico las líneas que hemos añadido ...
Código:
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
Le estamos diciendo que el widget que hemos declarado con el nombre de vbox, es un "box" (caja) con orientación vertical, y el 0 indicaría que no deje ningún espacio adicional con los widgets que empaquetemos dentro de ese vbox.
Si queréis ver todas las características de un box, leed esto

Código:
gtk_container_add (GTK_CONTAINER (window), vbox);
Bien, merece la pena explicar un poco esta linea. Hasta el momento teníamos una ventana que es un GTK_WINDOW, bien, esta ya de por si es un widget de tipo contenedor, es decir, que puede contener a otros widgets.
A la hora de añadir widgets a un contenedor, podemos hacerlo de dos formas diferentes, una sería con gtk_container_add y la otra con gtk_box_pack_start. La diferencia entre una y la otra es que la segunda tiene más opciones de "configuración", ya la explicaré un poco más adelante cuando la usemos, de momento me centro en la que usamos en esta línea de código, gtk_container_add.
La declaración de esta sería
Código:
void gtk_container_add (GtkContainer *container, GtkWidget *widget);  // OJO, esto NO tenemos que añadirlo a nuestro código, simplemente es con carácter informativo que lo pongo aquí
Es decir, en el primer parámetro de indicamos a que tipo de container lo vamos a añadir, y con el segundo le indicamos el widget a añadir, en este caso estamos añadiendo a la ventana principal (recordad que la llamamos window) que es del tipo GTK_CONTAINER, un widget al que hemos llamado vbox.
Ahora el contenedor al que deberemos añadir los siguientes widgets sería este vbox, enseguida lo comprobareis.

Añadiendo la primera sección (Longitud de la contraseña)
Bien, ahora que ya tenemos la ventana creada y su vertical box, vamos a añadir el primer frame, para ello lo primero es la declaración de dicho frame.
Código:
// Estas 2 líneas ya las teniamos
GtkWidget *window = NULL;
GtkWidget *vbox;
// A continuación añadimos
GtkWidget *frame_longitud;
Como podéis ver hemos declarado un widget con el nombre frame_longitud. Lo he llamado así porque como después crearemos otros frames, para no liarnos le he agregado el nombre de la sección que estamos creando, en este caso como estamos haciendo la parte donde ingresaremos la longitud de la contraseña, pues eso, longitud.

Ya lo tenemos declarado, ahora toca crear el widget.
Código:
// Esta línea ya la teníamos
gtk_container_add (GTK_CONTAINER (window), vbox);
//Ahora a continuación
frame_longitud = gtk_frame_new ("  LONGITUD DE LA CONTRASEÑA  ");
gtk_container_add(GTK_CONTAINER(vbox), frame_longitud);
Aquí veis que hemos creado un nuevo frame, llamado  frame_longitud, y con el título "LONGITUD DE LA CONTRASEÑA" , y a continuación lo hemos añadido al vbox con gtk_container_add
Fijaros bien, que ahora no lo hemos añadido a window, lo estamos añadiendo a vbox, el vertical box que creamos en la ventana superior (window).

Bien, ahora tocaría añadir un nuevo vertical box, pero esta vez al frame_longitud, como siempre para ello lo primero sería la declaración del widget.
Código:
// Ahora no creo una linea nueva, lo añado a continuación de la declaración de vbox.
GtkWidget *window = NULL;
GtkWidget *vbox, *vbox_long;
GtkWidget *frame_longitud;
Bien, por mantener un mínimo orden, he declarado el widget vbox_long a continuación de vbox. Podemos añadir en una linea todos los que queramos, yo los separo por clases por mantener un orden, en este caso todos los vertical box en la misma línea.
Y como antes, los widgets que agreguemos en este frame, los añadiremos a este nuevo vertical box (vbox_long).

Una vez declarado, toca añadirlo.
Código:
// Esta líneas ya las teníamos
frame_longitud = gtk_frame_new ("  LONGITUD DE LA CONTRASEÑA  ");
gtk_container_add(GTK_CONTAINER(vbox), frame_longitud);
// Ahora agregamos el vbox_long al frame_longitud
vbox_long = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame_longitud), vbox_long);
Es lo mismo que explique antes, hemos creado un box vertical, y lo hemos añadido a su contenedor inmediatamente superior, en este caso frame_longitud.

Ahora y como último paso en esta sección de la longitud de la contraseña, vamos a añadir un spin button, que contendrá números del 1 al 100 de cara a indicar el tamaño que tendrá la contraseña que queremos averiguar.
Una vez más el primer paso es la declaración, pero aquí la cosa cambia. En este caso, cuando pulsemos el botón para hacer los calculos necesario (tamaño del diccionario, número de palabras etc..), el control del programa pasará a otra función distinta a main, por lo que como os explique al principio si declaramos el spin button en la función main, al intentar acceder a ella desde la función calcular nos dará un error. Por tanto vamos a declarar este spin button en la zona de la que hablé al principio, la de las variables globales.

La cosa quedaría así :
Código:
// El include a la libería ya lo teniamos ...
#include <gtk/gtk.h>

// Aquí irá una parte del código en la cual declararemos las funciones que aún tenemos que crear

// Y aquí pondríamos las declaraciónes globales
GtkWidget *spinner_long;
Es exactamente lo mismo que hemos estado haciendo hasta ahora para la declaración de los widgets, pero en una zona diferente del código. En este caso hemos declarado el widget con el nombre "spinner_long".
Una vez más insisto que el nombre que le pongamos a un widget cuando lo declaramos no define el tipo de widget que será, pero es conveniente poner un nombre acorde a lo que queremos crear de cara a una fácil comprensión del código.

Tal como funciona un spin button, para crearlo tenemos que pasarle una serie de parametros, y para ello necesitamos crear un nuevo objeto, un GtkAdjustment, el cual contendrá una serie de parámetros que ahora explicaré y que aplicaremos a nuestro spin button.

Igual que siempre, lo primero es declararlo, esta vez como no necesitamos acceder a el desde otras funciones lo haremos donde hemos hecho el resto de declaraciones en la función main.
Código:
// Esto es lo que teniamos hasta ahora
GtkWidget *window = NULL;
GtkWidget *vbox, *vbox_long;
GtkWidget *frame_longitud;
// Ahora declaro en GtkAdjustment
GtkAdjustment *spinner_adj;
Tan sólo comentar que en este caso no lo declaramos como un GtkWidget, si no como GtkAdjustment..

Una vez declarados el spin button y el GtkAdjustment toca añadirlos al vbox_long (que es el vertical box que agreramos al frame_longitud).

Código:
// Esto era lo último que habíamos añadido
vbox_long = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame_longitud), vbox_long);
// Ahora toca crear el spinner, aplicar los ajustes y mostrarlo
spinner_adj = (GtkAdjustment *) gtk_adjustment_new (8.0, 1.0, 100.0, 1.0, 1.0, 1.0);
spinner_long = gtk_spin_button_new (spinner_adj, 1.0, 0);
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinner_long), TRUE);
gtk_box_pack_start (GTK_BOX(vbox_long), spinner_long, FALSE, FALSE, 0);

Paso a explicar cada línea de lo que acabamos de añadir
Código:
spinner_adj = (GtkAdjustment *) gtk_adjustment_new (8.0, 1.0, 100.0, 1.0, 1.0, 1.0);
Acabamos de crear el objeto que declaramos antes, que llamamos spinner_adj, y le estamos diciendo que es un nuevo GtkAdjustment con las siguientes características :
     - Valor inicial : 8
     - Valor mínimo : 1
     - Valor máximo 100
     - Incremento mínimo en una pulsación: 1
     - Incremento máximo en una pulsación: 1
     - El último valor sinceramente no lo entiendo muy bien, pero ajustándolo a 1 funciona como queremos que funcione.
Aquí teneis al detalle la declaración de gtk_adjustment_new().

Código:
spinner_long = gtk_spin_button_new (spinner_adj, 1.0, 0);
Ahora ya estamos creando el spin button, le pasamos el GtkAdjustment que hemos creado, el incremento u por último el número de decimales a mostrar, en este caso será 0 ya que no necesitamos valores con decimales.
Aquí tenéis al detalle la declaración de gtk_spin_button_new

Código:
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinner_long), TRUE);
Le estamos diciendo que el GTK_SPIN_BUTTON spinner_long (el que estamos añadiendo) sea solo numérico.

Código:
gtk_box_pack_start (GTK_BOX(vbox_long), spinner_long, FALSE, FALSE, 0);
Aqí estamos usando la otra forma de añadir wigets que comenté anteriormente. Por un lado teníamos gtk_container_add que es la que habiamos usado hasta ahora, y por otro lado esta que acabamos de utilizar. Como ya dije antes esta forma tiene más control sobre como mostramos el widget en cuestión.
Podéis ver la declaración al detalle aquí
Bien, en este caso estamos diciendo que empaquete en el contenedor vbox_long, el widget spinner_long, que no se expanda, ni ocupe todo el espacio cuando cambiamos el tamaño de la ventana, y que no deje espacio (en píxeles) con su contenedor. La mejor forma de entender esto es ir cambiando los valores FALSE a TRUE e ir haciendo pruebas compilando y ejecutándolo.

Llegados a este punto ya tenemos la sección de la Longitud de la Contraseña creada totalmente, ahora podemos compilar y probar como tenemos el programa hasta ahora.

El código completo hasta ahora debería quedaros así.
Código:
#include <gtk/gtk.h>

//Declaraciones globales
GtkWidget *spinner_long;

int main(int argc, char *argv[])
{
// Declaraciones
GtkWidget *window = NULL;
GtkWidget *vbox, *vbox_long;
GtkWidget *frame_longitud;
GtkAdjustment *spinner_adj;

gtk_init(&argc, &argv);

// EN ESTE BLOQUE DIBUJAMOS LA VENTANA PRINCIPAL
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
//Conecto la señal de cerrar ventana a cerrar el programa
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
// Le digo que al iniciar la ventana esté centrada en la pantalla
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);  
// Defino el título de la ventana
gtk_window_set_title (GTK_WINDOW (window), "DICCIOCALC");
// Defino el borde de la ventana
gtk_container_set_border_width (GTK_CONTAINER (window), 6);
// Defino el tamaño inicial (y será el mínimo)
gtk_widget_set_size_request(window, 350, 350);

//AÑADO UN VERTICALBOX PARA CONTENER LOS WIDGETS
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);


//AÑADO UN FRAME PARA LA LONGTUD DE LA CONTRASEÑA
frame_longitud = gtk_frame_new ("  LONGITUD DE LA CONTRASEÑA  ");
gtk_container_add(GTK_CONTAINER(vbox), frame_longitud);
// Añado un vbox al frame
vbox_long = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame_longitud), vbox_long);
//Añado el spinner al vbox
spinner_adj = (GtkAdjustment *) gtk_adjustment_new (8.0, 1.0, 100.0, 1.0, 1.0, 1.0);
spinner_long = gtk_spin_button_new (spinner_adj, 1.0, 0);
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinner_long), TRUE);
gtk_box_pack_start (GTK_BOX(vbox_long), spinner_long, FALSE, FALSE, 0);

// Resto del código de diseño ...

gtk_widget_show_all (window);
gtk_main ();
return 0;
}

Recordad, para compilar :
Código:
gcc dicciocalc.c -o dicciocalc `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`


Al ejecutarlo ...


Bien, ya tenemos la primera sección, vamos a por la segunda, "Juego de caracteres".
Tenemos que añadir un nuevo frame, así que como siempre, lo primero declararlo. Y como sólo accederemos a el desde el main, pues es en esa función que lo declaramos.

Código:
// Declaraciones
GtkWidget *window = NULL;
GtkWidget *vbox, *vbox_long;
GtkWidget *frame_longitud, *frame_chars;
GtkAdjustment *spinner_adj;

Fijaros que lo he declarado a continuación del frame que ya teniamos, y lo he hecho con el nombre de frame_chars.

Ahora toca agregar el código para agregarlo.
Código:
// Estas dos líneas es lo último que teniamos
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinner_long), TRUE);
gtk_box_pack_start (GTK_BOX(vbox_long), spinner_long, FALSE, FALSE, 0);
//Ahora añadimos lo siguiente
frame_chars = gtk_frame_new ("  JUEGO DE CARACTERES  ");
gtk_box_pack_start (GTK_BOX (vbox), frame_chars, FALSE, FALSE, 10);
Es lo mismo que ya habiamos hecho antes, la única diferencia es que si os fijáis a la hora de empaquetarlo dejamos una separación de 10 pixeles con el frame que ya teniamos creado.

Lo mismo que en el frame anterior, ahora toca crear un vertical box de cara a añadir a el los widgets necesarios de esta sección, por tanto lo primero ya sabeis que es, declarar ese vertical box, y una vez más, lo haremos en la función main.
Código:
// Declaraciones
GtkWidget *window = NULL;
GtkWidget *vbox, *vbox_long, *vbox_chars;
GtkWidget *frame_longitud, *frame_chars;
GtkAdjustment *spinner_adj;
No hay mucho que comentar, hemos declarado dicho vertical box con el nombre de vbox_chars.

Como siempre el procedimiento es el mismo, declaramos, creamos y empaquetamos, por tanto :
Código:
// Estas dos líneas es lo último que teniamos
frame_chars = gtk_frame_new ("  JUEGO DE CARACTERES  ");
gtk_box_pack_start (GTK_BOX (vbox), frame_chars, FALSE, FALSE, 10);
//Una vez mas primero lo creamos y luego lo añadimos.
vbox_chars = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame_chars), vbox_chars);

Si os dais cuenta siempre es lo mismo, habíamos declarado un frame, lo creamos y empaquetamos. Ahora hemos declarado un vertical box, lo creamos y lo agregamos a ese frame, y a partir de ahora los widgets que agreguemos lo haremos a este vbox_chars.

En esta sección será la que le digamos al programa que juegos de caracteres usar para que haga los calculos del diccionario que podriamos crear con ellos (los juegos de caracteres). Por lo tanto necesitamos :
   - Un check button que llamaremos opcion_alfa_mayusculas.
   - Un check button que llamaremos opcion_alfa_minusculas.
   - Un check button que llamaremos opcion_numeros.
   - Un check button que llamaremos opcion_otros.
   - Un spin button que llamaremos spinner_chars.

Empezamos con las declaraciones, pero en este caso necesitaremos acceder a estos widgets desde otra función diferente a main, por lo que tenemos que declararlos en la zona de variables globales (Al principio del código)...
Esto es lo que teníamos
Código:
//Declaraciones globales
GtkWidget *spinner_long;
Nos quedará así
Código:
//Declaraciones globales
GtkWidget *spinner_long, *spinner_chars;;
GtkWidget *opcion_alfa_mayusculas, *opcion_alfa_minusculas, *opcion_numeros, *opcion_otros;
A estas alturas no creo que sea necesario explicar lo que hemos hecho, ya debería estar claro como se declara un widget.

Una vez más, ahora toca crear y agregar los widgets creados...
Código:
// Lo último que habiamos puesto era la creacion y empaquetado del vbox_chars en el frame
vbox_chars = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame_chars), vbox_chars);
// Ahora creamos y empaquetamos los widgets en ese vbox_chars

//Añadimos los checkbox alfabeticos
opcion_alfa_mayusculas = gtk_check_button_new_with_label("Mayúsculas (A-Z)");
gtk_box_pack_start (GTK_BOX (vbox_chars), opcion_alfa_mayusculas, FALSE, FALSE, 3);

opcion_alfa_minusculas = gtk_check_button_new_with_label("Minúsculas (a-z)");
gtk_box_pack_start (GTK_BOX (vbox_chars), opcion_alfa_minusculas, FALSE, FALSE, 3);

opcion_numeros = gtk_check_button_new_with_label("Numérico (0-9)");
gtk_box_pack_start (GTK_BOX (vbox_chars), opcion_numeros, FALSE, FALSE, 3);
Bien, de momento sólo añadimos 3 de los 4, ya que el de "opcion_otros" es un tanto especial, ahora lo veréis.
En los tres ya añadidos es lo mismo, lo hemos creado con el texto correspondiente a cada uno (o sea Mayúsculas A-Z, Minuscúlas a-z, etc ..) y hemos dejado un espacio de 3 pixeles entre ellos a la hora de empaquetarlos con gtk_box_pack_start.
Como mucho decir que os fijéis en que cuando empaquetamos siempre le decimos que lo haga a vbox_chars.

Ahora toca el ocion_otros, pero este tiene una característica especial, y es que al lado del check button , tenemos que añadir un spin button.
¿ Y cómo hacemos esto ? Muy sencillo, igual que hasta ahora para poner un widget debajo del siguiente habíamos creado un vertical box y añadido los widgets a este, ahora vamos a crear un horizontal box (le llamaremos hbox), añadiremos este hbox al vbox_chars, y después añadiremos el opcion_otros y el spin button a este hbox, de manera que en una misma línea horizontal nos aparezcan los dos widgets.

Por enésima vez, lo primero declarar el horizonal box, en este caso en la zona de declaraciones del main.
Código:
// Declaraciones
GtkWidget *window = NULL;
GtkWidget *vbox, *vbox_long, *vbox_chars;
GtkWidget *frame_longitud, *frame_chars;
GtkAdjustment *spinner_adj;
// Agregamosla declaración del hbox
GtkWidget *hbox;

Y repetimos el proceso de siempre, creación y empaquetado.
Código:
// Lo último que habiamos puesto era la creacion y empaquetado de la  opcion_numeros
opcion_numeros = gtk_check_button_new_with_label("Numérico (0-9)");
gtk_box_pack_start (GTK_BOX (vbox_chars), opcion_numeros, FALSE, FALSE, 3);

// Ahora le toca al hbox recién declarado
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add (GTK_CONTAINER (vbox_chars), hbox);
Fijaros que en vez de decirle que cree el box de forma vertical ( GTK_ORIENTATION_VERTICAL) lo hemos hecho pasándole el argumento para que lo haga de forma horizontal con GTK_ORIENTATION_HORIZONTAL, y lo hemos añadido al vbox_chars. Ahora tan solo queda añadir lo que nos queda de esta sección al hbox.
Código:
// Lo último que habiamos puesto era la creacion y empaquetado del  hbox
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add (GTK_CONTAINER (vbox_chars), hbox);

// Ahora añadimos los widgets que nos faltan, ya sabéis, primero creamos y luego empaquetamos.
opcion_otros = gtk_check_button_new_with_label("Otros carácteres (Indicar número)");
gtk_box_pack_start (GTK_BOX (hbox), opcion_otros, FALSE, FALSE, 0);

spinner_adj = (GtkAdjustment *) gtk_adjustment_new (10.0, 1.0, 40.0, 1.0, 1.0, 1.0);
spinner_chars = gtk_spin_button_new (spinner_adj, 1.0, 0);
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinner_chars), TRUE);
gtk_box_pack_start (GTK_BOX(hbox), spinner_chars, FALSE, FALSE, 5);
Hemos agregado el checkbutton con las dos primeras líneas. A continuación definimos los ajustes del spinner tal como hicimos antes con el spinner de la longitud de contraseña, le decimos que solo sea numérico y empaquetamos. Daros cuenta que estos dos últimos widgets los hemos agregado al hbox para que nos aparezcan de forma horizontal, dejando un espacio entre ellos de 5 pixeles.

Bueno, pues ya hemos acabado otra sección, os pongo el código completo hasta ahora.

Código:
#include <gtk/gtk.h>

//Declaraciones globales
GtkWidget *spinner_long, *spinner_chars;;
GtkWidget *opcion_alfa_mayusculas, *opcion_alfa_minusculas, *opcion_numeros, *opcion_otros;

int main(int argc, char *argv[])
{
// Declaraciones del main
GtkWidget *window = NULL;
GtkWidget *vbox, *vbox_long, *vbox_chars;
GtkWidget *frame_longitud, *frame_chars;
GtkAdjustment *spinner_adj;
GtkWidget *hbox;

gtk_init(&argc, &argv);

// EN ESTE BLOQUE DIBUJAMOS LA VENTANA PRINCIPAL
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
//Conecto la señal de cerrar ventana a cerrar el programa
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
// Le digo que al iniciar la ventana esté centrada en la pantalla
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);  
// Defino el título de la ventana
gtk_window_set_title (GTK_WINDOW (window), "DICCIOCALC");
// Defino el borde de la ventana
gtk_container_set_border_width (GTK_CONTAINER (window), 6);
// Defino el tamaño inicial (y será el mínimo)
gtk_widget_set_size_request(window, 350, 350);

//AÑADO UN VERTICALBOX PARA CONTENER LOS WIDGETS
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);


//AÑADO UN FRAME PARA LA LONGTUD DE LA CONTRASEÑA
frame_longitud = gtk_frame_new ("  LONGITUD DE LA CONTRASEÑA  ");
gtk_container_add(GTK_CONTAINER(vbox), frame_longitud);
// Añado un vbox al frame
vbox_long = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame_longitud), vbox_long);
//Añado el spinner al vbox
spinner_adj = (GtkAdjustment *) gtk_adjustment_new (8.0, 1.0, 100.0, 1.0, 1.0, 1.0);
spinner_long = gtk_spin_button_new (spinner_adj, 1.0, 0);
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinner_long), TRUE);
gtk_box_pack_start (GTK_BOX(vbox_long), spinner_long, FALSE, FALSE, 0);


//AÑADO UN FRAME PARA LOS JUEGOS DE CARACTERES
frame_chars = gtk_frame_new ("  JUEGO DE CARACTERES  ");
//gtk_container_add(GTK_CONTAINER(vbox), frame_chars);
gtk_box_pack_start (GTK_BOX (vbox), frame_chars, FALSE, FALSE, 10);
// Añado un vbox al frame
vbox_chars = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (frame_chars), vbox_chars);
//Añadimos los checkbox alfabeticos
opcion_alfa_mayusculas = gtk_check_button_new_with_label("Mayúsculas (A-Z)");
gtk_box_pack_start (GTK_BOX (vbox_chars), opcion_alfa_mayusculas, FALSE, FALSE, 3);

opcion_alfa_minusculas = gtk_check_button_new_with_label("Minúsculas (a-z)");
gtk_box_pack_start (GTK_BOX (vbox_chars), opcion_alfa_minusculas, FALSE, FALSE, 3);

opcion_numeros = gtk_check_button_new_with_label("Numérico (0-9)");
gtk_box_pack_start (GTK_BOX (vbox_chars), opcion_numeros, FALSE, FALSE, 3);

//Añado un hbox
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add (GTK_CONTAINER (vbox_chars), hbox);

// Añado el opcion_otros y el spinner_chars al hbox
opcion_otros = gtk_check_button_new_with_label("Otros carácteres (Indicar número)");
gtk_box_pack_start (GTK_BOX (hbox), opcion_otros, FALSE, FALSE, 0);

spinner_adj = (GtkAdjustment *) gtk_adjustment_new (10.0, 1.0, 40.0, 1.0, 1.0, 1.0);
spinner_chars = gtk_spin_button_new (spinner_adj, 1.0, 0);
gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spinner_chars), TRUE);
gtk_box_pack_start (GTK_BOX(hbox), spinner_chars, FALSE, FALSE, 5);


// Resto del código de diseño ...


gtk_widget_show_all (window);
gtk_main ();
return 0;
}

Si compilamos tendremos esto :





En construcción, to be continued ...
« Última modificación: 31-07-2015, 12:19 (Viernes) por 5.1 » En línea

Qui non intelligit aut taceat aut discat
5.1
Colaborador
*
Desconectado Desconectado

Mensajes: 523


@352E31


Ver Perfil
« Respuesta #1 : 28-07-2015, 16:37 (Martes) »

Ya que no puedo moderar esta sección del foro, reservo este post ....
En línea

Qui non intelligit aut taceat aut discat
jostey
**
Desconectado Desconectado

Mensajes: 10


Ver Perfil
« Respuesta #2 : 28-07-2015, 17:42 (Martes) »

Me sumo a estos consejos, que a pesar de que estoy estudiando C en este curso, aun no vimos nada con interfaz gráfica. Ánimo!  Grin
En línea
sanson
Moderador Global
*
Desconectado Desconectado

Mensajes: 8375


Ver Perfil
« Respuesta #3 : 28-07-2015, 22:50 (Martes) »

Ponemos  chincheta y proponemos al jefe que moderes la zona , cosa lógica por otro lado

Eso si , ni un permiso que te vigiló jejjjeje


Editó

A coño que ya esta vk , pensaba que era nueva sección jejejejeje
En línea

5.1
Colaborador
*
Desconectado Desconectado

Mensajes: 523


@352E31


Ver Perfil
« Respuesta #4 : 28-07-2015, 23:08 (Martes) »

Ponemos  chincheta y proponemos al jefe que moderes la zona , cosa lógica por otro lado

Eso si , ni un permiso que te vigiló jejjjeje


Editó

A coño que ya esta vk , pensaba que era nueva sección jejejejeje

Sí sí, que con el movimiento que hay en esta sección se necesitan 2 o 3 moderadores  Grin

Nada, si necesito que se borre/edite/mueva  algo del post, ya se lo diré a vk, pero vamos, no creo que este muy concurrido este hilo ...
En línea

Qui non intelligit aut taceat aut discat
sanson
Moderador Global
*
Desconectado Desconectado

Mensajes: 8375


Ver Perfil
« Respuesta #5 : 28-07-2015, 23:27 (Martes) »

Sino , siempre tienes el reporte y lo recibimos todos , así te garantizas cobertura
En línea

vk496
Moderador
*
Desconectado Desconectado

Mensajes: 2192



Ver Perfil WWW
« Respuesta #6 : 29-07-2015, 01:08 (Mi?rcoles) »

Jo, llego tarde. Me hacia ilusión hacer mi primera chincheta Sad

(Voy a conspirar contra @sanson en secreto a partir de hoy)

jajajajajaja

Muchas gracias por tu aporte 5.1 . Veo muchas horas invertidas en este hilo. En cuanto saque tiempo, lo leo.

Estaré atento al siguiente!

Salu2
En línea
sanson
Moderador Global
*
Desconectado Desconectado

Mensajes: 8375


Ver Perfil
« Respuesta #7 : 29-07-2015, 01:29 (Mi?rcoles) »

@vk496
Pues nada hombre , se quita y ya esta jejeje
En línea

vk496
Moderador
*
Desconectado Desconectado

Mensajes: 2192



Ver Perfil WWW
« Respuesta #8 : 29-07-2015, 01:53 (Mi?rcoles) »

@vk496
Pues nada hombre , se quita y ya esta jejeje
Oh dios. Se me sube el poder a la cabeza... xDDDDD

Nota: me cago en Tapatalk. Llevan estos meses cambiando todo. Me he dado cuenta que ya no me saltan notificaciones cuando alguien me menciona....

Salu2
En línea
sanson
Moderador Global
*
Desconectado Desconectado

Mensajes: 8375


Ver Perfil
« Respuesta #9 : 29-07-2015, 01:57 (Mi?rcoles) »

Pues si , muchos cambios , pero las notificaciones a mi si me siguen llegando
En línea

USUARIONUEVO
Colaborador
*
Desconectado Desconectado

Mensajes: 13732



Ver Perfil
« Respuesta #10 : 29-07-2015, 01:59 (Mi?rcoles) »

pss , y lo acabo de ver ,  ... creia que se abria este post en desarrollo, y yo mirando alli ...


muy perdio , me lo leo ahora mismo , gracias.


pues por mas que miro y leo , me suena todo a chino.  Grin
« Última modificación: 29-07-2015, 05:02 (Mi?rcoles) por USUARIONUEVO » En línea

5.1
Colaborador
*
Desconectado Desconectado

Mensajes: 523


@352E31


Ver Perfil
« Respuesta #11 : 29-07-2015, 09:26 (Mi?rcoles) »

...  pues por mas que miro y leo , me suena todo a chino.  Grin

En serio? Míratelo con calma, tú tienes nivel de sobra para entenderlo perfectamente.... y cualquier duda pregunta, que para eso he abierto el hilo ...
Venga va, que me sentiré muy orgulloso si te sirve de algo el taller  Grin
En línea

Qui non intelligit aut taceat aut discat
USUARIONUEVO
Colaborador
*
Desconectado Desconectado

Mensajes: 13732



Ver Perfil
« Respuesta #12 : 30-07-2015, 07:32 (Jueves) »

...  pues por mas que miro y leo , me suena todo a chino.  Grin

En serio? Míratelo con calma, tú tienes nivel de sobra para entenderlo perfectamente.... y cualquier duda pregunta, que para eso he abierto el hilo ...
Venga va, que me sentiré muy orgulloso si te sirve de algo el taller  Grin

el de bash + gtkdialog seguro , pero esto en C , es todo chino para mi.
En línea

sol666
*******
Desconectado Desconectado

Mensajes: 1289



Ver Perfil
« Respuesta #13 : 30-07-2015, 20:19 (Jueves) »

si que es dificil si,yo del cursillo que di en el inem hace unos cuatro años no me acuerdo de nada,solo de que int es entero,printf muestra en pantalla,scanf lee lo que escribes y poco mas,no lleguemos a tanto nivel aparte de que fueron 2 meses de C y 2 meses de java y escribiamos con windows con un programa llamado netbeans que si te dejabas un ; te mostraba donde estaba el error,lleguemos hasta hacer una calculadora.
« Última modificación: 30-07-2015, 20:20 (Jueves) por sol666 » En línea
5.1
Colaborador
*
Desconectado Desconectado

Mensajes: 523


@352E31


Ver Perfil
« Respuesta #14 : 30-07-2015, 20:24 (Jueves) »

si que es dificil si,yo del cursillo que di en el inem hace unos cuatro años no me acuerdo de nada,solo de que int es entero,printf muestra en pantalla,scanf lee lo que escribes y poco mas,no lleguemos a tanto nivel aparte de que fueron 2 meses de C y 2 meses de java y escribiamos con windows con un programa llamado netbeans que si te dejabas un ; te mostraba donde estaba el error,lleguemos hasta hacer una calculadora.

A ver, fácil no es, pero tampoco es tan difícil, te lo aseguro. Si lo lees con calma, vas mirando cada paso, mirando los enlaces que pongo, estoy seguro que lo comprendereis.... evidentemete no es llegar y ya, no, es más complejo que eso, pero no es tan difícil como parece ... yo no había tocado gtk para nada hasta que hice dixiescan, y c no tenía ni idea vamos ...
En línea

Qui non intelligit aut taceat aut discat
USUARIONUEVO
Colaborador
*
Desconectado Desconectado

Mensajes: 13732



Ver Perfil
« Respuesta #15 : 31-07-2015, 01:18 (Viernes) »

te veo to solo  Cool

y es que para alguien que ya sepa C , pues igual , pero sin saber nada de nada , c+gtk  ...   Evil Evil


la intencion es lo que cuenta , sino mira la de posts fijos que hay , y aun asi se hacen las misma preguntas 10.000 veces , como ¿este adaptador vale?,?  ¿cual es el mejor...? ..etc etc etc.
En línea

5.1
Colaborador
*
Desconectado Desconectado

Mensajes: 523


@352E31


Ver Perfil
« Respuesta #16 : 31-07-2015, 10:54 (Viernes) »

te veo to solo  Cool

y es que para alguien que ya sepa C , pues igual , pero sin saber nada de nada , c+gtk  ...   Evil Evil


la intencion es lo que cuenta , sino mira la de posts fijos que hay , y aun asi se hacen las misma preguntas 10.000 veces , como ¿este adaptador vale?,?  ¿cual es el mejor...? ..etc etc etc.

Sí, ya imaginaba que mucha participación no habría en este hilo, pero no es algo nuevo, desde que me registré en el foro siempre ha pasado lo mismo, y desde el 2007 ya ha llovido.... Aún recuerdo la primera herramienta que publiqué en este foro (un script para hacer wardriving cojonudo jejeje, que por cierto, ya no existe) y ya por aquel entonces era lo mismo, todo lo que sea darle a un botón y que te diga una contraseña tiene un alto indice de participación, pero si se trata de entender lo que hace ese botón, ya la cosa cambia, y es desmotivador, pero bueno, es lo que hay.
Muchas veces me pregunto si la "desaparición" de muchos de los mejores usuarios que ha tenido este foro se debe a eso, a la desmotivación por repetir una y otra vez la misma cantinela...

En fin, sea como sea, yo este post lo termino jejejeje.
En línea

Qui non intelligit aut taceat aut discat
USUARIONUEVO
Colaborador
*
Desconectado Desconectado

Mensajes: 13732



Ver Perfil
« Respuesta #17 : 02-08-2015, 22:49 (Domingo) »

creo que se han hido todos de vacaciones.

¿solo le falta el boton ejecutar no?
En línea

5.1
Colaborador
*
Desconectado Desconectado

Mensajes: 523


@352E31


Ver Perfil
« Respuesta #18 : 02-08-2015, 23:03 (Domingo) »

creo que se han hido todos de vacaciones.

¿solo le falta el boton ejecutar no?

Le falta un entry para poder poner las contraseñas que es capaz de procesar tu ordenador cada segundo, el botón ejecutar y lógicamente la función que calcula todo... mañana por la mañana intentaré acabarlo
En línea

Qui non intelligit aut taceat aut discat
USUARIONUEVO
Colaborador
*
Desconectado Desconectado

Mensajes: 13732



Ver Perfil
« Respuesta #19 : 02-08-2015, 23:07 (Domingo) »

creo que se han hido todos de vacaciones.

¿solo le falta el boton ejecutar no?

Le falta un entry para poder poner las contraseñas que es capaz de procesar tu ordenador cada segundo, el botón ejecutar y lógicamente la función que calcula todo... mañana por la mañana intentaré acabarlo

tranqui , ya ves que esto lleva un ritmo frenetico  jajajaja  Grin Grin Grin
En línea

Páginas: [1] Ir Arriba Imprimir 
« anterior próximo »
Ir a:  


Ingresar con nombre de usuario, contraseña y duración de la sesión

Las cookies de este sitio web se usan para personalizar el contenido y los anuncios, ofrecer funciones de redes sociales y analizar el tráfico. Además, compartimos información sobre el uso que haga del sitio web con nuestros partners de redes sociales, publicidad y análisis web, quienes pueden combinarla con otra información que les haya proporcionado o que hayan recopilado a partir del uso que haya hecho de sus servicios
Si continúa navegando consideramos que acepta su uso. OK Más información | Y más
Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines
SMFAds for Free Forums