C++ Gtkmm Tutorial 3

9 October , 2013 bill C++ Programming

Introduction
In part 3 of this Gtkmm tutorial I will explain how to connect the buttons to signals and show dialogs when they are clicked.

The New Class File
The big change from tutorials 1 and 2 is that the creation and functionality of the window has been moved into it’s own file. It is a class inheriting Gtk::Window. Click file, new then class from the drop down menu in the IDE. Change the class name to mywindow and click create.

gtmm_tut3_new_class

The Code
main.cpp

#include <gtkmm.h>
#include "mywindow.h"

int main(int argc, char *argv[])
{
    Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "com.gtkmm.tutorial3.base");

    mywindow window;

    return app->run(window);
}

mywindow.h

#ifndef MYWINDOW_H
#define MYWINDOW_H

#include <gtkmm.h>

class mywindow : public Gtk::Window
{
    public:
        mywindow();
        virtual ~mywindow();
    protected:
        void on_big_button1_click();
        void on_button2_click();
        void on_button3_click();
        void on_quit_click();
        void dialog(Glib::ustring msg);
    private:
};
#endif // MYWINDOW_H

mywindow.cpp

#include "mywindow.h"

mywindow::mywindow()
{
    set_default_size(400, 200);
    set_title("Tutorial 3");

    Gtk::Box *vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0));
    add(*vbox);

    Gtk::MenuBar *menubar = Gtk::manage(new Gtk::MenuBar());
    vbox->pack_start(*menubar, Gtk::PACK_SHRINK, 0);

    Gtk::MenuItem *menuitem_file = Gtk::manage(new Gtk::MenuItem("_File", true));
    menubar->append(*menuitem_file);
    Gtk::Menu *filemenu = Gtk::manage(new Gtk::Menu());
    menuitem_file->set_submenu(*filemenu);
    Gtk::MenuItem *menuitem_quit = Gtk::manage(new Gtk::MenuItem("_Quit", true));
    menuitem_quit->signal_activate().connect(sigc::mem_fun(*this, &mywindow::on_quit_click));
    filemenu->append(*menuitem_quit);

    Gtk::Grid *grid = Gtk::manage(new Gtk::Grid);
    grid->set_border_width(10);
    vbox->add(*grid);

    Gtk::Button *b1 = Gtk::manage(new Gtk::Button("Big Button 1"));
    b1->set_hexpand(true);
    b1->set_vexpand(true);
    b1->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_big_button1_click));
    grid->attach(*b1, 0, 0, 1, 2);

    Gtk::Button *b2 = Gtk::manage(new Gtk::Button("Button 2"));
    b2->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_button2_click));
    grid->attach(*b2, 1, 0, 1, 1);

    Gtk::Button *b3 = Gtk::manage(new Gtk::Button("Button 3"));
    b3->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_button3_click));
    grid->attach(*b3, 1, 1, 1, 1);

    vbox->show_all();
}

mywindow::~mywindow()
{
    //dtor
}

void mywindow::on_big_button1_click()
{
    dialog("Big Button 1 Pressed!");
}

void mywindow::on_button2_click()
{
    dialog("Button 2 Pressed!");
}

void mywindow::on_button3_click()
{
    dialog("Button 3 Pressed!");
}

void mywindow::on_quit_click()
{
    hide();
}

void mywindow::dialog(Glib::ustring msg)
{
    Gtk::MessageDialog dlg(msg, false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK, true);
    dlg.set_title("Gtkmm Tutorial 3");
    dlg.run();
}

gtmm_tut3_app

Explaining The Code
In main.cpp all of the window creation has been removed.

#include "mywindow.h"

An include has been added that declares the interface of the mywindow class.

mywindow window;

A mywindow is created instead of a Gtk::Window. The mywindow class inherits Gtk::Window.

In mywindow.h the interface of the mywindow class is defined.

class mywindow : public Gtk::Window

We define out mywindow class and inherit the Gtk::Window. The inheritance is after the colon (:).

public:
    mywindow();
    virtual ~mywindow();
protected:
    void on_big_button1_click();
    void on_button2_click();
    void on_button3_click();
    void on_quit_click();
    void dialog(Glib::ustring msg);

We declare our functions that will be used in the mywindow class here.

In mywindow.cpp I will explain the differences from tutorial 1 and 2.

set_default_size(400, 200);
set_title("Tutorial 3");

Because the mywindow class is a Gtk::Window, the functions from Gtk::Window can be used directly without the need for a . or -> operator.

menuitem_quit->signal_activate().connect(sigc::mem_fun(*this, &mywindow::on_quit_click));
b1->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_big_button1_click));
b2->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_button2_click));
b3->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_button3_click));

Gtkmm makes it very easy to connect signals to functions. The instance of the class that will handle the event is handed to the connect function which will be this instance. The name of the class and function is also given to the connect function so the event knows what function to call in the given instance.

mywindow::~mywindow()
{
    //dtor
}

This is the class destructor which is not needed as Gtkmm will clean up all of the created widgets. Gtkmm managed widgets is covered in tutorial 2.

void mywindow::on_big_button1_click()
{
    dialog("Big Button 1 Pressed!");
}

void mywindow::on_button2_click()
{
    dialog("Button 2 Pressed!");
}

void mywindow::on_button3_click()
{
    dialog("Button 3 Pressed!");
}

The 3 functions above are the functions connected to button click events. The button functions call a dialog function with a string to display in the dialog.

void mywindow::on_quit_click()
{
    hide();
}

This is the function connected to the drop down menu quit event. Hiding the main window in a Gtkmm application will end it’s execution. hide is a function in Gtk::Window which mywindow has inherited so it can be called directly.

void mywindow::dialog(Glib::ustring msg)
{
    Gtk::MessageDialog dlg(msg, false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK, true);
    dlg.set_title("Gtkmm Tutorial 3");
    dlg.run();
}

This is a function that displays a dialog with the given text msg. The info icon is displayed on the dialog and it has only an ok button on it. The title is set to “Gtkmm Tutorial 3″ and then the dialog is run which displays it. The dialog display code is put in it’s own function to have it in 1 place not 3.

To Come
In tutorial 4 I will explain how to use some simple widgets such as the label and entry. We are getting closer to creating our simple game.

callback, gui, how to, linux, programming,


Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by WordPress. Designed by elogi.