OrlSan
Usuario (México)
Los relojes nunca fueron exactos y es tremendamente difícil hacer uno exacto. ¿Por qué? Existen muchos problemas relacionados con los péndulos, sin embargo estos no dejan de ser aparatos interesantes. Mediante un péndulo es posible demostrar la aceleración de Coriolis, calcular el valor de la aceleración de la gravedad o incluso demostrar la rotación de la tierra. A pesar de esto, los péndulos también son cuerpos, y por ende, sufren las consecuencias de la acción de fuerzas no conservativas (la fricción de la cuerda que los sostiene y la fricción contra el aire son las dos fuerzas que nos afectan). Y por si no fuera suficiente, los péndulos tienen un período de oscilación que depende del ángulo de la amplitud que tiene su movimiento. PLANTEAMIENTO DEL PROBLEMA Consideremos el modelo de un péndulo ideal, aquel que no es interferido por otras fuerzas, donde la masa de la cuerda que sostiene a la masa que oscilará es nula. Si la pesa con masa m se desvía de modo que la cuerda forme un ángulo α con la vertical, entonces, de acuerdo a la ley de la conservación de la energía, donde v es la velocidad de la masa y g es la aceleración de la gravedad. Si tenemos en cuenta únicamente las oscilaciones pequeñas respecto a la posición de equilibrio, podemos considerar que la longitud s del arco que describe la pesa cuando se desvía en un ángulo pequeño θ satisface la relación s = lθ$. Siendo así tenemos y de la ecuación (1) llegamos a la ecuación diferencial Puesto que θ decrece con el aumento de t (para valores pequeños de t), la ecuación (2) puede escribirse de la forma Si T es el período de las oscilaciones del péndulo, entonces O bien Y tal como podremos notar en la fórmula (3), el período de las oscilaciones del péndulo depende del ángulo α. Este hecho es pues, la causa principal por la que el reloj de péndulo no es exacto, pues, en la práctica, cada vez que la masa alcanza la posición extrema el ángulo es diferente de α. PERO ORLANDO, YO ME PERDÍ DESDE Ah! Bueno, no te angusties, a mi no me aparece todo mágicamente. Verás: Cuando nos queremos aproximar al valor del seno de un ángulo, para valores del ángulo muy, muy pequeños, la longitud del arco (s) es muy parecido al valor del seno del ángulo sin(α), por eso se da la igualdad. ¿Y CÓMO SACASTE LA ECUACIÓN DIFERENCIAL (2)? Si te fijas en la fórmula (1) tenemos una igualdad generada por el principio de la conservación de la energía, cosa que no te puedo explicar en este post. Si recuerdas que la velocidad es la derivada de la posición con respecto del tiempo, entonces recordarás la ecuación La cual dice básicamente que en un intervalo de tiempo muy pequeño, la posición del cuerpo cambia un poco su posición, y que esta posición es realmente un desplazamiento a través del arco (s). Por eso, juntando esas dos ecuaciones, se llega a la ecuación diferencial (2). ¿ENTONCES QUÉ? Bueno, con esto estás demostrando matemáticamente que no existe una posibilidad, aunque sea remota, de tener un reloj de péndulo exacto. ¿Es posible hacer que el movimiento de un péndulo o de un movimiento armónico simple sea exacto, o sea, que no dependa del ángulo de oscilación del movimiento? SI, es posible, pero eso te lo explico en otro post, el post de mañana. Mientras recuerda lo que te digo en este post y de sobra sabes que tus dudas, comentarios y demás cosas curiosas como un gif divertido es bienvenido en los comentarios. Muchas gracias! REFERENCIAS -Amelkin, Vladimir Vasílievich, Ecuaciones Diferenciales en la Práctica. Editorial URSS, 2003. ISBN 5-354-00443-8. -Halliday, Resnker, Fundamentals of Physics. Wiley.

