Mis dudas sobre GTK+ (Python)

Hola a todos. Estoy bastante experimentado en hacer programas con interfaz gráfica en C# (windows) y he decidido aprender a hacer programas con interfaz gráfica en GTK+ (digo yo que será mas fácil teniendo una base, aunque no tenga nada que ver). Estoy usando Python para abstraerme de problemas como punteros y tal. Ayer me leí por encima algunos tutoriales y bueno, es bastante fácil... me defiendo.

Me gustaría tener este hilo para que los que saben del tema me ayuden a resolver las dudas que se me presentan (que serán muy básicas). Y aquí va mi primera duda:

"Colocar" controles en formularios GTK+ (en Python):

Me gustaría saber como puedo especificar la posición y el tamaño de los controles que meto en un formulario. Por ejemplo, para este programa, la ventana que muestra es esta:

Imagen

¿Qué llamadas tengo que incluir para que, por ejemplo, el botón tenga una altura de 10, anchura de 30 y este en la posición 20, 20 (con respecto a la esquina superior izquierda de la ventana)?

Saludos, gracias por vuestras respuestas.
No puedes (mejor dicho, no debes). Deberías aprender cómo funciona Gtk, es mucho más fácil una vez te acostumbras.

- ferdy
Quizá todavía este pensando en .NET... He leido que hay que utilizar Box's para meter los controles, pero claro, el Box también se tendrá que "colocar" ¿no? (y el problema es que no se como hacerlo).

Saludos.
Lo que haces es dividir la ventana en cajas. Si quieres poner, una caja de texto y un botón harás algo así (con dibujos conceptuales + código C):

* Lo primero creas la ventana, y, tendrías:

GtkWidget *w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+-------------------+
|                   |
|                   |
|                   |
|                   |
|                   |
|                   |
|                   |
+-------------------+


* Luego creas los widgets, un botón y una caja de texto.
* Además, creas una vbox (el 2 no es el número de posiciones, no hace falta especificarlo).
* La ventana también es un container de una posición así que añades el vbox a la ventana:

GtkWidget *box = gtk_vbox_new(FALSE, 2);
GtkWidget *t = gtk_text_view_new();
GtkWidget *b = gtk_button_new_with_label("Oh Hai!");
gtk_container_add(GTK_CONTAINER(w), box);

+-------------------+
|                   |
|                   |
|                   |
+-------------------+
|                   |
|                   |
|                   |
+-------------------+


* Lo siguiente es usar las funciones para añadir elementos a una caja, por ejemplo, podemos añadirlos desde arriba hacia abajo:

gtk_box_pack_start(GTK_BOX(box), t, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), b, TRUE, TRUE, 0);

+-------------------+
|                   |
|    CAJA TEXTO     |
|                   |
+-------------------+
|                   |
|       BOTÓN       |
|                   |
+-------------------+


Piensa que puedes meter una HBox dentro de una posición de una VBox y así, poco a poco, ir modelando tu interfaz.

Si, los dibujos son gilipollescos... pero, por alguna razón, a mi me ayudaron a que Gtk hiciera 'click' en mi cabeza :)

- ferdy
Gracias Ferdy por tu ayuda. Ya veo de que va la cosa :).

Dos cosas:

* Creo que no hace falta especificar que la caja vertical se divide en dos (gtk_vbox_new(FALSE, 2)), porque luego puedes añadir tantos controles como quieras, ¿no?.

* Con la solución que propones la caja de texto y el botón son tan anchos como ancha es la caja vertical, si al botón le modifico el tamaño (set_size_request) sólo cambia la altura (la anchura, como he dicho, el la misma que la de la caja).

Se me ha ocurrido meter el botón en una caja horizontal (y esta se coloca en la parte baja de la caja vertical) y así el set_size_request si puede cambiarle la anchura al botón... no se si es "la solución" o es una guarrada :-?.

Saludos.
* Creo que no hace falta especificar que la caja vertical se divide en dos (gtk_vbox_new(FALSE, 2)), porque luego puedes añadir tantos controles como quieras, ¿no?.


