<!doctype book public "-//Davenport//DTD DocBook V3.0//EN" [
<!entity % ISOnum PUBLIC "ISO 8879-1986//ENTITIES Numeric and Special Graphic//EN">
%ISOnum;
<!entity gtkmm "<application>Gtk--</application>">
<!entity gtk   "<application>Gtk</application>">
<!entity gnu   "<acronym>GNU</acronym>">
<!entity cxx   "<application>C++</application>">
<!entity c     "<application>C</application>">
<!entity referencebook SYSTEM "../reference/reference.sgml">
<!entity % examplelist SYSTEM "../examples/examplelist.sgml">
%examplelist;
<!entity ch-creating-new-widgets SYSTEM "ch_creating_new_widgets.sgml">
]>

<book status="in progress">
  <bookinfo><title>&gtkmm; Studiehandledning</title>
    <bookbiblio>
      <authorgroup>
	<author><honorific>Stud</honorific><honorific>rer</honorific>
	  <honorific>nat</honorific>
	  <firstname>Marcus</firstname><surname>Brinkmann</surname>
	  <authorblurb><para>Marcus studerar matematik och  and samlar
erfarenheter av Linux sedan början av 1996.</para></authorblurb>
	</author>
	<othercredit>
	  <firstname>Tero</firstname><surname>Pulkkinen</surname>
	  <authorblurb><para>
            <graphic fileref="pictures/tero_pulkkinen.gif"
format="GIF"></graphic> Tero underhåller och utvecklar
&gtkmm;.</para></authorblurb>
	</othercredit>
      </authorgroup>
      <abstract><para>En omfattande och lättförståelig guide till det
lovande grafiska användargränssnittet &gtkmm;.</para>
      </abstract>
      <revhistory>
	<revision>
	  <revnumber>0.1</revnumber>
	  <date>Juni 1998</date>
	  <authorinitials>M.B.</authorinitials>
	  <revremark>Ursprunglig utgåva.</revremark>
	</revision>
      </revhistory>
      <copyright><year>1998</year><holder>Marcus
Brinkmann</holder></copyright>
    </bookbiblio>
    <legalnotice><title>Copyright-förhållanden</title>
      <para>
Det är tillåtet att kopiera och distribuera ordagranna kopior av denna
manual förutsatt att copyrighten och denna tillåtelse finns med på
alla kopior.
</para>
      <para>
Det är tillåtet att bearbeta denna fil med TeX och andra
textbearbetningssystem (till exempel <acronym>DSSSL</acronym>-motorer)
och att skriva ut resultaten, förutsatt att det utskrivna dokumentet
innehåller en kopieringstillståndet identiskt med detta bortsett från
uteslutandet av denna paragraf (eftersom denna paragraf inte är
relevant för den utskrivna manualen).
</para>
      <para>
Det är tillåtet att kopiera och distribuera modifierade versioner av
denna manual under samma förhållanden som för ordagrann kopiering,
förutsatt att hela resultatet av arbetet distribueras med villkor som
är identiska med dessa.
</para>
      <para>
Det är tillåtet att kopiera och distribuera översättningar av denna
manual till andra språk, under ovanstående villkor för modifierade
versioner, med undantag gjort för att dessa villkor kan vara i en
översättning som är godkänd av den ursprungliga copyright-innehavaren.
</para>
      <para>
Exempelprogrammen är allmän egendom.
</para>
      <para>Följande adress finns här endast i informativt syfte.
<address> Free Software Foundation, Inc. <street>59 Temple Place -
Suite 330</street> <city>Boston</city>, <state>MA</state>
<postcode>02111-1307</postcode> <country>USA</country> </address>
      </para>
    </legalnotice>
  </bookinfo>
  <preface><title>Förord</title>
    <para>
      Med <application>Linux</application> finns ett stort urval av
applikationer till ingen eller lågt pris, och många av dem är av hög
kvalité.  Tyvärr är avsaknaden av dokumentation i stor kontrast till
detta.  Anledningarna är enkla att se: För de flesta utvecklare är
programmering mycket roligare än att förklara det tydligt uppenbara.
    </para>
    <para>
      För mig är programmering i &cxx; i &gtkmm;-miljö nytt och långt
ifrån uppenbart, och jag hoppas att nedskrivandet av de grundläggande
principer jag förstått längs vägen kommer att hjälpa mig att klargöra
mitt tänkande och hjälpa andra att förstå det lättare.
    </para>
    <para>
      Om du har några rättningar, anmärkningar, frågor eller svar om
detta dokument, tveka inte att kontakta mig. Min adress är: <address>
Marcus Brinkmann <email>Marcus.Brinkmann@ruhr-uni-bochum.de</email>
</address> Anmärkningar gällande den svenska översättningen kan
skickas till: <address> Fredrik Liljegren
<email>cof@ebox.tninet.se</email> </address>
    </para>
  </preface>
  <part><title>Komma igång</title>
    <partintro><title>Vad är &gtkmm;</title>
      <para>
        Idag kan mjukvara interagera med användaren på många sätt, och