Hola T! Ayer publique la forma en la que se guardan los archivos con Vala y usando la libreria GLib para este proposito. Ahora les mostrare la forma mas facil para abrir el contenido de un archivo y desplegarlo en pantalla. El programa que crearemos nos pedira el nombre del archivo que abriremos, y con eso nos desplegara en la pantalla su contenido. El programa del que hablo es el siguiente: Compila con $ valac nombre_archivo.vala -o nombre_binario En donde nombre_archivo.vala es el nombre que le has dado al fichero al guardarlo, y te recomiendo que lo guardes en la carpeta personal para evitar ir a directorios al iniciar la compilacion. La opcion -o nombre_binario no es obligatoria, por ejemplo, si mi fichero se llama abrir_archivos.vala, y ejecuto el comando valac abrir_archivos.vala, el compilador generara un binario llamado abrir_archivos, si deseas cambiar el nombre por defecto, usa esa opcion. Recuerda que tu archivo debe tener la extension .vala, de lo contrario el compilador devolvera un error. Ahora, recuerda por favor el post anterior, si no lo viste, por favor, dale una mirada para que lo que te diga aqui no quede incompleto. El siguiente post combinara lo aprendido en los dos ultimos posts con la plataforma Gtk+ para hacer un editor de textos muy simple, el cual poco a poco ira mejorando, agregando nuevas funciones, etc... El post anterior es Guardar archivos con Vala: FileUtils.set_contents, por favor dale una mirada si lo que expongo aqui no es claro. Ahora comenzamos a lo que venimos: a explicar el programa creado poco a poco string nombre_archivo, contenido; Aqui declaramos dos variables del tipo cadenas de texto (string). La primera es el nombre del archivo, que es pasado como parametro a la funcion get_contents() para abrir el archivo, y el segundo es el contenido, pasado tambien a la funcion get_contents() para que ahi se guarde la informacion contenida en el archivo. stdout.printf ("Nombre del archivo:"); nombre_archivo = stdin.read_line (); En estas dos lineas el programa pregunta el nombre del archivo a leer, y captura desde el teclado el nombre que le proporcionemos, almacenando los datos en la variable nombre_archivo mediante los datos devueltos por la funcion stdin.read_line (), para ser pasado a la funcion get_contents para abrir el archivo. FileUtils.get_contents (nombre_archivo, out contenido); stdout.printf(contenido); return 0; Aqui, FileUtils es usado, con la funcion get_contents (), para traer el contenido de un archivo a la variable "contenido". Mira la documentacion de FileUtils aqui El metodo es usado dando como parametro del nombre del archivo la variable "nombre_archivo", y como salida, la variable llamada "contenido" almacenara los datos del archivo. La funcion stdout.printf () es usada para imprimir en pantalla simplemente lo que almacene la variable "contenido", sin mas ni menos. El programa concluye con return 0; como es de esperar para terminar la funcion main (). Aqui la prueba del funcionamiento del programa: Bueno, amigos, hasta aqui el post, por favor comenten cualquier cosa, exceptuando poner algun GIF molesto o algo parecido al clasico "no lei un carajo". Espero haber sido claro, y por favor espera el proximo post que viene bastante bueno, ahi veremos la combinacion de Gtk y Glib para abrir archivos y editarlos. Hasta la proxima!
Hola amigos, gracias por pasar... El motivo del post es porque el Lin-x que recientemente posteé tiene algunos errores de drivers y no los he podido corregir. Entonces creo que en vez de descargar una imagen de DVD es mejor descargar desde la página oficial de Ubuntu la imágen de Cd y configurarlo nosotros mismos ya que trae más drivers incorporados y de más mejoras como la version del kernel y demás. Bueno, a lo que voy: Primero, vean una captura de ubuntu normal (si no lo puedes ver click aqui) Y luego, vean el Ubuntu modificado con el Pack. (s no lo puedes ver click aqui) Bueno, comenzamos por fin... Primero hay que ir a SouceForge.net a descargar el pack de instalación. Click aqui No se asusten, no es un .deb es un archivo .tar.gz, pero de todas fomas es fácil. Luego, descárguenlo y muevan el archivo a la carpeta personal. en mi caso /home/orlando (den click secundario y luego seleccionen) Luego, abrimos terminal. Nota: todos los comandos en negritas 1.- tar zxf Macbuntu-10.04.tar.gz esto es para descomprimir 2.- cd Macbuntu-10.04 entramos a la carpeta descomprimida 3.- ./install.sh ejecutamos el instalador Listo... Nota: Durante la instalación es probable que nos quiera descargar muchos paquetes (compiz, docky, etc) es normal y necesario. Tambien puede ser que parezca un escritorio sin forma, si esto sucede, desde la misma terminal teclea sudo reboot y el sistema se reinicia. Después ya tendrán su sistema bien configurado. Si no les gustó y ya lo instalaron.... pues desinstalalo, puedes descargar el archivo de desinstalacion desde aqui y lo ejecutan como ejecutamos el install.sh "./uninstall.sh" Gracias por su atencion Espero haber sido claro. Comenten cualquier duda Otra cosa les recomiendo ampliamente esta web http://sourceforge.net a todos aquellos que quieran descargar software libre y que ya están hartos de softonic y todo eso claro que también está nuestra querida terminal para instalar algo de software desde los repositorios de ubuntu, o el centro de software para saber mas o menos lo que estamos instalando es cuestion de cada quien Por cierto...
Hola, taringueros. Gracias por pasar.El viernes fui a la Biblioteca Central de la UNAM, supuestamente a buscar algo de información sobre la arquitectura romana; pero ¿a quién engaño? Me fui derechito a la sección de Matemáticas y encontré unos libros excelentes sobre programación, sin embargo, ninguno de linux en serio (C, Python, Ruby o algo parecido) y sólamente encontré sobre programación Windows, y entre esos libros encontré este: http://www.amazon.com/XNA-Game-Studio-Express-Developing/dp/1598633686 El libro está en inglés, y es una cosa increible, explica no sólo cómo crear juegos en Windows (y antes de que me empiecen a decir si programo en Windows, dejenme mostrarles algo: http://www.nature.com/naturejobs/science/jobs?q=Programmer, miren la cantidad de trabajos que EXIGEN conocimientos de programación sobre Windows, especialmente en la plataforma .NET, no me gusta, pero si quiero dedicarme a ser programador, es algo necesario, mi corazón es linuxero, pero mi trabajo puede ser en windows, es una pena, y en serio buscaré trabajo como programador Linux, pero si no lo consigo, necesitaré un plan de refuerzo )En fin, el libro explica qué son los objetos en el capítulo 2, y ahora que lo sé, quiero compartirlo con la comunidad. porque nunca he visto algo parecido en la Web.En primer lugar, en C# y en Vala, los programas están hechos de una o más clases. Una clase es la definición de un objeto. Pero, ¿qué es un objeto? La respuesta corta es "todo" (Todo en C# y Vala son objetos).Los objetos son representaciones en la memoria de cosas de la vida real. Las computadoras procesan los datos como ceros y unos. Los humanos pensamos en términos de conceptos más abstractos. ¿Cómo describirías un perro en una computadora? Últimadamente, tu descripción deberá ser una emisión de ceros y unos, porque ese es el lenguaje que la computadora comprende. Es el trabajo del compilador de C# y Vala convertir un lenguaje legible por los humanos en una descripción legible por la máquina.Las clases son la forma de describir objetos en el compilador C# y Vala. Una forma muy, muy simplificada para un perro puede verse así: public class Dog{ public int NumberOfLegs = 4; public void Speak() { System.Console.Writeline("Woof"); }} Pero a mí se me ocurre un programa un poco más "Taringuero": using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Aplicación_de_muestra{ class Program { static void Main(string[] args) { System.Console.WriteLine("Nombre del taringuero: "); string nombre = System.Console.ReadLine(); var taringuero = new Taringuero(); taringuero.ID = nombre; System.Console.WriteLine("¿Cuántos puntos tiene " + taringuero.ID + "?"); string pts = System.Console.ReadLine(); taringuero.Puntos = int.Parse(pts); System.Console.WriteLine("¿Crees que " + taringuero.ID + " se merece 10 puntos? [s/n]"); string respuesta = System.Console.ReadLine(); if(respuesta == "s") { taringuero.Agregar10(); System.Console.WriteLine("Ya le dimos 10, ahora tiene " + taringuero.Puntos); } else { System.Console.WriteLine("Entonces no le damos puntos, tiene " + taringuero.Puntos); } nombre = System.Console.ReadLine(); // Esto es para evitar que el programa se cierre // Al escribir y/o dar enter se cerrará } } class Taringuero { public string ID = ""; int puntos; public int Puntos { get { return puntos; } set { puntos = value; } } public void Agregar10() { puntos = puntos + 10; } }} Y al ejecutar el programa tenemos:Y ahí tienen, no me voy a poner a explicarles todo el programa, tal como lo dije en la descripción, no soy un programador experto en windows, con lo que les puse como descripción será suficiente para un programador astuto que lea esto, si no entienden, lean estos recursosEste lo recomiendo mucho, tiene todo que ver con lo que vimos en el post:http://msdn.microsoft.com/en-us/library/aa287786(v=VS.71).aspxSi no sabes C# (TODO lo que aprendas de C# lo puedes aplicar en Vala, y viceversa, por eso elegí ese lenguaje):http://msdn.microsoft.com/en-us/library/aa287558(v=VS.71).aspxY si no tienen visual Studio, descarguenlo, es gratishttp://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-csharp-expressObviamente seleccionan su descarga en Español, en la parte de abajoY eso sería todo por hoy, espero que les haya servido e interesado lo que dije, si tienen alguna duda, comentario o lo que sea, por favor comenten.Muchas gracias por su atencion. Hasta la próxima
Hola, taringueros linuxeros! Continuaré la serie de posts que he venido haciendo con Vala y Gtk+, esta vez veremos varias cosas, entre las que destacan: 1- Configurar Geany para la compilación directa de codigo fuente de Vala y Gtk+ 2- Aprender a agrupar en contenedores los widgets Gtk+ 3- Reutilizar codigo fuente 4- Hacer un editor de textos muy muy simple Entre otras... así que mejor comenzamos En primer lugar, vamos a instalar Geany, por cierto, aprovecho este parentesis para avisarte que si no tienes las librerias Gtk+, GLib, y el compilador Valac instalados, ve al post llamado Vala + Gtk = :headbang: [parte 1], ahi te explico cómo instalarlos desde tus repositorios para que no te descargues codigo fuente. Creo que no es necesario hacer un tutorial para instalar Geany, así que mejor vamos a lo que nos importa, primero, tenemos el geany así: Seleccionamos el menú Construir > Preferencias y tendremos una ventana igual a esta (debemos tener un archivo .vala abierto para que nos despliegue las opciones asi): observa que he hecho cambios a lo que viene por defecto, cambiando unicamente la sección de la compilación, poniendo unicamente así valac --pkg gtk+-2.0 "%f" Y con eso el Geany pasará la opción Gtk para el compilador de vala, con el fin de evitar la terminal, asi que nos quedaremos con algo así: Nota que es un programa Gtk+ y lo hemos compilado directamente. Y una vez que lo ejecutamos, vamos a ver algo parecido a esto: Y creo que con esto terminamos el curso intensivo de instalación y configuración de Geany para codigo fuente en Vala con Gtk+ Ahora si, vamos a lo que nos importa de acuerdo al codigo fuente de un ejemplo que puede ser visto en http://live.gnome.org/Vala/GTKSample El ejemplo es muy largo, asi que voy a ponerlo como codigo fuente, sin color y sin resaltos. Si lo quieres ver a color y resaltado, por favor copialo a tu Geany o Gedit y puedes verlo perfectamente. using Gtk; public class TextFileViewer : Window { private TextView text_view; public TextFileViewer () { this.title = "Text File Viewer"; this.position = WindowPosition.CENTER; set_default_size (400, 300); var toolbar = new Toolbar (); var open_button = new ToolButton.from_stock (Stock.OPEN); open_button.is_important = true; toolbar.add (open_button); open_button.clicked.connect (on_open_clicked); this.text_view = new TextView (); this.text_view.editable = false; this.text_view.cursor_visible = false; var scroll = new ScrolledWindow (null, null); scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); scroll.add (this.text_view); var vbox = new VBox (false, 0); vbox.pack_start (toolbar, false, true, 0); vbox.pack_start (scroll, true, true, 0); add (vbox); } private void on_open_clicked () { var file_chooser = new FileChooserDialog ("Open File", this, FileChooserAction.OPEN, Stock.CANCEL, ResponseType.CANCEL, Stock.OPEN, ResponseType.ACCEPT); if (file_chooser.run () == ResponseType.ACCEPT) { open_file (file_chooser.get_filename ()); } file_chooser.destroy (); } private void open_file (string filename) { try { string text; FileUtils.get_contents (filename, out text); this.text_view.buffer.text = text; } catch (Error e) { stderr.printf ("Error: %sn", e.message); } } public static int main (string[] args) { Gtk.init (ref args); var window = new TextFileViewer (); window.destroy.connect (Gtk.main_quit); window.show_all (); Gtk.main (); return 0; } } Cuando lo compiles, tendrás algo como esto: Ahora si, vamos a analizar algunos fragmentos de código para que nos queden claros algunos aspectos del programa. public class TextFileViewer : Window { // aqui hay codigo fuente... } Aquí se define como una clase (ese nombre reciben las funciones en Vala, haciendo enfasis en que es un tipo de referencia), creando una función llamada TextFileViewer, siendo asignada como una ventana, es decir, en vez de referirnos a la ventana como Window (), nos referiremos a ella como TextFileViewer. private TextView text_view; Aqui tambien hacemos una referencia a una función llamada TextView, que en la documentación de Gtk+ es definida como un visor de textos, si quieres ver más acerca de esa función, por favor, visita este enlace. La función TextView es redireccionada para que sea llamada como text_view en el programa, es similar a usar un alias para mejorar la claridad de la lectura del codigo. public TextFileViewer () { this.title = "Text File Viewer"; this.position = WindowPosition.CENTER; set_default_size (400, 300); Creo que esta parte no requiere más explicaciones si es que has venido leyendo los posts anteriores, así que nada más te digo que aqui estamos definiendo la función TextFileViewer, que en realidad es una ventana Gtk+, con la posición del la ventana en el Centro de la pantalla (en el post anterior explico como usar diferentes posiciones por defecto), haciendo que la ventana tenga un tamaño por defecto de 400x300 px. var toolbar = new Toolbar (); var open_button = new ToolButton.from_stock (Stock.OPEN); open_button.is_important = true; toolbar.add (open_button); open_button.clicked.connect (on_open_clicked); Aqui, en la primera línea, estamos creando una barra de tareas, usada comunmente para agrupar botones Gtk+, iconos, etiquetas de texto, etc... Mira esta liga para ver más detalles. ... En la segunda línea que te pongo aquí, estamos creando un botón, pero esta vez creamos un botón de herramientas (ToolButton), desde el Stock (mira aqui para más detalles del stock y los botones predefinidos para funciones). Esta vez unicamente se crea un botón para abrir. No te tienes que preocupar acerca del icono, del nombre o de cualquier otra cosa, el stock se encarga de definir eso. En la linea donde se define si el botón es importante se define positivo, es decir que el botón es importante, para que se muestre el ícono del botón (la carpeta que aparece en muchos programas, y se muestre la cadena de texto "Abrir". Si seleccionamos "false" en esa configuración, se mostrará el botón con el icono, pero no se mostrará la cadena de texto "Abrir" (haz el experimento, no pasa nada ). Sustituye esa linea por esta otra: open_button.is_important = false; Compila y ejecuta el programa, mira la diferencia y luego me dices. En la siguiente linea, agregamos el botón abrir a la barra de herramientas, y en la siguiente conectamos al botón abrir con una función llamada "on_open_clicked", misma que viene a ser explicada a continuación. this.text_view = new TextView (); this.text_view.editable = false; this.text_view.cursor_visible = false; La explicacion de esto es más compleja, si quieres evitarte leer un buen rato, solamente te digo que el metodo this () puede ser usado para crear constructores, mira ejemplos de constructores aqui y puedes comprenderlo mejor. Si no quieres quebrarte la cabeza con eso, solo te digo que creamos un visor de texto (TextView, porque fue redirigido como text_view en lineas anteriores), definiendo que el visor NO ES EDITABLE, y que el cursor no se ve en el visor. var scroll = new ScrolledWindow (null, null); scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); scroll.add (this.text_view); Aqui añadimos un ScrolledWindow, es decir, una barra de desplazamiento, en caso de que el texto sea más grande de lo que es el TextView, mira http://valadoc.org/references/gtk+-2.0/0.11.5/Gtk.ScrolledWindow.html para más detalles del ScrolledWindow, por cierto, los dos null que hay ahí significan que NO HAY AJUSTE VERTICAL Y ORIZONTAL. Por cierto, eso de set_policy (), significa que el ajuste del scroll bar va a ser automático, ahi en la pagina que te acabo de dar viene el metodo para que lo estudies más a fondo. Por ultimo, el scrollbar empaqueta el text_view dentro de el (adelante habrá un diagrama de los widgets empaquetados, por si no comprendes bien eso) var vbox = new VBox (false, 0); vbox.pack_start (toolbar, false, true, 0); vbox.pack_start (scroll, true, true, 0); add (vbox); Aqui creamos un contenedor vertical, el cual está declarado como inhomogéneo, con un espacio entre elementos de 0 px. Mira http://valadoc.org/references/gtk+-2.0/0.11.5/Gtk.VBox.html para más detalles. El VBox empaqueta la barra de tareas (toolbar), y enseguida empaqueta el scoll (ScrolledWindow). En la ultima linea, la ventana agrega el VBox, para finalizar así la parte gráfica inicial del programa. private void on_open_clicked () { var file_chooser = new FileChooserDialog ("Open File", this, FileChooserAction.OPEN, Stock.CANCEL, ResponseType.CANCEL, Stock.OPEN, ResponseType.ACCEPT); if (file_chooser.run () == ResponseType.ACCEPT) { open_file (file_chooser.get_filename ()); } file_chooser.destroy (); } Aqui estamos definiendo la función on_open_clicked, definida como private, para que UNICAMENTE pueda ser usada dentro de las dos llaves que inician en la linea 3 y terminan en la linea 51. En la función creamos un FileChooserDialog, el cual tiene la función de abrir, con dos botones del stock: uno para CANCELAR y otro para ACEPTAR. hay un enunciado de condición: el if() que está ahi, el cual actua unicamente si la respuesta que le damos al FileChooser es ACEPTAR. Si lo hacemos, se invoca a la función open_file (declarada después), y al terminar salimos del FileChooserDialog, con el nunciado destroy(). En caso de responder negativo (CANCELAR), pasamos directamente el destroy(). private void open_file (string filename) { try { string text; FileUtils.get_contents (filename, out text); this.text_view.buffer.text = text; } catch (Error e) { stderr.printf ("Error: %sn", e.message); } } Aqui estamos definiendo la función open_file, la cual requiere un string como parámetro, llamado "filename". Dentro de la función, se declara otro string llamado "text", el cual será usado para almacenar el contenido del archivo. Se invoca a la función FileUtils.get_contents() para obtener el contenido del archivo. Se da como parámetro el string "filename" y como buffer de salida el string "text". después, el texto del buffer de text_view es declarado igual al texto obtenido con la función get_contents(). En caso de error, se cacha el codigo de error y se desplegará en la terminal. public static int main (string[] args) { Gtk.init (ref args); var window = new TextFileViewer (); window.destroy.connect (Gtk.main_quit); window.show_all (); Gtk.main (); return 0; } } Aqui se inicia la ejecución del programa. Como muchos saben, el programa no inicia por otro lugar más que por la función main (), la cual estamos declarando. Se inicia el Gtk.init (ref args);, necesario en TODO programa GTK+. se crea una nueva ventana, la cual es definida como un nuevo "TextFileViewer" se conecta el botón cerrar de la ventana con un main_quit. y por ultimo se ordena a la ventana mostrar todo lo que contenga. Se pasa a la función Gtk.main() y por ultimo se da el clasico return 0; para finalizar la ejecución del programa. Ahora creo que ya me he cansado de escribir, asi que nada más te dejo el codigo del editor de textos más simple que existe, y en el proximo post te lo explico linea por linea: using Gtk; public class TextFileViewer : Window { private TextView text_view; public TextFileViewer () { this.title = "Text File Viewer"; this.position = WindowPosition.CENTER; set_default_size (400, 300); var toolbar = new Toolbar (); var open_button = new ToolButton.from_stock (Stock.OPEN); open_button.is_important = true; toolbar.add (open_button); open_button.clicked.connect (on_open_clicked); var save_button = new ToolButton.from_stock (Stock.SAVE); open_button.is_important = true; toolbar.add (save_button); save_button.clicked.connect (on_save_clicked); this.text_view = new TextView (); this.text_view.editable = true; this.text_view.cursor_visible = true; var scroll = new ScrolledWindow (null, null); scroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); scroll.add (this.text_view); var vbox = new VBox (false, 0); vbox.pack_start (toolbar, false, true, 0); vbox.pack_start (scroll, true, true, 0); add (vbox); } private void on_open_clicked () { var file_chooser = new FileChooserDialog ("Abrir archivo", this, FileChooserAction.OPEN, Stock.CANCEL, ResponseType.CANCEL, Stock.OPEN, ResponseType.ACCEPT); if (file_chooser.run () == ResponseType.ACCEPT) { open_file (file_chooser.get_filename ()); } file_chooser.destroy (); } private void on_save_clicked () { var file_chooser = new FileChooserDialog ("Guardar archivo", this, FileChooserAction.SAVE, Stock.CANCEL, ResponseType.CANCEL, Stock.OPEN, ResponseType.ACCEPT); if (file_chooser.run () == ResponseType.ACCEPT) { save_file (file_chooser.get_filename ()); } file_chooser.destroy (); } private void open_file (string filename) { try { string text; FileUtils.get_contents (filename, out text); this.text_view.buffer.text = text; } catch (Error e) { stderr.printf ("Error: %sn", e.message); } } private void save_file (string filename) { try { FileUtils.set_contents (filename, this.text_view.buffer.text); } catch (Error e) { stderr.printf ("Error: %sn", e.message); } } public static int main (string[] args) { Gtk.init (ref args); var window = new TextFileViewer (); window.destroy.connect (Gtk.main_quit); window.show_all (); Gtk.main (); return 0; } } Ahora si, me despido. Por ultimo te quiero comentar que este post lo he hecho en tres dias (es en serio), asi que por favor tomate la molestia de valorar un poco el esfuerzo. Por supuesto no soy perfecto, asi que si tengo algun error por favor dimelo, yo te lo agradeceré. Muchas Gracias!!!