Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Die Artikel ::  GTKmm Tutorial Teil 2  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
evilissimo
Chefkoch

Benutzerprofil
Anmeldungsdatum: 12.11.2003
Beiträge: 2282
Beitrag evilissimo Chefkoch 16:59:15 11.06.2006   Titel:   GTKmm Tutorial Teil 2            Zitieren

Grafische Benutzerschnittstellen in C++ mit GTKmm betriebssystemunabhängig gestalten Teil 2


Nach einer langen Auszeit habe ich mich dazu aufgerafft, endlich am Tutorial weiterzuschreiben. Ich hoffe, ihr könnt mir diese Pause verzeihen. :)

Wie versprochen behandle ich in diesem Teil das GTK+ Boxensystem, Labels, Buttons und Signale (Events). Ich werde ein paar Anwendungsbeispiele zu dem jeweiligen Thema anführen. Zum Schluss werde ich ein Beispiel mit allen Widgets zeigen und die eventuell noch unbekannten Schritte zusätzlich kommentieren.


1.GTK+ Boxensystem


1.1 Einführung

In GTK+ und somit auch in GTKmm werden die Widgets mit so genannten „boxes“ angeordnet. Das sind Container, die die Widgets aufnehmen können. Mit diesem Konzept ordnet man Widgets nur relativ und nicht absolut an - im Gegensatz zu dem, wie man es von den bekannteren GUI-Designern kennt (z.b. Borland C++ Builder, Visual C++, Visual C# usw.)

Dieses Konzept ermöglicht ein dynamisches Anpassen der Größe der Widgets zur jeweiligen Fenstergröße, ohne das sich der Programmierer darum kümmern müsste.

Von diesen Containern gibt es verschiedene Arten.
Es gibt Container, die nur jeweils ein Widget aufnehmen können ( diese wurden von Gtk::Bin abgeleitet ), Container die mehrere Widgets aufnehmen können, aber nur in eine Richtung, sprich Horizontal oder Vertikal. Dies wären z.B. Gtk::Hbox für die horizontale und Gtk::VBox für die vertikale Richtung.
Und zu guter Letzt gibt es noch eine Tabelle ( Gtk::Table ), in der man n x m Widgets, je nach dem, wie man es braucht, unterbringen kann, eben in einer tabellarischen Anordnung.

Eine Besonderheit ist aber das Widget Gtk::Fixed. Dies kann Elemente an festen Koordinaten aufnehmen, welche dann aber nicht resizable sind.
Ich werde auf diese Widgets nicht näher eingehen, da ich der Meinung bin, dass man auf diese auch verzichten kann, und mir das Programmieren mit dem Boxensystem wesentlich einfacher und eleganter erscheint.


1.2 Widgets und Boxes

Die Container Gtk::HBox und Gtk::VBox haben neben dem Standard-Konstruktor einen Konstruktor mit folgenden Parametern:

C++:
Gtk::HBox( bool homogenous , int padding );
Gtk::VBox( bool homogenous , int padding );


homogenous gibt hier an, dass der Platz der Widgets gleichmäßig aufgeteilt wird, wenn man true übergibt. Der Parameter padding gibt an, wie viel Platz in Pixeln zwischen den Bereichen der Widgets sein soll.

Um Widgets in die Boxes einzufügen, haben diese folgende Methoden:
C++:
void pack_start(Gtk::Widget& child, PackOptions options = PACK_EXPAND_WIDGET, guint padding = 0);
void pack_end(Gtk::Widget& child, PackOptions options = PACK_EXPAND_WIDGET, guint padding = 0);


Der erste Parameter ist eine Referenz auf das Widget, das wir hinzufügen wollen, z.B. ein Gtk::Button Objekt.

Der zweite Parameter gibt die PackOption an. Davon hängt es ab, wie sich die Anordnung der Widgets abspielt.

Es gibt 3 verschiedene Optionen:

  • PACK_SHRINK
  • PACK_EXPAND_WIDGET
  • PACK_EXPAND_PADDING


Gibt man PACK_SHRINK an, wird nur so viel Platz verwendet, wie das Widget wirklich braucht, und es wird niemals expandiert.

Bei PACK_EXPAND_WIDGET wird der freie Platz ausgefüllt, indem das Widget einfach vergrößert wird.

Bei PACK_EXPAND_PADDING wird der freie Platz einfach durch Abstände ausgefüllt; das Widget ist dann so gesehen zentriert in seinem Bereich. Der Bereich ist abhängig von dem Drumherum und das wird alles immer dynamisch angepasst.

Der dritte Parameter padding gibt an, wie viel Platz das Widget drum herum haben soll. Im Gegensatz zu dem Parameter des Konstruktors ist hier der Platz um das Widget herum gemeint.


1.3 Widgets und Tables

Gtk::Table hat folgenden Konstruktor:

C++:
Gtk::Table::Table(guint n_rows = 1, guint n_columns = 1, bool homogeneous = false)


Im Grunde ist dieser eigentlich selbsterklärend. n_rows gibt an, wie viele Zeilen das Table haben soll, und n_columns, wie viele Spalten.
homogenous gibt an, ob die Zellen homogen, sprich immer gleich groß, sein sollen.
Generell wäre ich vorsichtig mit der Verwendung von homogenous = true, da es viele Widgets gibt, die sehr viel Platz brauchen und es damit eine negative Auswirkung auf alle Widgets haben kann. Aber natürlich kann dieser Effekt auch erwünscht sein.
Das Beste ist, dass man sich generell erst mal mit den ganzen Containern auseinander setzt und damit etwas rumspielt, bis man das alles verstanden hat.
Das ist einfacher, als ellenlange Texte darüber zu lesen. Die eigene Erfahrung ist immer noch die lehrreichste. (Das ist meine Meinung ;) )