det är inte en lätt uppgift för programmeraren att besluta vilka in-
och utdataenheter han skall stödja. Standarder och abstrakta
gränssnitt kan vara till stor hjälp för att göra detta beslut mindre
viktigt, eftersom många enheter kan användas på ett unikt sätt,
åtminstone från programmerarens ståndpunkt. Under Linux, till exempel,
finns det ingen anledning att bry sig om informationslagringsenheter,
eftersom kerneln tillhandahåller ett filsystem som ett abstrakt
gränssnitt och ett bibliotek förser oss med ett rent sätt att komma åt
filsystemet.
      </para>
      <para>
        Dock finns det fortfarande tillräckligt många sorters utdata
som varierar på ett mer fundamentalt sätt. Det är till exempel
sannolikt av viss vikt huruvida utdatan består av endast text (och med
text menar jag ett bokstavsflöde kodat i någon standard såsom
<acronym>ANSI</acronym>), eller om utdatan är grafisk (bestående av
pixlar).
      </para>
      <para>
        Situationen blir ännu mer förvirrande när programmeraren måste
skriva ett användargränssnitt för interaktiv kommunikation med
användaren. Det finns många indataenheter tillgängliga, alltifrån en
mängd tangentbord, musar, pads, och det slutar inte med
röstigenkänning. Programmeraren kan också använda olika sätt att
presentera möjligheterna med vilka användaren kan kontrollera
applikationen.
      </para>
      <para>
        Det finns standardprotokoll för in- och utdataenheter, och
programmerare kan använda dem för att vara oberoende av det faktiska
läget av in- och utdataenheter. Det finns dock flera bibliotek
tillgängliga som förser ett konsekvent grafiskt användargränssnitt
(<acronym>GUI</acronym>, Graphical User Interface). Det är önskvärt
att alla program använder samma användargränssnitt för att göra
situationen mindre förvirrande för användaren, men det nuvarande läget
är långt ifrån detta ideal.
      </para>
      <para>
        Att skriva ett utbyggbart, konsekvent användargränssnitt av
hög kvalité som går att porta, och kan användas för att skriva
<application>X</application>-applikationer på ett bekvämt sätt är
målet med &gtk;-projektet. Det är skrivet i och för &c;, och många
kända särdrag från objektorienterade programspråk var tvungna att
återimplementeras i &c;. &gtkmm; tillhandahåller ett omslag kring
&gtk; för användning i &cxx;, och har fördelarna med en typsäker miljö
(till och med för signaler) och integrerade objektorienterade
möjligheter såsom arv för utbyggnaden av &gtk;s möjligheter.
      </para>
    </partintro>
    <chapter><title>Förutsättningar</title>
      <para>
        Det finns vissa saker du behöver innan du ens kan börja jobba
med &gtkmm;, men även saker som du kommer att behöva lära dig sida vid
sida med &gtkmm; om du inte redan känner till dem. Annars kommer du
knappast lyckas med att skriva bra mjukvara, oavsett hur bra redskap
eller bibliotek du använder.
      </para>
      <para>
        Var dock försiktig och ta inte orden i detta kapitel för
bokstavligt. Det är osannolikt att jag verkligen vet precis vad
förutsättningarna är. Fri programvara utvecklas snabbt för tillfället,
och fakta är inaktuella efter kort tid. Av denna anledning kommer
vissa förutsättningar inte att skrivas ut tydligt utan avsiktligt vara
otydliga. Vänligen se den senaste dokumentationen som kommer med
mjukvarupaketet för mest aktuell information.
      </para>
      <sect1><title>Det uppenbara</title>
	<para>
          Du behöver en plattform som stöds av &gtk;, en komplett
&gtk;-installation och &gtkmm;.
	</para>
	<para>
          Förmodligen tillhandahåller distributionen du använder
binära paket. I så fall är allt du behöver göra att installera de
lämpliga paketen för utveckling med &gtk; och &gtkmm;. Om du måste
bygga paketen själv av någon anledning, skaffa de senaste
källkodspaketen via anonym ftp. Tack vare
<application>autoconf</application> bör byggande och installerande
vara enkelt.
	</para>	
	<para>
          Efter byggande och installerande av biblioteken kan du länka
in dem i applikationer som använder &gtkmm;. Lägg märke till att
&gtkmm;s biblioteksnamn kommer att vara <filename>libgtkmm</filename>
eftersom streck i biblioteksnamn kan vara förvirrande för
systemverktygen.
	</para>
      </sect1>
      <sect1><title>Kompilatorn</title>
	<para>
          Vidare, du behöver en fungerande &cxx;-kompilator. En bra
