Ahora, vamos a ir un poco más allá, aunque los ejemplos están hechos por mí, en parte me he basado un poco en la documentación de gtkmm (recomendable, llena de ejemplos e información interesante de cada widget), aunque ahora voy a utilizar algo de investigación propia.
El método a seguir será parecido a veces anteriores, un archivo principal, y una clase (con archivos cpp y h). Al compilar el proyecto, ha ocupado entre 45Kb y 60Kb, por lo que para ser un navegador no ocupa demasiado. Además, si leemos un poco la documentación de GtkWebkit veremos que podemos modificar el comportamiento del módulo para integrarlo en nuestras aplicaciones.
Para este pequeño proyecto he utilizado WebkitGtk+ >=1.1.7 y no Webkitmm porque este último no está muy avanzado en su desarrollo… y de paso quería practicar cómo podía comunicarme con widgets hechos en C en lugar de C++.
[ wk.cpp – Programa principal ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <gtkmm.h> #include "wkmain.h" WkWindow *wkwind; int main(int argc, char *argv[]) { Main entorno (argc, argv); // Creamos la ventana WkWindow wkwind; // Ejecutamos entorno.run(wkwind); return 0; } |
[ wkmain.h ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #ifndef _WKMAIN_H #define _WKMAIN_H #include <gtkmm.h> #include <webkit/webkit.h> #define CLICK_CONNECT(widget, method) widget->signal_clicked().connect(sigc::bind<Widget*>(sigc::mem_fun(*this, &method),(Widget*)widget)) using namespace Gtk; class WkWindow : public Window { public: WkWindow(); ~WkWindow(); // Click en el botón go void go_click(Widget *sender); // Actualizamos la barra de progreso bool wkprogress(); // Cargamos una web void carga_web(Glib::ustring url); VBox vb; // Divisiones en la vertical HBox cabecera; // Barra superior Label texto; // Texto de dirección Entry direccion; // Editor de texto para la dirección Button *go; // Botón para ver la web GtkWidget *web_view; // Widget de webkit ScrolledWindow scroll; // Ventana de scroll para páginas web grandes (más grandes que la ventana) Statusbar statusbar; // Barra de estado ProgressBar progressbar; // Barra de progreso private: int timeout; // Aquí almacenamos los eventos timeout }; #endif |
Bien, viendo esto, veremos que será un navegador sencillo (una entrada de texto para la dirección, un botón para ver la web, el motor webkit para ver la web, y una barra de estado con una barra de progreso).
Vemos el código wkmain.cpp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include "wkmain.h" WkWindow::WkWindow() : texto("Dirección: ") { // Configuro la ventana set_title("Navegador con Webkit"); set_border_width(5); set_default_size(800, 600); // Las barras de scroll salen automáticamente scroll.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC); // Configuro la cabecera go = new Button(Stock::GO_FORWARD); cabecera.pack_start(texto, PACK_SHRINK); cabecera.pack_start(direccion, PACK_EXPAND_WIDGET); cabecera.pack_start(*go, PACK_SHRINK); CLICK_CONNECT(go, WkWindow::go_click); vb.pack_start(cabecera, PACK_SHRINK); vb.set_spacing(3); // Espacio de 3pixels entre elementos // Configuramos el módulo webkit ! Atención es de Gtk, no Gtkmm web_view=webkit_web_view_new (); // Llamamos al método de carga de web carga_web("https://poesiabinaria.net/"); // Seguimos añadiendo objetos al Vbox vb.pack_start(scroll, PACK_EXPAND_WIDGET); // El moulo webkit no podemos añadirlo tan fácil, tenemos que añadir // el webkit al scrollbox mediante funciones de gtk (gtk_container_add). // Además, para sacar el objeto de Gtk del scrollbox (gtkmm) debemos llamar al método gobj() gtk_container_add(GTK_CONTAINER(scroll.gobj()), web_view); vb.pack_start(statusbar, PACK_SHRINK); statusbar.pack_start(progressbar, PACK_EXPAND_WIDGET); progressbar.set_fraction(0.0); // Progreso al 0% add(vb); show_all_children(); } WkWindow::~WkWindow() { } void WkWindow::carga_web(Glib::ustring url) { progressbar.set_fraction(0.0); // Progreso al 0% webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), url.data()); // Generamos un evento programado, cada 50ms se generará la señal // y llamaremos al método wkprogress() timeout=Glib::signal_timeout().connect(sigc::mem_fun(*this, &WkWindow::wkprogress),50); // Actualizamos cada 50ms } void WkWindow::go_click(Widget *sender) { carga_web(direccion.get_text()); } bool WkWindow::wkprogress() { // Calculamos el progreso double progreso=webkit_web_view_get_progress(WEBKIT_WEB_VIEW(web_view)); // Pasamos el progreso a la progressbar (que está en la statusbar) progressbar.set_fraction(progreso); return (progreso!=0); // Cuando progreso sea 0, devolveremos FALSE, y se desconectará el signal_timeout } |
Está todo más o menos explicado en los comentarios. Para compilar hacemos lo siguiente:
$ g++ -o webkitex wk.cpp wkmain.cpp `pkg-config –cflags gtkmm-2.4 webkit-1.0` `pkg-config –libs gtkmm-2.4 webkit-1.0`
(Haciendo coincidir las versiones de webkit y gtkmm
NOTA: Aunque en el blog parezca que pone `pkg-config -libs …` pone `pkg-config –libs` (dos signos menos).
ACTUALIZACIÓN 15/11/2010: Gracias a ChineseGeek por sus comentarios he añadido una versión compatible con versiones de webkit inferiores a 1.1.7. Podemos descargarlo desde aquí: (webkit_cpp.tar.bz2 2.5Kb).
Pingback: Bitacoras.com /
Pingback: BlogESfera.com /
Hola, primero q todo felicitarte por el blog, muy bueno la verdad! Segundo, tengo algunas dudas al momento de compilar el browser, la primera es con respecto al comando; veo que incluyes un archivo wkmain.cpp al momento de compilar, el cual no lo tengo, de todas formas, si compilo con el comando que indicas alli me da este error:
g++: wkmain.cpp: No existe el fichero ó directorio
En el fichero incluído de wk.cpp:2:
wkmain.h:1:1: error: #ifndef sin terminar
Si intento compilar con el mismo comando pero cambiando wkmain.cpp por wkwin.cp (que es el otro archivo que realizaste en el post) me dan estos errores:
En el fichero incluído de wk.cpp:2:
wkmain.h:1:1: error: #ifndef sin terminar
En el fichero incluído de wkwin.cp:1:
wkmain.h:1:1: error: #ifndef sin terminar
wkwin.cp: In constructor ‘WkWindow::WkWindow()’:
wkwin.cp:18: error: ‘widget’ no se declaró en este ámbito
wkwin.cp:18: error: ‘method’ no se declaró en este ámbito
wkwin.cp:18: error: expected `;’ before ‘widget’
wkwin.cp: At global scope:
wkwin.cp:43: error: expected constructor, destructor, or type conversion before ‘::’ token
wkwin.cp: In member function ‘void WkWindow::carga_web(Glib::ustring)’:
wkwin.cp:49: error: ‘webkit_web_view_load_uri’ no se declaró en este ámbito
wkwin.cp: In member function ‘bool WkWindow::wkprogress()’:
wkwin.cp:61: error: ‘webkit_web_view_get_progress’ no se declaró en este ámbito
Ojala puedas ayudarme, muchas gracias de antemano!
@ChineseGeek
¡Gracias por tu apoyo!
Perdóname, me equivoqué al nombrar uno de los archivos, anteriormente se llamaba wkwin.cp pero es wkmain.cpp; yo creo que todos los fallos vienen de ahí, prueba a ver y me comentas.
Suerte!
@admin
Compilando como me indicas me dan estos dos errores, por mas que googleo no veo como solventar estos inconvenientes:
wkmain2.cpp: In member function ‘void WkWindow::carga_web(Glib::ustring)’:
wkmain2.cpp:55: error: ‘webkit_web_view_load_uri’ no se declaró en este ámbito
wkmain2.cpp: In member function ‘bool WkWindow::wkprogress()’:
wkmain2.cpp:70: error: ‘webkit_web_view_get_progress’ no se declaró en este ámbito
@ChineseGeek
Pues el caso es que son errores de la versión, qué versión de gtkwebkit usas? Te lo digo, porque en la versión 1.1.1 surgieron las funciones webkit_web_view_load_uri() y webkit_web_view_get_progress().
webkit_web_view_load_uri() es sustituto de webkit_web_view_open()
y se usa igual, cambia
webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), url.data());
por
webkit_web_view_open(WEBKIT_WEB_VIEW(web_view), url.data());
Para no usar webkit_web_view_get_progress() la he tenido que liar un montón, pero esepero poder publicar pronto resultados que compilen bien en esta página a lo largo del día.
@ChineseGeek
Ya lo tienes, descarga el archivo, a ver si te funciona bien. Pásate por aquí y me comentas qué tal; si tienes más errores, haremos lo posible por subsanarlos 🙂
@admin
Ya sospechaba yo que era un problema con la version de webkit. Ahora ya funciona, gracias por la ayuda! Voy a ver si implemento los botones de atras y adelante, cuando lo tenga listo te aviso jajaja. Saludos!
@ChineseGeek ,
Espero tener noticias tuyas pronto!