En efecto.... edito el post para no crear confusión.

* Con la solución que propones la caja de texto y el botón son tan anchos como ancha es la caja vertical, si al botón le modifico el tamaño (set_size_request) sólo cambia la altura (la anchura, como he dicho, el la misma que la de la caja).

Se me ha ocurrido meter el botón en una caja horizontal (y esta se coloca en la parte baja de la caja vertical) y así el set_size_request si puede cambiarle la anchura al botón... no se si es "la solución" o es una guarrada


Si, es una idea. De todos modos, mírate los parámetros de pack_start y los de la VBox.

- ferdy
También tienes la opción de colocar controles en un determinado lugar,
con el contenedor 'Fixed' o el 'Layout'
Yo te aconsejaría que pillaras el Glade (está para windows) y probaras a meter cajas, cambiar tamaño, meter controles, usar sus propiedades. Simplemente para que veas como funciona el tema. Nada más :)
Hagoromo escribió:También tienes la opción de colocar controles en un determinado lugar,
con el contenedor 'Fixed' o el 'Layout'

Waaaa encontré eso de chiripa en un ejemplo de add_with_properties (que por cierto, no me lo reconoce, pero da igual) en el manual de referencia (http://www.pygtk.org/docs/pygtk/class-g ... properties). De todos modos habéis estado atentos :), ¡eso era justo lo que quería!.

Fox escribió:Yo te aconsejaría que pillaras el Glade (está para windows) y probaras a meter cajas, cambiar tamaño, meter controles, usar sus propiedades. Simplemente para que veas como funciona el tema. Nada más :)

¡Genial! ¡¡Si puedo abstraerme de picar el código de las interfaces gráficas mejor que mejor!! Es a lo siguiente a lo que le echaré un vistazo. Unas preguntas: ¿Genera también código Python o es sólo para C/C++? ¿Trae el típico editor de texto e intérprete integrado (en plan IDE, como eclipse) para, por ejemplo, añadir códigos a las funciones que responden al click a los botones?

Ferdy, te agredezco un montón tu ayuda :) (conozco tus mensajes, suelen ser cortos y este creo que es una de las pocas "explicaciones" que has dado [buenazo]). El problema es que no encuentro flexibilidad viendo que los botones se colocan según vaya colocando cajas VBox y HBox. Soy muy perfeccionista y quiero que cada widget esté donde yo quiera que esté y con las Box me volvería loco...

Además, ¿no sería el código mas limpio? N líneas para especificar la ventana y su widget Fixed en ella, y M líneas para especificar cada wiget (entre ellas, la posición y el tamaño). Del otro modo sería: especificar ventana, widgets, cajas, esta caja dentro de esta, esta dentro de esta... :-? No se... vuelvo a repetir que vengo de .NET, allí se hace "como la solución de Fixed", es fácil y funciona bien...

Saludos.
Por eso te dije que realmente no debías, simplemente no quise decirte que el layout fixed existía para que intentaras hacer las cosas bien.

Justo porque lo suyo es que los widgets estén donde deben, deberías usar el modelo tradicional de Gtk. Es la única forma de que las ventanas sean redimensionables. Piensa que programar en una plataforma es imitar o seguir los modelos que se usan, para seguir el principio de 'mínima sorpresa' y conseguir que las interfaces 'encajen' en el resto del sistema.

Y creo que cuando las preguntas están bien hechas doy buenas respuestas. Si doy malas respuestas es, por lo general, porque la pregunta es una porquería (mal formulada).

- ferdy
Yo te aconsejaría que pillaras el Glade (está para windows) y probaras a meter cajas, cambiar tamaño, meter controles, usar sus propiedades. Simplemente para que veas como funciona el tema. Nada más :)

¡Genial! ¡¡Si puedo abstraerme de picar el código de las interfaces gráficas mejor que mejor!! Es a lo siguiente a lo que le echaré un vistazo. Unas preguntas: ¿Genera también código Python o es sólo para C/C++? ¿Trae el típico editor de texto e intérprete integrado (en plan IDE, como eclipse) para, por ejemplo, añadir códigos a las funciones que responden al click a los botones?