kompilator är <application>gcc</application>, &gnu;s
&c;/&cxx;-kompilator.
	</para>
	<para>
          Du måste veta hur man kompilerar och länkar program skrivna
i din miljö. På en <application>Linux</application>-plattform kan man
till exempel kompilera och länka ett program
<filename>stardust.cc</filename> med <application>gcc</application>
med ett kommando: <screen><prompt>$</prompt> <userinput>g++ -o
stardust stardust.cc -lgtkmm `gtk-config --cflags` `gtk-config
libs`</userinput></screen>
	</para>
	<para>
          Den sista delen behövs dock bara om ditt system inte klarar
beroenden mellan delade bibliotek korrekt. På vissa system kan du
klara dig utan anropet för <unserinput>'gtk-config
libs'</userinput>.</unserinput>
	</para>
      </sect1>
      <sect1><title>Vad mer?</title>
	<para>
	  Jag behöver mer information här.
	</para>
      </sect1>

    <chapter><title>Grunderna</title>
      <epigraph>
	<attribution>Zippy</attribution><para>Barn, de sju basala
matgrupperna är TUGGUMMI BLOSS, BAKVERK, PIZZA, PESTICIDER,
ANTIBIOTIKA, NUTRA-SWEET och SURMJÖLK!!</para>
      </epigraph>
      <sect1><title>Det kortaste exemplet</title>
	<para>
          Det finns ett minsta möjliga &cxx;-program som använder
&gtkmm;. Vänligen beakta följande kod;
<example><title>Kortaste &gtkmm;-programmet</title>
<programlisting role="C++">
&shortest-program;
</programlisting>
</example>
</para>
	<para>
          Den första raden inkluderar de klasser och mallar från vilka
du kan härleda dina objekt och signaler. Den tredje raden är
deklarationen av funktionen <function>main()</function>.
          <indexterm><primary
sortas="main"><function>main</function></primary></indexterm> Detta är
den funktion som anropas när programmet är kompilerat och körs. Varje
program måste inkludera en och endast en
<function>main()</function>-funktion, som skall returnera en värde av
typen "<type>int</type>" som returneras till skalet (programmets
felvärde). Skalet ger två parametrar till <function>main()</function>,
ett <type>int</type>-värde (här kallat <parameter>argc</parameter>)
och en pekare till en lista av standard &c;-strängar. Det förra är ett
tal som är ett högre än antalet argument givet till programmet på
kommandoraden, det senare är den kompletta kommandoraden nedbruten i
programnamnet (<parameter>argv[0]</parameter>) och argumenten
(<parameter>argv</parameter>[1] till
<parameter>argv</parameter>[<parameter>argc</parameter>-1]).
	</para>
	<para>
          Raderna 4 till 12 är definitionen av main-funktionen. Detta
är den kod som faktiskt exekveras. På rad 5 är variabeln
<parameter>eventLoop</parameter> av typen
<classname>Gtk_Main</classname> deklarerad och definierad.
<classname>Gtk_Main</classname> är den viktigaste klassen i &gtkmm;.
Varje &gtkmm;-program måste ha en förekomst av klassen
<classname>Gtk_Main</classname>, som handhar signalerna och
programflödet. Det finns precis en konstruktör för
<classname>Gtk_Main</classname>, och denna förväntar sig två argument.
Dessa är pekare till de två argumenten givna till main-funktionen av
skalet. Anledningen är att <classname>Gtk_Main</classname> kommer
plocka ut &gtkmm;-specifika argument från kommandoraden. Dessa kommer
att tas bort och behandlas.
	</para>
	<para>
          Efter att alla väsentliga &gtkmm;-objekt är konstruerade och
initialiserade (här i rad 7 och 8) så kommer programmets flöde att
överlämnas till &gtkmm; genom anrop av
<classname>Gtk_Main</classname>-objektet
<parametet>eventLoop</parameter>s metod <function>run()</function>
(rad 10). Så småningom kommer &gtkmm; att återlämna kontrollen till
main-funktionen, och då returnerar main framgång (rad 11).</parametet>
	</para>
	<para>
          I detta enkla exempel skapas bara ett synligt
&gtkmm;-objekt, objektet <parameter>helloWorldWindow</parameter> av
typen <classname>Gtk_Window</classname>. Efter konstrueringen kommer
fönstret inte att förverkligas. För att bygga och göra det synligt
måste man anropa medlemsmetoden <function>show()</function>. Detta är
sant för alla synliga &gtkmm;-objekt. I vårt exempel händer detta på
rad 8. Pröva programmet med och utan rad 8 så ser du skillnaden.
	</para>
	<para>
          Om du kör programmet så kommer du att se ett fönster med