So und nun möchte ich euch erst mal schocken:

C++:
void Gtk::Table::attach(Gtk::Widget& child,
                        guint left_attach, guint right_attach,
                        guint top_attach, guint bottom_attach,
                        guint xoptions = Gtk::FILL | Gtk::EXPAND,
                        guint yoptions = Gtk::FILL | Gtk::EXPAND,
                        guint xpadding = 0, guint ypadding = 0);


Diese Methode ist natürlich auf den ersten Blick ziemlich abschreckend, aber die Verwendung ist einfacher, als es auf den ersten Blick aussehen mag.

child ist das Widget, das wir einfügen möchten und das als Referenz auf das Widget-Objekt übergeben wird.
left_attach gibt an, welche Zelle die Startposition auf der X-Achse ist.
right_attach gibt an, welche Zelle die Endposition auf der X-Achse ist, wobei die Endposition mindestens 1 größer als die Startposition sein muss.
top_attach gibt an, welche Zelle die Startposition auf der Y-Achse ist.
bottom_attach gibt an, welche Zelle die Endposition auf der Y-Achse ist, wobei die Endposition mindestens 1 größer als die Startposition sein muss.

xoptions gibt an, wie sich das Widget innerhalb seiner Zelle auf der X-Achse verhalten soll. Dies ist den PackOptions bei den Boxes ähnlich.
yoptions gibt an, wie sich das Widget innerhalb seiner Zelle auf der Y-Achse verhalten soll. Dies ist den PackOptions bei den Boxes ähnlich.

xpadding gibt an, wie viel Platz das Widget links und rechts von sich haben soll (freier Platz).
ypadding gibt an, wie viel Platz das Widget oben und unten von sich haben soll (freier Platz).


Um das Ganze zu verstehen, schauen wir uns einfach mal den Aufbau einer Tabelle an:

Code:
1
2
3
4
5
6
7
8
    0   1   2
  +---+---+---+
0 | a | b | c |
  +---+---+---+
1 | d | e | f |
  +---+---+---+
2 | g | h | i |
  +---+---+---+


Ich habe die Buchstaben in die Tabelle eingefügt, um besser erklären zu können, wie das Ganze dann beim Aufruf auszusehen hat. Die Zahlen entsprechen dem Zeilen- und Reihenindex.

