Now let's create a simple GUI from Glade. First you have to install Glade on your system, you may use synaptic package manager or Ubuntu software center to install it.
When you run Glade you may see the following window as the main window of Glade.
As you can see, left hand side of the window includes the palette which has all the gtkmm widget that glade support, and right hand side includes the properties of the selected widget and all the widgets list as a hierarchical list.
Every gtkmm GUI needs a top level window. Therefore first of all add a 'Window' from the palette, then you can add more widgets to the window. Also there is a widget type called 'Containers', containers can have one or more widgets on it. Therefore you should add proper containers to the empty window to include more widgets. For this example first add 'Vertical box' to window with 2 items. Then I added 'Label' to first position and 'Horizontal box' with 2 items to second position of vertical box. Likewise I have created the following GUI and saved it as GtkBuilder file format with the file name “gui.glade”. Also I have changed names of some widgets to make design file more understandable. The xml file for Glade GUI can be found at the end of this article for downloads.
Now let's write a C++ code for this GUI. As we all know C++ is a OOP language, but still we did not use the advantage of the OOP behavior for our gtkmm codes. Now let's see how to encapsulate all the things which are related to specific gui into one class.
First add new class to your project by right click on the eclipse project and selecting new class from the pop-up menu. It will create two file on the project's src folder as header file and source file. Copy following code to header (.h) file.
#include <gtkmm.h>
class FrmMain : public Gtk::Window{
protected:
Glib::RefPtr<Gtk::Builder> builder;
Gtk::Button *btnOk;
Gtk::Button *btnCancel;
Gtk::Label *lblNotice;
public:
FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);//constructor
protected:
//signal handlers
void on_ok_button_clicked();
void on_cancel_button_clicked();
};
Code explained
class FrmMain : public Gtk::Window{
Glib::RefPtr<Gtk::Builder> builder;
Gtk::Button *btnOk;
Gtk::Button *btnCancel;
Gtk::Label *lblNotice;
FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);//constructor
void on_ok_button_clicked();
void on_cancel_button_clicked();
The source file for the above header file will be,
#include "FrmMain.h"
using namespace Gtk;
FrmMain::FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) :
Gtk::Window(cobject), builder(refGlade){
builder->get_widget("btnOk", btnOk);
builder->get_widget("btnCancel", btnCancel);
builder->get_widget("lblNotice",lblNotice);
btnOk->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
btnCancel->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));
}
void FrmMain::on_ok_button_clicked(){
lblNotice->set_text("OK clicked");
}
void FrmMain::on_cancel_button_clicked(){
lblNotice->set_text("Cancel clicked");
}
Code explained
FrmMain::FrmMain(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) :
Gtk::Window(cobject), builder(refGlade){
builder->get_widget("btnOk", btnOk);
builder->get_widget("btnCancel", btnCancel);
builder->get_widget("lblNotice",lblNotice);
btnOk->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_ok_button_clicked));
btnCancel->signal_clicked().connect(sigc::mem_fun(*this, &FrmMain::on_cancel_button_clicked));
Glib::SignalProxy0< void > signal_clicked();
Here zero mean no parameters and void means return type is void. Let's see another example,
Glib::SignalProxy1< bool,GdkEventButton* > signal_button_press_event();
Here 1 mean one parameter with the type of GdkEventButton* and bool return type. Therefore your function will be,
bool on_my_button_press_event(GdkEventButton* event){
}
void FrmMain::on_ok_button_clicked(){
lblNotice->set_text("OK clicked");
}
void FrmMain::on_cancel_button_clicked(){
lblNotice->set_text("Cancel clicked");
}
Now these are the code for signal handlers. Each one will set a specific text to lblNotice label.
So our encapsulated class is ready for execution. But where is the place to import or load xml file to the project by giving the file name of the xml file? This task perform on the main function of the project as,
Main kit(argc,argv);
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("gui.glade");
FrmMain *frm = 0;
builder->get_widget_derived("frmMain", frm);
kit.run(*frm);
Code explained
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("gui.glade");
FrmMain *frm = 0;
builder->get_widget_derived("frmMain", frm);
kit.run(*frm);
If you run the code, you will see the result as,
when you click on OK and Cancel button the text of the label will change accordingly.
So now you can encapsulate all the variables, functions and structs, etc... to a class through this way. Also this will enable re-usability of the code.
The complete source code can be download here (with the glade xml file).
Hi. I'm trying to give row headers to my gtk:TableView. Any idea of how can I do that? the documentation only seems to cover column headers
ReplyDeleteThis really help me, thank you
ReplyDeleteIs there a way to style your buttons etc. within xml or another seperate file? Don't wanna style inside the c++ code.
ReplyDeleteCreating a GUI with GTKMM and Glade is impressive! The tutorial's step-by-step guidance simplifies the process of designing graphical interfaces for C++ applications. Ways Guard Business The combination of GTKMM and Glade empowers developers to create visually appealing and responsive user interfaces.
ReplyDelete