Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [GTK] Web Browser


Автор: shutffl 4.10.2009, 19:58
Доброго времени суток !!

Предыстория
В очередных порывах программирования с использованием различных GUI-библиотек решил глянуть на GTK+, а точнее - gtkmm (хотя разницы особо нет - C / C++).

Подскажите, плз, как можно отобразить HTML-страницу? Гугл говорит, что есть GtkHTML (1, 2, 3). Но документации по нему очень мало. Есть все тот же WebKit, но доков тоже не особо. Еще наткнулся на такую вещь как Gecko - может этого зверька приручить попробовать, а?

Суть проблемы
Используя libCURL, получаю код HTML, который надо вывести в окошко (браузер). Вполне возможно, что с WebKit даже не понадобится использовать libCURL, но все же. Тот код, что сейчас уже написан, требует визуального оформления. Все, что надо уже есть, кроме отображения HTML.

Проблемы
  • Приложение кроссплатформенное, но как работать с WebKit так и не понял: не нашел документации / примеров.
  • Не знаю как использовать WebKit в win32: смог получить WebKit.dll и еще пару *.dll, но хедеров нет. Возможно надо их git потерзать получше. В Linux еще не пробовал использовать, так как без win32 реализации это просто бесполезно.
 smile
Чем из стандартного и доступного для *NIX / win32 можно разобрать регулярные выражения? Как-то использовал что-то типа regex, но точно не помню и еще не смотрел. Спрашиваю ради того, чтобы потом проблема не было.

Заранее спасибо.

Автор: bsa 5.10.2009, 09:50
shutffl, смотри std::tr1::regex, boost::regex

Автор: shutffl 5.10.2009, 17:32
Цитата(bsa @  5.10.2009,  09:50 Найти цитируемый пост)
shutffl, смотри std::tr1::regex, boost::regex 

Спасибо..
А boost теперь в стандарте?
Сейчас уточнил на счет std::tr1::*.. Оно же тоже еще не в стандарте.. Значит придется в обеих системах использовать boost..

Автор: shutffl 8.10.2009, 00:22
Так-с.. Рассказываю о своих экспериментах с Webkit

main.c
Код

#include <gtk/gtk.h>
#include <webkit/webkit.h>

int main(int argc, char *argv[]) {
  GtkWidget *window;
  GtkWidget *browser;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  browser = webkit_web_view_new();
  //gtk_container_add(GTK_CONTAINER(window), browser);
  //gtk_widget_show(browser);

  gtk_widget_show(window);

  gtk_main();

  return 0;
}


Компиляция:
Код

gcc main.c `pkg-config webkit-1.0 gtk+-2.0 --cflags --libs`


При запуске вылетает такое чудо:
Код

./a.out 

GLib-ERROR **: The thread system is not yet initialized.
aborting...

warning: Lowest section in /usr/lib/libicudata.so.42 is .hash at 0000000000000120


И вылетает Bug Buddy. Что может быть? Goole ничем не помог особо. Смотрел по WebKit в исходниках Midori.

Автор: jonie 8.10.2009, 09:38
кроме буста, есть еще libpcre  - собственно то чем пользуется php и perl .... мб не столь объектно ориентированное, но не тянет за собой буста ...

Автор: shutffl 8.10.2009, 13:40
jonie, спасибо..

Автор: shutffl 9.10.2009, 15:25
Только что попробовал собрать Midori.. Собралось и запустилось без прооблем.. Странно, что не срабатывает моя инициализация webkit_web_view_new()..

Автор: shutffl 11.10.2009, 05:35
Вот рабочий код..
Код

/*
 * Copyright (C) 2006, 2007 Apple Inc.
 * Copyright (C) 2007 Alp Toker <[email protected]>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <gtk/gtk.h>
#include <webkit/webkit.h>

static GtkWidget* main_window;
static GtkWidget* uri_entry;
static GtkStatusbar* main_statusbar;
static WebKitWebView* web_view;
static gchar* main_title;
static gdouble load_progress;
static guint status_context_id;

static void
activate_uri_entry_cb (GtkWidget* entry, gpointer data)
{
    const gchar* uri = gtk_entry_get_text (GTK_ENTRY (entry));
    g_assert (uri);
    webkit_web_view_load_uri (web_view, uri);
}

static void
update_title (GtkWindow* window)
{
    GString* string = g_string_new (main_title);
    g_string_append (string, " - WebKit Launcher");
    if (load_progress < 100)
        g_string_append_printf (string, " (%f%%)", load_progress);
    gchar* title = g_string_free (string, FALSE);
    gtk_window_set_title (window, title);
    g_free (title);
}

static void
link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data)
{
    /* underflow is allowed */
    gtk_statusbar_pop (main_statusbar, status_context_id);
    if (link)
        gtk_statusbar_push (main_statusbar, status_context_id, link);
}

static void
title_change_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, const gchar* title, gpointer data)
{
    if (main_title)
        g_free (main_title);
    main_title = g_strdup (title);
    update_title (GTK_WINDOW (main_window));
}

static void
notify_load_status_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
{
    if (webkit_web_view_get_load_status (web_view) == WEBKIT_LOAD_COMMITTED) {
        WebKitWebFrame* frame = webkit_web_view_get_main_frame (web_view);
        const gchar* uri = webkit_web_frame_get_uri (frame);
        if (uri)
            gtk_entry_set_text (GTK_ENTRY (uri_entry), uri);
    }
}