Angenommen, wir wollen hier Widget 'a' in Zelle 0/0 einfügen, dann würde der Aufruf folgendermaßen aussehen:

C++:
 m_table.attach( a , 0 , 1 , 0 , 1 );


für b sieht das Ganze so aus:

C++:
 m_table.attach( b , 1 , 2 , 0 , 1 );


für e sieht das Ganze dann so aus:

C++:
 m_table.attach( e , 1 , 2 , 1 , 2 );


für i sieht das Ganze dann so aus:

C++:
 m_table.attach( i , 2 , 3 , 2 , 3 );


Nun möchte man aber, dass sich ein Widget über mehrere Zellen erstreckt. Wie das Widget 'd' in diesem Beispiel:
Code:
1
2
3
4
5
6
7
8
    0   1   2
  +---+---+---+
0 | a | b | c |
  +---+---+---+
1 |     d     |
  +---+---+---+
2 | e | f | g |
  +---+---+---+


Dann würde das Einfügen für das Widget 'd' folgendermaßen aussehen:

C++:
 m_table.attach( d , 0 , 3 , 1 , 2 );


Und für folgendes Layout
Code:
1
2
3
4
5
6
7
8
    0   1   2
  +---+---+---+
0 | a | b | c |
  +---+---+---+
1 |           |
  +     d     +
2 |           |
  +---+---+---+

so:
C++:
 m_table.attach( d , 0 , 3 , 1 , 3 );



Bei den xoptions und yoptions gibt es folgende Optionen:

  • FILL
  • SHRINK
  • EXPAND


Bei Gtk::FILL wird das Widget, sollte es kleiner als die Zelle selbst sein, auf Zellengröße vergrößert.
Gtk::EXPAND zwingt das Table zum Größerwerden, sollte der Platz für das Widget nicht ausreichen.
Wenn die Tabelle weniger Platz bekommt, als sie braucht, weil der Benutzer z.B. die Fenstergröße ändert, verschwindet das Wigdet einfach. Wenn man Gtk::SHRINK angibt, werden die Widgets in der Tabelle verkleinert, damit sie in den Bereich passen.


1.4 Single Widget Container

Es gibt auch Container-Widgets, die nur ein einziges Widget aufnehmen können. Bestes Beispiel ist Gtk::Window.

Diese Widgets haben nur die Methode add zum Hinzufügen der Widgets und nehmen als Parameter eine Referenz auf das Widget, das hinzugefügt werden soll.

Es gibt auch noch Ausnahmen bei den "Single Widget Containern": Das ist Gtk::Paned, aber auf das werde ich ein anderes Mal zu sprechen kommen ;)


1.5 Anwendung

In dem Beispiel werde ich bereits das erste Mal Gtk::Label benutzen, um zu verdeutlichen, wie man die Boxes verwendet.
C++:
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
struct MyWindow : Gtk::Window
{
    MyWindow();
 
    Gtk::VBox   m_vbox;
    Gtk::HBox   m_hbox;
    Gtk::Label  m_label1;
    Gtk::Label  m_label2;
    Gtk::Label  m_label3;
};    
 
MyWindow::MyWindow()
: Gtk::Window(),
  m_vbox(true,5),// homogene Ausrichtung und 5 px Abstand
  m_hbox(true,5),// homogene Ausrichtung und 5 px Abstand
  m_label1("Label 1"),
  m_label2("Label 2"),
  m_label3("Label 3")
{
    // Text der Titelleiste setzen
    set_title("GTKmm Tutorial Teil 2");
 
    // m_label1 der horizontalen box als erstes Element übergeben
    m_hbox.pack_start(m_label1);
    // m_label2 der horizontalen box als zweites Element übergeben
    m_hbox.pack_start(m_label2);
 
    // m_hbox der vertikalen box als erstes Element übergeben
    m_vbox.pack_start(m_hbox);
    // m_label3 der vertikalen box als zweites Element übergeben
    m_vbox.pack_start(m_label3);
 
    // die vertikale Box an das Fenster übergeben
    add(m_vbox);
 
    // sorgt dafür, dass alle Widgets angezeigt werden
    show_all_children();
}