standardstorlek (200x200) och med samma titel som programmets namn på
kommandoraden. Standardstorleken används bara om fönstret är tomt (om
det inte innehåller några barnobjekt), eftersom ett fönster med
storleken 0x0 är svårt att påverka eller ens se. Vidare kommer du se
att programmet inte avslutas, ens om det får stängningssignal från din
fönsterhanterare. Så är det på grund av att vi inte har tagit med
signalhantering ännu, och det kommer vi inte göra än på ett tag.
Vänligen avbryt programmet med
          <keycombo><keycap>Ctrl</keycap><keycap>C</keycap></keycombo>
eller förstör fönstret.
	</para>
      </sect1>
      
      <sect1><title>Fönsteregenskaper</title>
	<para>
          Vi kan redan ändra några av
<parameter>helloWorldWindow</parameter>s egenskaper, till exempel
titelsträngen eller minsta storleken. Följande kropp kommer exempelvis
att ändra båda på en gång; <programlisting role="C"> Gtk_Window
helloWorldWindow; helloWorldWindow.set_title("Hello, world!");
helloWorldWindow.set_usize(200,20); helloWorldWindow.show();
</programlisting>
	</para>
	<para>
          <classname>Gtk_Window</classname>-klassen tillhandahåller en
metod, <function>set_title(<type>char *</type>)</function>, för att
ändra fönstrets titel. Om du dock ser till huvudfilen eller
dokumentationen så kommer du märka att
<classname>Gtk_Window</classname> <emphasis>inte</emphasis>
tillhandahåller nån metod <function>set_usize(<type>gint</type>
<parameter>width</parameter>, <type>gint</type>
<parameter>height</parameter>)<function>, som ställer in  widgetens
storlek. <function>set_usize</function> tillhandahålls av
<classname>Gtk_Widget</classname>, och
<classname>Gtk_Window</classname> är en klass med
<classname>Gtk_Widget</classname> som ursprung. Du ska alltid hålla i
tankarna att du också kan använda medlemsmetoder från föräldraklasser
för att ändra dina &gtkmm;-objekts egenskaper.</function>
	</para>
	<para>
          Sättet som din fönsterinstans hanteras av fönsterhanteraren
kan ändras av en variabel av typen <type>GtkWindowType</type>, given
till <classname>Gtk_Window</classname>s konstruktör. Det finns tre
möjliga värden: <symbol>GTK_WINDOW_TOPLEVEL</symbol> (standard),
<symbol>GTK_WINDOW_DIALOG</symbol> och
<symbol>GTK_WINDOW_POPUP</symbol>. För att få reda på vad de gör,
ändra rad 7 i exemplet till något likt: <programlisting role="C">
Gtk_Window helloWorldWindow(GTK_WINDOW_TOPLEVEL); </programlisting>
och byt sedan ut <symbol>GTK_WINDOW_TOPLEVEL</symbol> mot någon av de
andra två möjligheterna.Du kommer att få se att fönster av typen
<symbol>GTK_WINDOW_TOPLEVEL</symbol> hanteras helt och hållet av
fönsterhanteraren. Vidare kommer du få se att fönster av typen
<symbol>GTK_WINDOW_DIALOG</symbol> saknar några handtag (till exempel
storleks- och stängningsknapparna) och att fönster av typen
<symbol>GTK_WINDOW_POPUP</symbol> inte hanteras alls av
fönsterhanteraren (ingen ram, inga knappar).
	</para>
      </sect1>

      <sect1><title>Etikett-widgeten</title>
	<para>
          Låt oss nu gå över till ett annat &gtkmm;-objekt,
widget-klassen <classname>Gtk_Label</classname>.  Konstruktören ber om
en <type>const char*</type> som innehåller etikettens namn.
	</para>
	<para>
          Betänk detta exempelprogram:
	  <example><title>Etikett-widget</title>
<programlisting role="C">
&label-widget;
</programlisting>
	  </example>
	</para>
	<para>
          De flesta delarna av det här programmet är redan förklarade,
bara raderna 7, 8 och 11 är nya.  Om du kompilerar och kör detta
exempel så kommer du inte att få se ett fönster som är av
standardstorleken 200x200, utan ett fönster som har precis den storlek
som behövs för att innehålla texten "Hello, world!".  Vanligtvis
kommer en widget att ha en standardstorlek för att precis få plats med
den barn-widgeten den innehåller.
	</para>
	<para>
          En widget kan läggas till fönstret med medlemsmetoden
<function>add(<type>Gtk_Widget*</type>)</function>. Då detta kräver
att en pekare till widgetten läggs till så ger vi
<classname>Gtk_Label</classname>-widgettens pekare som parameter. Lägg
märke till att <function>add()</function> är en medlemsmetod i klassen
<classname>Gtk_Container</classname>, i vilken
<classname>Gtk_Window</classname> har sitt ursprung, inte i
<classname>Gtk_Window</classname> själv. Som du kommer att få se
senare så kan de använda detta tillvägagångssätt för att lägga till en
widget i alla behållare, inte bara fönster.
	</para>
	<para>
          Som redan nämnts så måste vi göra etiketten synlig med
