V této lekci se seznámíme s následujícími věcmi:
Některé základní koncepty programování s C++/GObject
Jak psát aplikace Gtk v jazyce C++
Než začnete s kódováním, musíte ve studiu Anjuta vytvořit nový projekt. Tím se vytvoří všechny soubory, které budete později potřebovat k sestavení a spuštění kódu. Je to také užitečné kvůli udržení všeho pohromadě.
Spusťte IDE Anjuta a klikněte na
Na kartě
Ujistěte se, že
Klikněte na
#include <gtkmm.h>
#include <iostream>
#include "config.h">
Jedná se o zcela základní kód C++ nastavující GTKmm. Podrobněji je to popsáno dále. Pokud základům rozumíte, tak tento sezmam přeskočte:
Tři řádky #include
na začátku vkládají knihovny config
(užitečné definice pro sestavení pomocí autotools), gtkmm
(uživatelské rozhraní) a iostream
(C++-STL). Funkce z těchto knihoven se používají ve zbytku kódu.
Funkce main
vytvoří nové (prázdné) okno a nastaví název do jeho záhlaví.
Funkce kit::run()
spustí hlavní smyčku GTKmm, která spustí uživatelské rozhraní a začne naslouchat událostem (jako jsou kliknutí nebo zmáčknutí kláves). Protože jsme této funkci jako argument předali okno, ukončí se aplikace automaticky při zavření tohoto okna.
Kód je připravený k použití, takže jej můžete zkompilovat kliknutím na
V následujícím okně zmáčkněte
Nyní oživíme prázdné okno. GTKmm uspořádává uživatelské rozhraní pomocí kontejneru Gtk::Container
, který může obsahovat další widgety a také další kontejnery. Zde použijeme nejjednodušší dostupný kontejner Gtk::Box
:
int
main (int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
Gtk::Window main_win;
main_win.set_title ("image-viewer-cpp");
Gtk::Box* box = Gtk::manage(new Gtk::Box());
box->set_orientation (Gtk::ORIENTATION_VERTICAL);
box->set_spacing(6);
main_win.add(*box);
image = Gtk::manage(new Gtk::Image());
box->pack_start (*image, true, true);
Gtk::Button* button = Gtk::manage(new Gtk::Button("Open Image…"));
button->signal_clicked().connect (
sigc::ptr_fun(&on_open_image));
box->pack_start (*button, false, false);
main_win.show_all_children();
kit.run(main_win);
return 0;
}
První řádky vytvoří widgety, které chceme používat: tlačítko pro otevření obrázku, vlastní widget pro zobrazení obrázku a box,, který použijeme jako kontejner.
Volání pack_start
přidává dva widgety do boxu a definuje jejich chování. Obrázek se roztáhne přes veškeré dostupné místo, zatímco tlačítko bude jen tak velké, jak je potřeba. Všimněte si, že jsem u widgetů výslovně nenastavili velikost. GTKmm to obvykle nepotřebuje, což usnadňuje udělat rozvržení, které vypadá dobře při různých velikostech okna. Následně je box přidán do okna.
Potřebujeme nadefinovat, co se stane, když uživatel klikne na tlačítko. GTKmm používá koncept signálů. Když je kliknuto na tlačítko, spustí se signál clicked, který můžeme napojit na nějakou akci. To se udělá pomocí funkce signal_clicked().connect
, která řekne GTKmm, aby zavolalo funkci on_open_image
, když je na tlačítko kliknuto. Funkci zpětného volání nadefinujeme v další části.
Posledním krokem je zobrazit všechny widgety v okně pomocí show_all_children()
. Je to stejné, jako byste zavolali metodu show()
postupně u všech našich synovských widgetů.
Nyní budeme definovat obsluhu signálu pro signál clicked tzn. pro tlačítko zmíněné dříve. Přidejte tento kód před metodu main
.
Gtk::Image* image = 0;
static void
on_open_image ()
{
Gtk::FileChooserDialog dialog("Open image",
Gtk::FILE_CHOOSER_ACTION_OPEN);
dialog.add_button (Gtk::Stock::OPEN,
Gtk::RESPONSE_ACCEPT);
dialog.add_button (Gtk::Stock::CANCEL,
Gtk::RESPONSE_CANCEL);
Glib::RefPtr<Gtk::FileFilter> filter =
Gtk::FileFilter::create();
filter->add_pixbuf_formats();
filter->set_name("Images");
dialog.add_filter (filter);
const int response = dialog.run();
dialog.hide();
switch (response)
{
case Gtk::RESPONSE_ACCEPT:
image->set(dialog.get_filename());
break;
default:
break;
}
}
Toto je trochu komplikovanější než vše, o co jsme se doposud pokusili, takže si to pojďme rozebrat:
Dialogové okno pro výběr souboru je vytvořeno pomocí konstruktoru Gtk::FileChooserDialog
. Jako argumenty přebírá název a typ dialogového okna. V našem případě je to dialogové okno Open.
Následující dva řádky přidají do dialogového okna tlačítka Open a Close.
Všimněte si, že používáme standardní názvy tlačítek z Gtk, místo abychom ručně psali „Cancel“ nebo „Open“. Výhodou použití standardních názvů je, že popisky tlačítek budou vždy přeloženy do uživatelova jazyka.
Druhým argumentem metody add_button()
je hodnota identifikující kliknuté tlačítko. I zde použijeme předdefinované hodnoty poskytované GTKmm.
Následující dva řádky omezí dialogové okno Gtk::Image
. Nejprve je vytvořen filtr a pak do něj přidáme všechny druhy souborů podporované v Gdk::Pixbuf
(což zahrnuje většinu obrázkových formátů, včetně PNG a JPEG). Nakonec tento filtr nastavíme aby byl filtrem dialogového okna
Glib::RefPtr
je chytrý ukazatel, který zde použijeme, aby se zajistilo, že filtr bude zlikvidován, až na něj nepovede žádný odkaz.
dialog.run
zobrazí dialogové okno dialog.run
hodnotu nebo by mohl vrátit , když uživatel klikne na switch
.
Skryjeme dialogové okno
Při předpokladu, že uživatel klikl na Gtk::Image
, takže se zobrazí.
Celý kód by nyní měl být připravený k fungování. Klikněte na
Pokud jste tak ještě neučinili, zvolte aplikaci
Pokud v této lekci narazíte na nějaké problémy, porovnejte si svůj kód s tímto ukázkovým kódem.
Zde je pár nápadů, jak byste mohli tuto jednoduchou ukázku rozšířit:
Umožnit uživateli výběr složky místo souboru a poskytnout ovládání pro procházení všech obrázků v této složce.
Použít při načtení obrázku náhodné filtry a efekty a umožnit uživateli takto změněný obrázek uložit.
GEGL poskytuje mocné schopnosti pro práci s obrázky.
Umožnit uživateli načíst obrázky ze síťového sdílení, skenerů a dalších složitějších zdrojů.
Pro práci se síťovými přenosy můžete použít GIO a pro obsluhu skeneru GNOME Scan.