Und so sieht's aus:



Ein Beispiel für die Verwendung eines Gtk::Table Containers findet ihr im Anwendungsbeispiel für die Buttons :)


2.Signale


2.1 Einführung

In GTKmm wird, um auf Signale/Events zu reagieren, die Bibliothek SigC++ verwendet. SigC++ ist sehr flexibel und mächtig und ist sehr vielseitig verwendbar. Es ist möglich, Funktionen und Methoden aller Art zu verwenden, und es besteht sogar die Möglichkeit, zusätzliche Parameter an ein Signal zu binden, um zusätzliche Daten an den eigenen Signalhandler zu übergeben.

Um nicht zu ausschweifend zu werden, zeige ich euch einfach ein paar Verwendungsbeispiele:

2.2 Anwendung


2.2.1 Eine Funktion als Signalhandler

C++:
void on_button_clicked(); // Unser Signalhandler
 
Gtk::Button button("Ich bin ein button"); // Wir verwenden einen Button zur Veranschaulichung
 
button.signal_clicked().connect(sigc::ptr_fun(&on_button_clicked));


Wie man sieht, ist die Verwendung recht unkompliziert. Die meisten Widgets haben spezielle Zugriffsmethoden, die es einem erlauben, Signalhandler zu setzen.

Gtk::Button hat in diesem Fall z.B. die Methode Gtk::Button::signal_clicked(), um den Handler zu setzen, der auf ein Klick-Ereignis reagiert.

Die Signale aller Widgets zu beschreiben, würde den Rahmen dieses Tutorials sprengen. Sie sollten daher der GTKmm-Dokumentation entnommen werden.


2.2.2 Methoden als Signalhandler

C++:
1
2
3
4
5
6
7
8
9
10
struct test
{
   void on_button_clicked(); // Unser Signalhandler
};
 
Gtk::Button button("Ich bin ein button"); // Wir verwenden einen Button zur Veranschaulichung
 
test test_obj;
 
button.signal_clicked().connect(sigc::mem_fun(test_obj,&test::on_button_clicked));

Um Methoden zu binden, bietet SigC++ die Funktion sigc::mem_fun.

Als ersten Parameter nimmt sigc::mem_fun eine Referenz auf das Objekt der Methode und als zweiten Parameter den Methodenzeiger auf die Methode an.


2.2.3 Binden von Parametern

Da man manchmal zusätzliche Parameter bei einem Ereignis braucht, um auf ein Signal zu reagieren, bietet SigC++ die Funktion sigc::bind an, um zusätzliche Parameter an den Signalhandler zu übergeben.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct data
{};
struct test
{
   void on_button_clicked(data d);
};
 
Gtk::Button button("Ich bin ein button"); // Wir verwenden einen Button zur Veranschaulichung
 
test test_obj;
data d;
 
button.signal_clicked().connect( sigc::bind<data>( sigc::mem_fun( test_obj , &test::on_button_clicked ), d ) );



3.Buttons


3.1 Einführung

In GTKmm gibt es neben den "normalen" Buttons auch RadioButtons, CheckButtons (aka CheckBox) und so genannte ToggleButtons. Viel zu erzählen gibt es hier nicht.

Schaut euch einfach mal das Beispiel an und ihr seht, dass die Verwendung sehr simpel ist. In diesem Beispiel kann man auch schön die Verwendung der oben besprochenen Parameterbindung sehen. Des Weiteren verwende ich ein Gtk::Table als Container, um dessen Verwendung auch darzustellen. :)


3.2 Anwendung

C++:
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
struct MyWindow : Gtk::Window
{
    MyWindow();
private:
    Gtk::ToggleButton     m_toggle_button;
 
    Gtk::CheckButton      m_check_button1;
    Gtk::CheckButton      m_check_button2;
 
    Gtk::RadioButtonGroup m_radiogroup;
    Gtk::RadioButton      m_radio_button1;
    Gtk::RadioButton      m_radio_button2;
   
    Gtk::Button           m_button;
 