medlemsmetoden <function>show()</function>. Lägg märke till att vi
först kan visa etiketten med <function>show()</function> och därefter
fönstret. Om du ändrar ordningen så kommer du först att få se det
tomma fönstret och sedan se etiketten ritas upp. I de flesta fall så
är det att föredra att rita upp widgetten internt för att sedan som
sista steg göra fönstret synligt.
	</para>
	<para>
          Klassen <classname>Gtk_Label</classname> har två
medlemsmetoder, <function>set(<type>const gchar*</type>
<parameter>str</parameter>)</function> och
<function>get(<type>gchar**</type>
<parameter>str</parameter>)</function> så att du kan ändra etiketten
och se vad den läser. Vänligen kom ihåg att klassen
<classname>Gtk_Label</classname> har sitt ursprung i andra klasser,
och att du kan använda medlemsmetoder från föräldraklasser för att
ändra andra egenskaper hos <classname>Gtk_Label</classname>. Till
exempel kan du ändra etikettens minsta storlek med medlemsmetoden
<function>set_usize(<type>gint</type>, <type>gint</type>)</function> i
klassen <classname>Gtk_Widget</classname>.
	</para>
      </sect1>

      <sect1><title>Knapp-widgeten</title>
	<para>
          Etiketter är ganska tråkiga, eftersom de är passiva. Om du
vill interagera med användaren så kommer du säkerligen vilja  ha
knappar med i din applikation.  För detta ändamål finns
<classname>Gtk_Button</classname> som liknar
<classname>Gtk_Label</classname>.
	</para>
	<para>
          <classname>Gtk_Button</classname>-klassen är dock mer
komplex, då den är en behållare (den har sitt ursprung i
<classname>Gtk_Container</classname>-klassen), så du kan lägga till en
etikett, lite grafik eller vad du vill. Widgetar läggs  till en knapp
på samma sätt som till ett fönster, med medlemsmetoden
<function>add(<type>Gtk_Widget *</type>)</function>.
	</para>
	<para>
          Om du bara vill lägga till en etikett till en