No es un IDE. Es una aplicación con la que crear las interfaces gráficas de forma visual, y lo que te genera es un xml que importas en Python, en C, o en lo que sea que lo soporte.
Ferdy escribió:Justo porque lo suyo es que los widgets estén donde deben, deberías usar el modelo tradicional de Gtk. Es la única forma de que las ventanas sean redimensionables. Piensa que programar en una plataforma es imitar o seguir los modelos que se usan, para seguir el principio de 'mínima sorpresa' y conseguir que las interfaces 'encajen' en el resto del sistema.

Bueno... en realidad para lo que hago me basta con ventanas que no se puedan redimensionar (de hecho, no quiero, nada mas que tenéis que ver el primer post en el que, sin tener ni idea de lo que me iba a encontrar, establezco que la ventana no se pueda redimensionar). No hago programas demasiado complejos... sólo para salir de hacer alguna tarea repetitiva o para aprender...

De todos modos, cuando me familiarice con los widgets y tal y no me supongan un problema (porque aun no estoy hecho con ellos...), me meto con los Box.
En algún momento, hará click en tu cabeza. A mi me costó bastante 'asumir' que Gtk es así jeje.

- ferdy
Lo que dice Ferdy es cierto, él te ha orientado inicialmente en el camino justo,
para no tener que usar los Fixed o Layouts. Si bien a todos, al principio, nos
ha costado un poco tomar la filosofía de los contenedores en Gtk+ [buuuaaaa]

Saludotes
Será mejor que me acostumbre a como hay que hacerlo, porque ya que lo hago mejor lo hago bien. Una pregunta: ¿es correcto establecer los tamaños de los widgets? (supongamos un botón en el centro de la ventana de tamaño 100x30, tendrá el mismo tamaño sea como sea la ventana y NO tan grande como sea la ventana).
Es mejor no alterar el tamaño de los widgets, porque cada wm usa sus themes
y eso puede interferir ... Pero lo que sí puedes (debes) hacer es configurar los
contenedores para que se porten de una manera determinada (ellos mismos
y sus contenidos)

Saludos
Entonces, por ejemplo, para el programa del primer post ¿cómo configuro el contenedor para que el botón tenga un tamaño "aceptable" (y no que ocupe toda la ventana) sin modificar el tamaño del mismo?.

Saludos.
Tienes que con las opciones que tiene. Si vas a glade y eliges el contenedor, hay unas opciones creo que eran las comunes (segunda pestaña) y ahí tendrás dos checkbox. Creo que uno pone algo de expand y el otro no me acuerdo (Sorry, no tengo glade a mano ahora mismo). Jugando con esas opciones puedes hacer que el control que este dentro de las distintas "casillas" de las cajas pues crezcan para ocupar todo el espacio, para que no crezcan, etc.


Es como ferdy dices, hasta que no hace click en la mollera, estarás un poco perdido.
Ya bueno, te refieres a expand y fill, pero eso "sólo" sirve para que se ajuste en toda la celda que le corresponde, se centre, etc... pero o bien es muy pequeño o bien es muy grande (ocupa toda la celda).

A modo de ejemplo, he hecho esta ventana:

Imagen

Establezco que la VBox tenga una anchura de borde (respecto a los bordes de la ventana) de 30 y un espaciado (entre el label y el botón) de 50. Ahora agrando la ventana y el botón se agranda en proporción a ella, vamos, que puede ser monstruoso... pero bueno, supongo que no lo voy a redimensionar...

Ferdy, ¿con lo de "no tocar los tamaños de los widgets" te refieres a dejarlos así?

Imagen

Sin que los widgets se ajusten a las cajas, y los que se redimensionan se ponen lo mas pequeños. Además, al redimensionar no cambian de tamaño (pero si de posición...).

Saludos.
18 respuestas