    Gtk::Table            m_table;
 
private:
    void attach_widgets_to_table();
    void connect_signals();
    void on_toggle_button_clicked();
    void on_radio_button_clicked(int);
    void on_check_button_clicked(int,Gtk::CheckButton const *);
    void on_button_clicked();
};
 
MyWindow::MyWindow()
: Gtk::Window(),
  m_toggle_button("Gtk::ToggleButton"),
  m_check_button1("Gtk::CheckButton 1"),
  m_check_button2("Gtk::CheckButton 2"),
  m_radiogroup(),
  m_radio_button1(m_radiogroup,"Gtk::RadioButton 1"),// RadioButton einer Gruppe zuordnen und Beschriftung geben
  m_radio_button2(m_radiogroup,"Gtk::RadioButton 2"),// RadioButton einer Gruppe zuordnen und Beschriftung geben
  m_button("Gtk::Button"),
  m_table(3,2,true) // 3 Zeilen, 2 Spalten, homogene Aufteilung der Zellen
{
    // Standardfenstergröße setzen; Breite: 400px Höhe: 170px
    set_default_size(400,170);
 
    // Titel setzen
    set_title("GTKmm Tutorial Teil 2");
 
    // Widgets in das Table einfügen
    attach_widgets_to_table();
 
    // Signale verbinden
    connect_signals();
   
    // Tabelle dem Fenster übergeben
    add(m_table);
   
    // Alle Widgets anzeigen
    show_all_children();
}
 
void MyWindow::attach_widgets_to_table()
{
    // Button in Zelle(0,0) einfügen
    m_table.attach(m_button,0,1,0,1);
 
    // ToggleButton in Zelle(1,0) einfügen
    m_table.attach(m_toggle_button,1,2,0,1);
 
    // CheckButton in Zelle(0,1) einfügen
    m_table.attach(m_check_button1,0,1,1,2);
 
    // CheckButton in Zelle(1,1) einfügen
    m_table.attach(m_check_button2,1,2,1,2);
 
    // RadioButton in Zelle(0,2) einfügen
    m_table.attach(m_radio_button1,0,1,2,3);
 
    // RadioButton in Zelle(1,2) einfügen
    m_table.attach(m_radio_button2,1,2,2,3);
}
 
void MyWindow::connect_signals()
{
    // Signale verbinden:
 
    m_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button_clicked));
 
    m_toggle_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_toggle_button_clicked));
 
    m_radio_button1.signal_clicked().connect(sigc::bind<int>(sigc::mem_fun(*this,&MyWindow::on_radio_button_clicked),1));
 
    m_radio_button2.signal_clicked().connect(sigc::bind<int>(sigc::mem_fun(*this,&MyWindow::on_radio_button_clicked),2));
 
    m_check_button1.signal_clicked().connect(sigc::bind<int,Gtk::CheckButton const *>(sigc::mem_fun(*this,&MyWindow::on_check_button_clicked),1,&m_check_button1));
 
    m_check_button2.signal_clicked().connect(sigc::bind<int,Gtk::CheckButton const *>(sigc::mem_fun(*this,&MyWindow::on_check_button_clicked),2,&m_check_button2));
}
 
void MyWindow::on_toggle_button_clicked()
{
    Glib::ustring msg = "ToggleButton wurde angeklickt. Neuer Status ist: ";
    if(m_toggle_button.get_active())
        msg += "gedrueckt";
    else
        msg += "nicht gedrueckt";
   
    Gtk::MessageDialog dia(*this,msg);
   
    dia.run();
}
 
void MyWindow::on_radio_button_clicked(int which)
{
    Glib::ustring msg = "Der Status von RadioButton ";
    if(which == 1)
        msg += "1 hat sich geaendert";
    else
        msg += "2 hat sich geaendert";
 
    Gtk::MessageDialog dia(*this,msg);
 
    dia.run();
}
 