<classname>Gtk_Button</classname>-behållare så kan du ge textsträngen
till konstruktören för <classname>Gtk_Button</classname>.  Detta är en
bekväm och vanlig förkortning.  Det innebär att följande kodbitar är
ekvivalenta: <programlisting role="C"> Gtk_Label someLabel("Hello,
world!"); someLabel.show(); Gtk_Button someButton;
someButton.add(&amp;someLabel); someButton.show(); </programlisting>
är det svåra sättet att åstadkomma: <programlisting role="C">
Gtk_Button someButton("Hello, world!"); someButton.show();
</programlisting>
	</para>
	<para>
          Det finns för tillfället inget sätt att komma åt etiketten
skapad av <function>Gtk_Button(<type>const gchar*</type>)</function>,
så du måste använda den genomförliga formen om du vill arbeta med den,
exempelvis om du vill ändra knappens text.
	</para>
	<para>
          Ändra så att "Hello, world!"-exemplet använder en knapp
istället för en etikett och försök köra det. Du kommer att få se att
knappens färg ändras om du rör muspekaren över den  och om du klickar
på den, men inget annat händer.  Det är möjligt att få något att
hända, och detta är meningen med signaler.
	</para>
      </sect1>

      <sect1><title>Signaler</title>
	<para>
          Signaler sänds ut av &gtkmm; när något intressant händer,
till exempel när ett fönster ändrar storlek eller när en knapp blir
nedtryckt.  Du kan koppla dessa signaler, vilket innebär att du kan
sätta en funktion till kön av funktioner som ska bli kallade när en
signal sänd ut.  Du kan koppla flera funktioner till en och samma
signal, och du kan sätta samma funktion på flera signaler.  Hur som
helst, funktionens returvärde och argument måste stämma överens med
signalens returvärde och argument.
	</para>
	<para>
          Beakta följande program som är en lång variant av övningen i
 föregående avsnitt:
	  <example><title>Ingen signal ännu</title>
<programlisting role="C">
&signal-1;
</programlisting>
	  </example>
	</para>
	<para>
          Lägg märke till avsaknaden av
<function>show()</function>-anrop för
<classname>Gtk_Label</classname>-, <classname>Gtk_Button</classname>-
och <classname>Gtk_Window</classname>-elementen. De är ersatta av ett
enda anrop av medlemsmetoden <function>show_all()</function> i
<classname>Gtk_Window</classname>-objektet
<parameter>helloWorldWindow</parameter>.
<function>show_all()</function> är en användbar och vanlig
förkortning, den anropar <function>show()</function> för widgeten
själv och för alla element den innehåller. <function>show()</function>
och <function>show_all</function> kommer diskuteras genomförligare
senare i denna studiehandledning när vi talar  om behållare.
	</para>
	<para>
          Vi vill få något att hända när knappen trycks ned.  Vi vill
till exempel ändra etikettens text (och detta är anledningen  till att
vi inte gav texten till knappens konstruktör).  För  att kunna göra
detta måste &gtkmm; lägga märke till oss nät knappen trycks ned.
Detta gör det genom att göra ett funktionsanrop.  Tja, det är lite mer
invecklat i verkligheten, men för tillfället räcker det med att tänka
på  signaler som funktionsanrop som görs av &gtkmm; som reaktion  på
en händelse.
	</para>
	<para>
          Det finns bara en sak kvar att göra för vårt program, det
måste berätta för &gtkmm; <emphasis>vilken funktion</emphasis> som
skall anropas när <emphasis>vilken aktivitet</emphasis> inträffat i
<emphasis>vilket element</emphasis>.  Detta gör man med
<function>connect_to_function</function>.  För att prova den, vänligen
lägg till följande funktion till ovanstående exempel, och lägg även
till anropet <function>connect_to_function</function> till
<function>main</function>-funktionen.
	</para>

	<para>
<programlisting role="C"> 2a   static void changeLabel(Gtk_Label&amp;
theLabel) 2b   { 2c     static bool flag=true; 2d 2e     flag = !flag;
2f     flag ? theLabel.set("Bye, bye!") 2g          :
theLabel.set("Hello, World!"); 2h   } 11a
connect_to_function(helloWorldButton.clicked, &amp;changeLabel,
helloWorldLabel); </programlisting>
	</para>
	<para>
<function>changeLabel</function> använder en statisk variabel av
bool-typ för att lagra etikettens nuvarande status (vi skulle också
kunna fråga den med <classname>Gtk_Label</classname>s medlemsmetod
<function>get</function>, men det skulle kräva en strängjämförelse, en
meningslöst tillkrånglande i detta lilla exempel) och ändrar
etikettens text när den blir anropad.
<function>connect_to_function</function>-funktionens anrop kräver en
del förklaring.
</para>
	<para>
Vanligen tar <function>connect_to_function</function> två argument.
Det första är signalen du vill koppla till, och det andra är
funktionen du vill koppla till signalen.  Ett valfritt tredje argument
 kommer att skickas vidare till den kopplade funktionen när signalen
sänds ut.  I vårt exempel så sänds signalen
<function>helloWorldButton-clicked</function> ut när knappen blir
klickad (med andra ord nedtryckt och uppsläppt) och
<function>changeLabel(helloWorldLabel)</function> anropas.  Om det
tredje av argumenten till <function>connect_to_function</function>
utelämnas så skickas inget argument vidare.
</para>
	<para>
Du kan koppla så många funktioner som du vill till en signal, de
anropas den ena efter den andra.  Dessutom kan du inte bara koppla
funktionsanrop till en signal, utan också medlemsmetoder av en klass
instansen och till och med andra signaler.  Signaler kontrollerar
flödet i ett interaktivt program.</para>
      </sect1>
    </chapter>
    
    <chapter><title>Till allvaret</title>
      <sect1><title>Packetering</title>
	<para>
Fram till nu så har varje objekt av klassen
<classname>Gtk_Container</classname> bara haft ett
<classname>Gtk_Widget</classname>-objekt i sig (till exempel ett
fönster med en etikett på).  Uppenbarligen är inte detta tillräckligt
i de flesta fall.  Det barnsliga sättet att lägga till en andra
etikett  skulle förmodligen bli något likt följande:
<example><title>Detta funkar inte!</title>
	    <programlisting role="C">
&packaging-1;
</programlisting>
	  </example>
</para>
	<para>
Vänligen försök kompilera och köra detta exempel.  Blir du förvånad?
Du kommer att se precis samma utdata som om raderna 9 och 13 inte hade
 varit där.  Att byta plats på raderna 12 och 13 kommer bara att visa
den andra texten "Bye, world!", men inte "Hello, world!".  Även om
detta inte verkar vettigt vid första anblicken så kommer du snart
komma på varför det finns <emphasis>starka skäl</emphasis> för detta
beteende.
</para>
	<para>
Det handlar helt och hållet om placering.  Det finns en vettig
standard för placering av en ensam widget i en behållare (den är
centrerad), det finns ingen uppenbar placering att föredra för mer än
en widget.  De skulle kunna bli placerade vertikalt eller
horisontellt, vänster-, högerjusterade eller centrerade.  Placeringen
kunde också bli olika för varje widget, till exempel några högst upp i
 behållaren och andra till höger.  Eftersom placering av widgettar är
en så komplex uppgift så finns det många olika sätt att göra det.
</para>
	<para>
Därför är det förbjudet att placera mer än ett objekt i en behållare,
och &gtk; kommer klaga med ett felmeddelande vid körning.
</para>
	<para>
Det lättaste sättet att placera widgettar är att placera dem i en rad
(horisontellt) eller i en kolumn (vertikalt).  För detta finns det två
 klasser i &gtkmm;, klassen <classname>Gtk_HBox</classname> och
<classname>Gtk_VBox</classname>.  Eftersom båda klasserna förser oss
med väldigt lika funktionalitet så har de sitt ursprung i en gemensam
bas,  klassen <classname>Gtk_Bok</classname>, som aldrig används
direkt. För följande förklaring används
<classname>Gtk_HBox</classname> som exempel, men samma saker är sanna
även om <classname>Gtk_VBox</classname>, eftersom gränssnittet
tillhandahålls av <classname>Gtk_Box</classname>, inte av en av
underklasserna.
</para>
	<para>
Huvudidén är att lägga till en box i behållaren, och sedan lägga till
widgettarna i boxen.  För detta ändamål har
<classname>Gtk_Box</classname> två metoder,
<function>pack_start(<type>Gtk_Widget*</type>)</function> och
<function>pack_end(<type>Gtk_Widget*</type>)</function>.
<function>pack_start</function> lägger till widgetar i början av boxen
 i riktning emot slutet, medan <function>pack_end</function> börjar i
slutet av boxen och går emot början.  Därför är ordningen metoderna
anropas i viktig.  Ett enkelt exempel visar båda sätten att lägga till
 widgetar i en box.
<example>
	    <title>Horisontell packetering</title>
	    <programlisting role="C">
&packaging-2;
</programlisting>
	  </example>
</para>
	<para>
Om du provar det här exemplet så bör du ändra fönstrets storlek för
att tvinga fram en annan placering.  Då en
<classname>Gtk_HBox</classname> har en annan standardstorlek för att
passa summan av standardstorleken på de widgetar den innehåller,
kommer du inte att se den annorlunda placeringen av widgetarna förrän
storleken ändrats.  Vänligen lägg märke till skillnaden i ordning
mellan anropen på rad 14 till 17 i <function>pack_start</function> och
 <function>pack_end</function>.
</para>
	<para>
En <classname>Gtk_Bok</classname> är en osynlig box, vilket innebär
att den inte lägger till något synligt till behållaren den läggs till
i.  Du måste ändå anropa <function>show()</function> för att göra
widgetarna den innehåller synliga.  <function>show</function> gör bara
 en widget synlig för dess direkta förälder.  Om den ska visa sig i
ett  fönster så måste alla widgetar på vägen ner till den vara synliga
också.  Detta är verkligen ett utmärkt exempel på varför
<function>show_all()</function> är en fantastisk bekvämlighet för
programmeraren.
</para>
	<para>
Du kan nästa flera horisontella och vertikala boxar för att nå en
bättre kontroll över placeringen.  Du kan också lägga till andra
widgetar till en box än etiketter.  Du kan justera elementens
placeringen i en box, men det är ämnet i en senare del i denna
studiehandledning.
</para>
      </sect1>

      <sect1><title>Ett exempel</title>
	<para>
Såhär långt bör läsaren redan ha blivit ganska bekantade med &gtkmm;.
Det är ett bra tillfälle nu att summera alla &gtkmm;s finesser som
presenterats i de föregående delarna med ett komplexare exempel.
Programmet nedan kommer att visa en lista med tre bockknappar, var och
 en med namnet på en basfärg på (röd, grön och blå (engelska: "red",
"green" och "blue")).  Användaren kan bocka av av på färgerna med ett
klick på bockknappen och programmet kommer räkna ut den resulterande
färgen som blir genom att blanda de förbockade färgerna.
</para>
	<para>
En bockknapp tillhandahåller en behållare tillsammans med en liten
bockruta till vänster.  Denna bockruta kan växlas med ett musklick för
 att indikera om saken skall vara på eller av.  En bockknapp
tillhandahålls a klassen <classname>Gtk_CheckButton</classname>.  För
din bekvämlighet tillhandahålls en standardkontruktör som tar emot en
sträng (liknande <classname>Gtk_Button</classname>).  Då
<classname>Gtk_CheckButton</classname> har sitt ursprung i
<classname>Gtk_Button</classname> kan alla signaler och medlemsmetoder
du redan kan användas.  Dessutom kan du fråga efter dess nuvarande
tillstånd med <function><type>bool</type> get_state()</function> och
du kan ställa in det med <function><type>void</type>
set_state(<type>bool</type> state)</function>.  En signal,
<function>toggled</function>, sänds ut närhelst dess nuvarande status
ändras.
</para>
	<para>
Ett enkelt program visar dig hur denna knapp kan användas.  Det
innehåller också allting du lärt dig tidigare, så om du har svårt att
förstå det, gå tillbaka och läs igen från början av handledningen.  En
 funktion förväntas du dock inte vara bekant med.  Det är anropet till
<function>connect_to_method</function>, som används för att koppla
ihop en medlemsmetod med en signal.  För tillfället räcker det att
veta att detta anrop används för att köra
<function>updateColor()</function> närhelst en bockknapps status
ändras.
<example><title>Bockknapp</title>
	    <programlisting role="C">
&checkbutton;
</programlisting>
	  </example>
</para>
	<para>
          Du måste ha märkt att programmets design ändrats grundligt
från den använd i tidigare exempel.  Tidigare hade vi alla objekt i
huvudfunktionen, vilket var vettigt eftersom vi hade relativt få
widgetar.  Med ett ökat antal objekt att hantera behöver vi en mer
sofistikerad design.  Det är en bra idé att skilja widgetarna åt genom
 platsen de dyker upp på i programmet.  Till exempel kan du skapa
separata klasser för varje fönster som används i ditt program.  Även
boxar och andra saker kan dock ses som separata enheter.  Ofta finns
det flera möjliga och bra lösningar.  I vårt fall har jag valt att
göra en klass <classname>ColorMix</classname> som representerar
innehållet i vårt fönster.  På detta vis kan vi använda objektet
<classname>ColorMix</classname> på andra platser, till exempel som en
del av ett större fönster.
</para>
	<para>
          En annan mycket viktig designfråga är användningen av
<emphasis>arv</emphasis>.  Eftersom klassen
<classname>ColorMix</classname> har sitt ursprung i
<classname>Gtk_HBox</classname> så blev det verkligen i sig själv ett
&gtkmm;-objekt!  I det exemplet ovan kan man se hur enkelt &gtkmm; kan
 utökas med komplexare widgetar.  Det är sant att
<classname>ColorMix</classname> är för specialiserad för att vara
särskilt användbar i andra sammanhang, men det är lätt att se att
detta inte är för nåt begränsande av arvmöjligheterna.  Om du använder
 konstruktörer som tar emot lämpliga parametrar så kan du enkelt skapa
dina egna abstrakta widgetar och andra &gtkmm;-objekt.
</para>
      </sect1>
      <sect1><title>Menyer</title>
	<para>
          Menyer är en väsentlig del av varje användarapplikation.  De
förser oss med snabb tillgång till programmets huvudsakliga
egenskaper.  Menyer organiseras i undermenyer, vilka koms åt via en
menylist, vanligen placerad högst upp i fönstret.
</para>
	<para>
          Menyföremål kopplas till funktioner med signaler: Om en
användare väljer något i en meny så sker en händelse och lämplig
signal sänds ut.  Du kan koppla ihop en eller flera funktioner med
denna signal för att få något att hända genom menyn.  Ett vanligt sätt 
att svara på ett menyval är att öppna ett dialogfönster, men även
direkta händelser kan vara lämpliga.
</para>
	<para>
          Du kan bygga upp menyer direkt av &gtkmm;-widgetarna, men
detta är omständligt då en massa overhead är inblandat i
implementeringen av de nödvändiga objekten.  För specialfallet menyer
tillhandahåller &gtkmm; ett bättre sätt att skapa den uppsättning
widgetar som krävs.  Detta system kallas
<classname>MenuFactory</classname>.
</para>

      </sect1>
      <sect1><title>Mer om signaler</title>
	<para>TOMT</para>
      </sect1>
    </chapter>
  </part>
  <part><title>Att utöka &gtkmm;</title>
  &ch-creating-new-widgets-sv;
  </part>
  <part><title>Referensbok</title>
    <partintro><title>Läs källkoderna, grabben!</title>
      <para>
        Denna del av studiehandledningen innehåller en komplett
klassreferens för &gtkmm;.  Varje klass och dess medlemsmetoder listat 
här tillsammans med de signaler du kan koppla dem till.  Denna
referensbok skapas direkt från det nuvarande &gtkmm;-källkodsträdet
och är oöversatt.
</para>
      <para>Program som används för att skapa referensboken.</para>
      <para>
        Du kan använda denna referensbok under din gång genom
studiehandledningen och medan du programmerar applikationer.  Om
utdataformatet tillåter det så är klasserna i studiehandledningen
länkade till noteringen i denna referens när de uppträder.
</para>
    </partintro>
&referencebook;
</part>
<!--  <appendix label="A"><title/A/
  <appendix label="B"><title/B/
  <appendix label="C"><title/C/
  <appendix label="D"><title/Development/
  <appendix label="F"><title/F/
  <appendix label="G"><title/Gtk/
  <index><title/Index/
  </index> -->
</book>