static void
notify_progress_cb (WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
{
    load_progress = webkit_web_view_get_progress (web_view) * 100;
    update_title (GTK_WINDOW (main_window));
}

static void
destroy_cb (GtkWidget* widget, gpointer data)
{
    gtk_main_quit ();
}

static void
go_back_cb (GtkWidget* widget, gpointer data)
{
    webkit_web_view_go_back (web_view);
}

static void
go_forward_cb (GtkWidget* widget, gpointer data)
{
    webkit_web_view_go_forward (web_view);
}

static GtkWidget*
create_browser ()
{
    GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

    web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
    gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view));

    g_signal_connect (web_view, "title-changed", G_CALLBACK (title_change_cb), web_view);
    g_signal_connect (web_view, "notify::load-status", G_CALLBACK (notify_load_status_cb), web_view);
    g_signal_connect (web_view, "notify::progress", G_CALLBACK (notify_progress_cb), web_view);
    g_signal_connect (web_view, "hovering-over-link", G_CALLBACK (link_hover_cb), web_view);

    return scrolled_window;
}

static GtkWidget*
create_statusbar ()
{
    main_statusbar = GTK_STATUSBAR (gtk_statusbar_new ());
    status_context_id = gtk_statusbar_get_context_id (main_statusbar, "Link Hover");

    return (GtkWidget*)main_statusbar;
}

static GtkWidget*
create_toolbar ()
{
    GtkWidget* toolbar = gtk_toolbar_new ();

#if GTK_CHECK_VERSION(2,15,0)
    gtk_orientable_set_orientation (GTK_ORIENTABLE (toolbar), GTK_ORIENTATION_HORIZONTAL);
#else
    gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
#endif
    gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);

    GtkToolItem* item;

    /* the back button */
    item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
    g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_back_cb), NULL);
    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);

    /* The forward button */
    item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
    g_signal_connect (G_OBJECT (item), "clicked", G_CALLBACK (go_forward_cb), NULL);
    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);

    /* The URL entry */
    item = gtk_tool_item_new ();
    gtk_tool_item_set_expand (item, TRUE);
    uri_entry = gtk_entry_new ();
    gtk_container_add (GTK_CONTAINER (item), uri_entry);
    g_signal_connect (G_OBJECT (uri_entry), "activate", G_CALLBACK (activate_uri_entry_cb), NULL);
    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);

    /* The go button */
    item = gtk_tool_button_new_from_stock (GTK_STOCK_OK);
    g_signal_connect_swapped (G_OBJECT (item), "clicked", G_CALLBACK (activate_uri_entry_cb), (gpointer)uri_entry);
    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);

    return toolbar;
}

static GtkWidget*
create_window ()
{
    GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
    gtk_widget_set_name (window, "GtkLauncher");
    g_signal_connect (window, "destroy", G_CALLBACK (destroy_cb), NULL);

    return window;
}

int
main (int argc, char* argv[])
{
    gtk_init (&argc, &argv);
    if (!g_thread_supported ())
        g_thread_init (NULL);

    GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
    gtk_box_pack_start (GTK_BOX (vbox), create_toolbar (), FALSE, FALSE, 0);
    gtk_box_pack_start (GTK_BOX (vbox), create_browser (), TRUE, TRUE, 0);
    gtk_box_pack_start (GTK_BOX (vbox), create_statusbar (), FALSE, FALSE, 0);

    main_window = create_window ();
    gtk_container_add (GTK_CONTAINER (main_window), vbox);

    gchar* uri = (gchar*) (argc > 1 ? argv[1] : "http://www.google.com/");
    webkit_web_view_load_uri (web_view, uri);

    gtk_widget_grab_focus (GTK_WIDGET (web_view));
    gtk_widget_show_all (main_window);
    gtk_main ();

    return 0;
}


Терерь осталось только его проанализировать..

Добавлено через 5 минут и 44 секунды
Вот, что у меня получилось для минимального приложения, загружающего только одну страницу..
Код

#include <gtk/gtk.h>
#include <webkit/webkit.h>

int main(int argc, char *argv[]) {
  GtkWidget *window;
  GtkWidget *swindow;
  static WebKitWebView *browser;

  gtk_init(&argc, &argv);

  if (!g_thread_supported())
    g_thread_init(NULL);


  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  swindow = gtk_scrolled_window_new(NULL, NULL);
  browser = WEBKIT_WEB_VIEW(webkit_web_view_new());

  gtk_container_add(GTK_CONTAINER(swindow), GTK_WIDGET(browser));
  gtk_container_add(GTK_CONTAINER(window), swindow);

  webkit_web_view_load_uri(WEBKIT_WEB_VIEW(browser), "http://google.com");

  gtk_window_set_default_size(GTK_WINDOW(window), 800,600);
  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}


Компиляция:
Код

cat Makefile 
all:
    gcc -Wall -g -c main.c `pkg-config gtk+-2.0 webkit-1.0 --cflags`
    gcc -Wall main.o `pkg-config gtk+-2.0 webkit-1.0 --libs`


Вот так вот работает.. Проблема была в g_thread_supported()..

Добавлено через 7 минут и 25 секунд
То есть вопрос можно считать решенным.. Пользуйтесь..

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)