void MyWindow::on_check_button_clicked(int which, Gtk::CheckButton const * cb)
{
    if(!cb)
    {
        Gtk::MessageDialog dia(*this,"Es ist ein Fehler aufgetreten",false,Gtk::MESSAGE_ERROR);
        dia.run();
        return;
    }
 
    Glib::ustring msg = "CheckButton ";
    if(which == 1)
        msg += "1";
    else
        msg += "2";
 
    if(cb->get_active())
        msg += " markiert";
    else
        msg += " Markierung aufgehoben";
 
    Gtk::MessageDialog dia(*this,msg);
 
    dia.run();
}
 
void MyWindow::on_button_clicked()
{
    Gtk::MessageDialog dia(*this,"Button wurde angeklickt :)");
   
    dia.run();
}
 
 
int main(int argc, char **argv)
{
    Gtk::Main main(argc,argv);
    MyWindow window;
    main.run(window);
    return 0;
}


Und so sieht's aus:




4.Implementation eines weiteren Beispiels

C++:
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
#include <gtkmm.h>
 
struct MyWindow : Gtk::Window
{
    MyWindow();
    ~MyWindow();
 
    void on_button1_clicked();
    void on_button2_clicked();
 
    Gtk::Button m_button1;
    Gtk::Button m_button2;
    Gtk::Label  m_label;
    Gtk::VBox   m_vbox;
    Gtk::HBox   m_hbox;
};
 
MyWindow::MyWindow()
: Gtk::Window(),
  m_button1("Klick mich1"),
  m_button2("Klick mich2"),
  m_label("<u><i><b>Ich bin ein Label</b></i></u>"),
  m_vbox(true,5),
  m_hbox(true,5)
{
    set_title("GTKmm Tutorial Teil 2");
 
    m_label.set_use_markup(true);
   
    m_hbox.pack_start(m_button1);
    m_hbox.pack_end(m_button2);
 
    m_button1.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button1_clicked));
    m_button2.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button2_clicked));
 
    m_vbox.pack_start(m_hbox);
    m_vbox.pack_start(m_label);
   
    add(m_vbox);
   
    set_default_size(200,100);
    show_all_children(true);
}
MyWindow::~MyWindow()
{
 
}
 
void MyWindow::on_button1_clicked()
{
    m_label.set_markup("<b><i>Button 1</i> wurde angeklickt</b>");
    m_label.set_use_markup(true);
}
void MyWindow::on_button2_clicked()
{
    m_label.set_markup("<b><u>Button 2</u> wurde angeklickt</b>");
    m_label.set_use_markup(true);
}
 
 
int main(int argc, char **argv)
{
    Gtk::Main main(argc,argv);
    MyWindow window;
    main.run(window);
    return 0;
}


Und last but not least: So sieht's aus:




So, diesmal gab's viel Code und wenig Erklärungen, so wird es auch im nächsten Teil aussehen, da ich nicht glaube, dass es zu den Widgets viel zu erzählen gibt. Ich hoffe, dass dieses Tutorial hilfreich war.

Ich schmeiße mich gleich auch ans nächste Tutorial, damit da nicht wieder so ne Ewigkeit dazwischen liegt :)

BR

evilissimo

_________________
evilissimo - R.I.P. dmr
< Moderator im C++/CLI Forum und im C++ Forum >
About Singletons: "Anyway, if our experts can make this mistake, you have made it and you don't even know about it."


Zuletzt bearbeitet von GPC am 09:53:11 21.11.2006, insgesamt 9-mal bearbeitet
Fan des guten Essens
Unregistrierter




Beitrag Fan des guten Essens Unregistrierter 08:12:26 14.06.2006   Titel:              Zitieren

evilissimo, lass dich knuddeln!

Ich freu mich! Endlich ein neuer Teil! :)




Das Magazin ist ja allgemein superklasse, aber deine GTK-Reihe ist mein persönliches Highlight. Aber auch ein Lob an die anderen Autoren, fast alles hier ist uneingeschränkt empfehlenswert. :)
Fan des guten Essens
Unregistrierter




Beitrag Fan des guten Essens Unregistrierter 08:34:30 14.06.2006   Titel:              Zitieren

So, habs mir jetzt durchgelsen, ein Fehler ist mir aufgefallen:

Zitat:
xpadding gibt an, wie viel Platz das Widget links und rechts von sich haben soll (freier Platz).
xpadding gibt an, wie viel Platz das Widget oben und unten von sich haben soll (freier Platz).


Einmal müsste es ypadding heißen.

Erklärungen sind wirklich knapp ausgefallen, aber haut noch so hin, ansonsten schön! :)
Fan des guten Essens
Unregistrierter




Beitrag Fan des guten Essens Unregistrierter 08:36:51 14.06.2006   Titel:              Zitieren

Shit, jetzt hab ich noch was vergessen:

Bei der Tabelle ist deine Erklärung etwas verwirrend, weil du die Zellen nummerierst, geeigneter wäre aber eine Nummerierung derer Eckpunkte.
Also wenn ich die erste Zelle haben will, mach ich das zweimal von Eckpunkt 0 ganz außen bis Eckpunkt Nummer 1.
Und nicht von Zelle 0 nach Zelle 1....

:)
evilissimo
Chefkoch

Benutzerprofil
Anmeldungsdatum: 12.11.2003
Beiträge: 2282
Beitrag evilissimo Chefkoch 08:46:00 14.06.2006   Titel:              Zitieren

Fan des guten Essens schrieb:
Shit, jetzt hab ich noch was vergessen:

Bei der Tabelle ist deine Erklärung etwas verwirrend, weil du die Zellen nummerierst, geeigneter wäre aber eine Nummerierung derer Eckpunkte.
Also wenn ich die erste Zelle haben will, mach ich das zweimal von Eckpunkt 0 ganz außen bis Eckpunkt Nummer 1.
Und nicht von Zelle 0 nach Zelle 1....

:)


Hmm wohl wahr.

_________________
evilissimo - R.I.P. dmr
< Moderator im C++/CLI Forum und im C++ Forum >
About Singletons: "Anyway, if our experts can make this mistake, you have made it and you don't even know about it."
Benutzername:
Unregistrierter




Beitrag Benutzername: Unregistrierter 11:49:20 31.07.2006   Titel:              Zitieren

hil evilissimo

zu allererst: Sehr gute Arbeit.
Mein Verbesserungsvorschlag: Du könntest noch deine Teile untereinander verlinken, also am Ende von Teil 1 noch einen Link auf Teil 2 setzen usw.
evilissimo
Chefkoch

Benutzerprofil
Anmeldungsdatum: 12.11.2003
Beiträge: 2282
Beitrag evilissimo Chefkoch 13:14:26 31.07.2006   Titel:              Zitieren

Benutzername: schrieb:
hil evilissimo

zu allererst: Sehr gute Arbeit.
Mein Verbesserungsvorschlag: Du könntest noch deine Teile untereinander verlinken, also am Ende von Teil 1 noch einen Link auf Teil 2 setzen usw.


Danke für den Vorschlag. Habe ich gemacht ;)

BR
Vinzenz

_________________
evilissimo - R.I.P. dmr
< Moderator im C++/CLI Forum und im C++ Forum >
About Singletons: "Anyway, if our experts can make this mistake, you have made it and you don't even know about it."
Benutzername:
Unregistrierter




Beitrag Benutzername: Unregistrierter 16:59:03 11.08.2006   Titel:              Zitieren

Hi evilissimo,
ich habe eine Tabelle mit 3 Zeilen und 2 Spalten. in der linken spalte sind 3 buttons und in der rechten ein Textview. Wenn ich aber bei der Tabelle homogenous auf false setze zeigt er nur die linke spalte an, setze ich auf true zeigt er alles an, allerdings ist die aufteilung jeweils halbe halbe, was ein wenig doof aussieht. wie kann ich angeben wieviel pix oder % die linke spalte einnehmen soll?
evilissimo
Chefkoch

Benutzerprofil
Anmeldungsdatum: 12.11.2003
Beiträge: 2282
Beitrag evilissimo Chefkoch 17:37:46 11.08.2006   Titel:              Zitieren

Benutzername: schrieb:
Hi evilissimo,
ich habe eine Tabelle mit 3 Zeilen und 2 Spalten. in der linken spalte sind 3 buttons und in der rechten ein Textview. Wenn ich aber bei der Tabelle homogenous auf false setze zeigt er nur die linke spalte an, setze ich auf true zeigt er alles an, allerdings ist die aufteilung jeweils halbe halbe, was ein wenig doof aussieht. wie kann ich angeben wieviel pix oder % die linke spalte einnehmen soll?


Du kannst die Prozentzahl oder Anzahl der Pixel nicht direkt setzen. Eine Möglichkeit wäre, dass du die Tabelle nicht homogen anlegst, die Buttons mit Gtk::SHRINK einsetzt und ein Padding setzt bis es so aussieht wie du das haben willst und dann eben das ScrolledWindow vom Treeview mit Gtk::EXPAND widget in die Tabelle einfügst.

Alternativ wäre HBox und eine VBox bzw eine VButtonBox für die Buttons vielleicht besser.

BR
Vinzenz

_________________
evilissimo - R.I.P. dmr
< Moderator im C++/CLI Forum und im C++ Forum >
About Singletons: "Anyway, if our experts can make this mistake, you have made it and you don't even know about it."


Zuletzt bearbeitet von evilissimo am 17:38:44 11.08.2006, insgesamt 1-mal bearbeitet
?!
Unregistrierter




Beitrag ?! Unregistrierter 13:24:23 13.05.2007   Titel:              Zitieren

ich hab gerade mit glade-2 einen editor erstellt, aber ch kapier folgendes nicht:

ich hab 2fenster: ein mainwindow und einen aboutdialog. ich will, dass der aboutdialog aufgerufen wird, sobald man auf help klickt (ein icon in der mueleiste(deteils: label: help, name: imagemenuitem33, handler: on_aboutdialog_show)

und im aboutdialog hab ich bei signals folgendes eingetragen:

Signals: open, close
Handler: on_aboutdialog_show, on_aboutdialog_close
objekt: aboutdialog, aboutdialog

und in der menüleiste folgendes: (menubar3)

signal: activate current
handler: on_aboutdialog_show
objekt: menuitem33

nachdem er den sourcecode erstellt hatte, hab ich da paar kleinigkeiten geändert

main.c:
C++:
1
2
3
4
5
6
7
8
9
  X3_Editor = create_X3_Editor ();
  gtk_widget_show (X3_Editor);
  g_signal_connect ((gpointer) X3_Editor, "destroy",
            G_CALLBACK (gtk_main_quit), NULL);
  aboutdialog = create_aboutdialog ();
  gtk_widget_show (aboutdialog);
    gtk_widget_hide (aboutdialog); //damit der dia unsichtbar ist
  g_signal_connect ((gpointer) aboutdialog, "destroy",
            G_CALLBACK (gtk_main_quit), NULL);


callback
C++:
1
2
3
4
5
6
7
8
9
  GtkWidget *X3_Editor; //definition vom mainwindow
  GtkWidget *aboutdialog; //definition vom aboutdialog
 
void
on_aboutdialog_show (GtkMenuShell * menushell,
             gboolean force_hide, gpointer user_data)
{
  gtk_widget_show (aboutdialog); //damit der dia wieder sichtbar wird
}


wenn ich komiliere und starte, dann kommt mein editor, das aboutfenster ist unsichtbar, aber dafür kann man es auch nicht mehr sichtbar machen (d.h. bei einem klick auf help passiert nix)

was läuft da falsch?

vielen dank schonmal im voraus!

btw: wie bekommt man glade dazu einen c++ sourcecode zu erstellen? wenn ich bei optionen c++ einstelle, bekomme ich keinen sc sondern einen fehler, in dem steht, dass ich sicherstellen soll, dass glade-- installiert ist. ich habs gedownloaded und hab es sogut wie in jeden ordner gestckt, aber es kommt immer wieder derselbe fehler...
C++ Forum :: Die Artikel ::  GTKmm Tutorial Teil 2  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können keine Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.