Category Archives: Programming

I2C scanner for Arduino

The following code is an I2C scanner for Arduino. It requests data from each address within the range [0:255]. I2C slaves that answer are display on the terminal.

#include 


void setup() { 
 //Initialize serial and wait for port to open:
  Serial.begin(115200); 
  
  // prints title with ending line break 
  Serial.println("I2C scanner ::: www.lucidarme.me"); 
} 


void loop() 
{
  // Test each I2C address 
  for (int i=0;i<256;i++)
  {
    // Request data (read one byte)
    Wire.requestFrom(i, 1);

    // If slave answers, a device is found
    if (Wire.available())
    {
      // Display address
      Serial.print(i,DEC);
      Serial.print("\t0x");
      Serial.print(i,HEX);
      Serial.print("\t");    
      Serial.print("0b");
      Serial.print(i,BIN);
      Serial.print("\t");
      Serial.println("Device found");
    }
    
//    delay(100);
  }
  Serial.println("End of scan"); 
  while (1);
} 

gtkmm – example 24

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to create an application with Tabs. The first tab display a button and the second tab display a label.

capture

Download


Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
    // Initialize gtkmm and create the main window
    Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
    // Create the window
    mainwindow window;
    // Start main loop
    return app->run(window);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 




// The class mainwindow inherits from Gtk::Window
class mainwindow : public Gtk::Window
{
    // Constructor and destructor
public:    
	mainwindow();
	virtual             ~mainwindow();

protected:
    //Signal handlers (run when the button is clicked)
    void                    on_button_clicked();

    //Page selector
    Gtk::Notebook           Selector;

    // Button for the first page
    Gtk::Button             Button;

    // Label for the second page
    Gtk::Label              Label;
};


#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"



// Constructor of the main Window (build ui interface).
mainwindow::mainwindow()
{
    // Resize the main window and set border width
    this->resize(400,200);
    set_border_width(5);

    // Add the label and connect the button
    Button.add_label("Page 1 (button)");
    Button.signal_clicked().connect(sigc::mem_fun(*this,&mainwindow::on_button_clicked));

    // Set label text
    Label.set_text("Page 2 (label)");

    // Add the widgets (button and label) in the notebook
    Selector.append_page(Button, "First");
    Selector.append_page(Label, "Second");

    // This packs the button into the Window (a container).
    add(Selector);
    show_all_children();
}




// Destructor of the class
mainwindow::~mainwindow()
{}

// Call when the button os clicked and display my url
void mainwindow::on_button_clicked()
{
    std::cout << "www.lucidarme.me" << std::endl;
}

C++ inheritance

This post shows through a simple example how inheritance works. Let’s consider a first class Parent with two member functions (fct1 and fct2). Note that fct2 is virtual. Let’s now consider a second class Child (which inherit from the class Parent) that also contain two member functions (fct1 and fct2). All this functions are protected, and they can be called from outside thanks to the public member functions callFunction1 and callFunction2 that belong to the class Parent. The question is : what will happen when these functions are called from the class Child ? In the case of fct1, which is not virtual, this is the function fct1 from the class Parent that is called. On the other hand, in the case of fct2, which is virtual, this is the function belonging to the class Child that is called. Note that the parent function can be called with the following syntax: Parent::fct2(). Note also that when calling the constructor of Child, the Parent constructor is called first.
The following program illustrates this explaination:

#include 


class Parent
{
public:
    Parent() {std::cout << "Constructor Parent" << std::endl;}

    void            callFunction1() { fct1(); }
    void            callFunction2() { fct2(); }

protected:
    void            fct1() 
    {   std::cout << "Class Parent :: function 1" << std::endl; }
    
    virtual void    fct2() 
    {   std::cout << "Class Parent :: function 2" << std::endl; }
};



class Child : public Parent
{
public:
    Child() {std::cout << "Constructor Child" << std::endl;}

protected:
    void            fct1() 
    {   std::cout << "Class Child :: function 1" << std::endl; }
    
    void            fct2() 
    {   std::cout << "Class Child :: function 2" << std::endl; 
        Parent::fct2(); }
};

int main()
{

    Child c;
    c.callFunction1();
    c.callFunction2();
    return 0;
}

This code output the following lines. The parent constructor is called before the child constructor. For fct1, this is the parent function called. For fct2, this is the child function called because the parent function is virtual.

Constructor Parent
Constructor Child
Class Parent :: function 1
Class Child :: function 2
Class Parent :: function 2

gtkmm – example 23

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to display an image (Pixbuf) into a cairo drawing area. The image can be moved, scaled, fitted or centered with the mouse. Scale is done with the scroll button of the mouse. Move is controlled with the left button. The right button display a popup menu with several options as illustrated below.

capture

Download


Source code

main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;
	
	// Create the drawing and add an image from file
	ScrollImage Img;    	
	Img.set_image_from_file("gtk.png");
	
	// Insert the drawing in the window
	window.add(Img);
	// Resize the window
	window.resize(600,400);
	// Set the window title
	window.set_title("ScrollImage");
	// Show the drawing
	Img.show();
	
	// Start main loop
	return app->run(window);
}

scrollimage.h

#ifndef SCROLLIMAGE_H
#define SCROLLIMAGE_H

#include 
#include 


// Minimun scale (low boundary)
#define			MIN_SCALE			0.05



class ScrollImage : public Gtk::DrawingArea
{
public:
	
	
	/*!
	 * \brief ScrollImage				Constructor, initialize the widget.
	 */
	ScrollImage();
	
	
	/*!
	 * \brief set_image_from_file		Load the image to display.
	 * \param filename					File name of the image.
	 */
	void set_image_from_file(const std::string& filename);
	
	
	
	
	
protected:
	
	/*!
	 * \brief on_draw					Override the draw handler : update display.
	 *									Don't call this function to update display, call queue_draw().
	 * \param cr						Cairo context.
	 * \return							Always false.
	 */
	virtual bool on_draw(const Cairo::RefPtr& cr);
	
	
	/*!
	 * \brief displayTarget				Display a little target at coordinates x,y.
	 * \param cr						Cairo context.
	 * \param x							x-coordinate of the center of the target.
	 * \param y							y-coordinate of the center of the target.
	 */
	void displayTarget(const Cairo::RefPtr& cr,double x, double y);
	
	
	/*!
	 * \brief on_scroll_event			This function is called when the mouse scroll changes.
	 *									This is a default handler for the signal signal_scroll_event().
	 * \param event						Properties of the event.
	 * \return							Always true (the event is processed).
	 */
	bool on_scroll_event(GdkEventScroll *event);
	
	
	/*!
	 * \brief on_button_press_event		This function is called when a mouse button is pressed.
	 *									This is a default handler for the signal signal_button_press_event().
	 * \param event						Properties of the event.
	 * \return							True if the event is processed, false otherwise.
	 */
	bool on_button_press_event(GdkEventButton *event);
	
	
	/*!
	 * \brief on_button_release_event	This function is called when a mouse button is released
	 *									This is a default handler for the signal signal_button_release_event().
	 * \param event						Properties of the event.
	 * \return							True if the event is processed, false otherwise.
	 */
	bool on_button_release_event(GdkEventButton *event);
	
	
	/*!
	 * \brief on_motion_notify_event	This function is called when the pointer is moved
	 *									This is a default handler for the signal signal_motion_notify_event().
	 * \param event						Properties of the event.
	 * \return							True if the event is processed, false otherwise.
	 */
	bool on_motion_notify_event(GdkEventMotion*event);
	
	
	
protected:
	/*!
	 * \brief resetView					Reset the view (best image fit in the window).
	 * \param winWidth					Width of the window (in pixels).
	 * \param winHeight					Height of the window (in pixels).
	 * \param imgWidth					Width of the image (in pixels).
	 * \param imgHeight					Height of the image (in pixels).
	 */
	void                        fitImage(int winWidth,int winHeight, int imgWidth, int imgHeight);
	
	
	/*!
	 * \brief fit						Set the fit flag to one and update display
	 *									Next call of on_draw will fit the image according to the drawing area.
	 */
	void                        fit();
	
	
	/*!
	 * \brief reset						Reset display (center the image and set scale to 1:1) and update display
	 */
	void                        reset();
	
	
	/*!
	 * \brief resetScale				Set scale to 1:1 and update display
	 */
	void                        resetScale();
	
	
	/*!
	 * \brief setCenter					Center the image on the pointer position from last click
	 */
	void                        setCenter();
	
	/*!
	 * \brief showHideTarget			Show or hide the center target and update display
	 */
	void                        showHideTarget();
	
	
private:
	
	// Image to display
	Glib::RefPtr   image;
	
	// Scale of the image
	double                      scale;
	
	// Coordinates of the image point to place at the center of the window (focussed pixel)
	double                      imgFocusX,imgFocusY;
	
	// Used to memorize last mouse coordinates
	int                         lastXMouse, lastYMouse;
	
	// Flags
	bool                        resetFlag;
	bool                        moveFlag;
	bool                        targetFlag;
	
	// Popup menu and submenus
	
	// Main popup menu
	Gtk::Menu                   m_Menu_Popup;
	Gtk::MenuItem               MenuItemFit;
	Gtk::MenuItem               MenuItemRstView;
	Gtk::MenuItem               MenuItemRstScale;
	Gtk::MenuItem               MenuItemSetCenter;
	Gtk::MenuItem               MenuItemTarget;
	Gtk::SeparatorMenuItem      MenuItemLine1;
	Gtk::SeparatorMenuItem      MenuItemLine2;
	
};

#endif // SCROLLIMAGE_H

scrollimage.cpp

#include "scrollimage.h"


// Constructor
ScrollImage::ScrollImage()
{
	// Set masks for mouse events
	add_events(Gdk::BUTTON_PRESS_MASK |
			   Gdk::BUTTON_RELEASE_MASK |
			   Gdk::SCROLL_MASK |
			   Gdk::SMOOTH_SCROLL_MASK |
			   Gdk::POINTER_MOTION_MASK);

	// ::: Create popup menu :::

	// Add and connect action set pointer as center
	MenuItemSetCenter.set_label("Set center here");
	MenuItemSetCenter.signal_activate().connect(sigc::mem_fun(*this,&ScrollImage::setCenter));
	m_Menu_Popup.append(MenuItemSetCenter);

	// Add a separator
	m_Menu_Popup.append(MenuItemLine1);

	// Add and connect action Fit image to drawing area
	MenuItemFit.set_label("Fit image");
	MenuItemFit.signal_activate().connect(sigc::mem_fun(*this,&ScrollImage::fit));
	m_Menu_Popup.append(MenuItemFit);

	// Add and connect action reset (center and set scale to 1)
	MenuItemRstView.set_label("Reset view");
	MenuItemRstView.signal_activate().connect(sigc::mem_fun(*this,&ScrollImage::reset));
	m_Menu_Popup.append(MenuItemRstView);

	// Add and connect action reset scale to 1
	MenuItemRstScale.set_label("Reset scale");
	MenuItemRstScale.signal_activate().connect(sigc::mem_fun(*this,&ScrollImage::resetScale));
	m_Menu_Popup.append(MenuItemRstScale);

	// Add a separator
	m_Menu_Popup.append(MenuItemLine2);

	// Add and connect action reset scale to 1
	MenuItemTarget.set_label("Hide center target");
	MenuItemTarget.signal_activate().connect(sigc::mem_fun(*this,&ScrollImage::showHideTarget));
	m_Menu_Popup.append(MenuItemTarget);

	// Show the menu
	m_Menu_Popup.show_all();
	// Connect the menu to this Widget
	m_Menu_Popup.accelerate(*this);


	// ::: Initialize view and flags :::
	fit();
	moveFlag=false;
	targetFlag=true;
}



// Load an image from file
void ScrollImage::set_image_from_file(const std::string& filename)
{
	image = Gdk::Pixbuf::create_from_file(filename);
}



// Mouse wheel event detected : update scale
bool ScrollImage::on_scroll_event(GdkEventScroll *event)
{
	// Compute the new scale according to mouse scroll
	double newScale=scale*(1-event->delta_y/20);
	if (newScalex - get_allocated_width()/2.;
	double DeltaY=event->y - get_allocated_height()/2.;
	imgFocusX=imgFocusX + DeltaX/scale - DeltaX/newScale ;
	imgFocusY=imgFocusY + DeltaY/scale - DeltaY/newScale ;;

	// Update scale and redraw the widget
	scale=newScale;
	queue_draw();

	// Event has been handled
	return true;
}


// Mouse button pressed : process mouse button event
bool ScrollImage::on_button_press_event(GdkEventButton *event)
{

	// Check if the event is a left button click.
	if (event->button == 1)
	{
		// Memorize pointer position
		lastXMouse=event->x;
		lastYMouse=event->y;
		// Start moving the view
		moveFlag=true;
		// Event has been handled
		return true;
	}

	// Check if the event is a right button click.
	if(event->button == 3)
	{
		// Memorize mouse coordinates
		lastXMouse=event->x;
		lastYMouse=event->y;
		// Display the popup menu
		m_Menu_Popup.popup(event->button, event->time);
		// The event has been handled.
		return true;
	}
	// Event has not been handled
	return false;
}



// Mouse button released : process mouse button event
bool ScrollImage::on_button_release_event(GdkEventButton *event)
{
	// Check if it is the left button
	if (event->button==1 && moveFlag)
	{
		// End of motion
		moveFlag=false;
		// Update image focus
		imgFocusX -= (event->x-lastXMouse)/scale;
		imgFocusY -= (event->y-lastYMouse)/scale;
		// Update display
		queue_draw();
		return true;
	}
	// Event has been handled
	return false;
}



// Mouse pointer moved : process event
bool ScrollImage::on_motion_notify_event (GdkEventMotion*event)
{

	// If the left button is pressed, move the view
	if (moveFlag)
	{
		// Get mouse coordinates
		int XMouse=event->x;
		int YMouse=event->y;

		// Update image focus
		imgFocusX -= (XMouse-lastXMouse)/scale;
		imgFocusY -= (YMouse-lastYMouse)/scale;

		// Memorize new position of the pointer
		lastXMouse=XMouse;
		lastYMouse=YMouse;

		// Update view
		queue_draw();
		return true;
	}
	// Event has been handled
	return false;
}


// Reset view (scale is set to 1:1 and image is centered)
void ScrollImage::reset()
{
	// Set scale to 1:1
	scale=1;
	// Update image focus
	imgFocusX = image->get_width()/2.;
	imgFocusY = image->get_height()/2.;
	// Update display
	queue_draw();
}


// Reset scale to 1:1
void ScrollImage::resetScale()
{
	scale=1;
	// Update display
	queue_draw();
}


// Center the dispay at the pointer coordinates
void ScrollImage::setCenter()
{
	// Update image focus
	imgFocusX += (lastXMouse - get_allocated_width()/2.)/scale;
	imgFocusY += (lastYMouse - get_allocated_height()/2.)/scale;
	// Update display
	queue_draw();
}

// Best fit of the image in the display
void ScrollImage::fit()
{
	// Set reset flag to true, next call of on_draw will reset display
	resetFlag=true;
	queue_draw();
}


// Hide or show the target center
void ScrollImage::showHideTarget()
{
	// Invert flag
	targetFlag=!targetFlag;
	// Update popup menu according to current status
	if (targetFlag)
		MenuItemTarget.set_label("Hide center target");
	else
		MenuItemTarget.set_label("Show center target");
	// Update display
	queue_draw();
}


// Reset view to fit in the drawing area
void ScrollImage::fitImage(int winWidth,int winHeight, int imgWidth, int imgHeight)
{
	// Compute ratio of the window and the image
	double winRatio=(double)winWidth/winHeight;
	double imgRatio=(double)imgWidth/imgHeight;

	// Check what is the best fit for the image according to the ratio
	if (imgRatio& cr)
{

	// Get the window size
	int winWidth=get_allocated_width();
	int winHeight=get_allocated_height();

	// Get the image size
	int imgWidth=image->get_width();
	int imgHeight=image->get_height();

	// If requested, reset view
	if (resetFlag) fitImage(winWidth,winHeight,imgWidth,imgHeight);

	// Create a new image for display filled with grey
	Glib::RefPtr display = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,false,8,winWidth,winHeight);
	display->fill(0x5F5F5F00);

	// Compute offset of the source image
	double OffsetX=winWidth/2-imgFocusX*scale;
	double OffsetY=winHeight/2-imgFocusY*scale;
	// Compute top left coordinate of the image in the area
	double Min_X=std::max(0.,OffsetX);
	double Min_Y=std::max(0.,OffsetY);
	// Compute bottom right coordinates of the image in the area
	double Max_X=std::min((double)winWidth,winWidth/2+(imgWidth-imgFocusX)*scale);
	double Max_Y=std::min((double)winHeight,winHeight/2+(imgHeight-imgFocusY)*scale);
	// Compute width and height
	double Width=Max_X-Min_X;
	double Height=Max_Y-Min_Y;

	// Scale image
	image->scale(display,
				 Min_X,Min_Y,
				 Width,Height,
				 OffsetX,OffsetY,
				 scale,scale,Gdk::INTERP_TILES);

	// Display the image in the drawing area
	Gdk::Cairo::set_source_pixbuf(cr,display,0,0);
	cr->rectangle(0,0,winWidth,winHeight);
	cr->fill();

	// Display the center target if requested
	if (targetFlag) displayTarget(cr,winWidth/2.,winHeight/2.);

	// Event has been handled
	return false;
}


// Display a target at coordinates x,y
void ScrollImage::displayTarget(const Cairo::RefPtr& cr,double x, double y)
{
	// Set color to black
	cr->set_source_rgba(0,0,0,0.5);

	// Display black quaters
	cr->arc(x,y,15,0,M_PI/2.);
	cr->line_to(x,y);
	cr->fill();
	cr->arc(x,y,15,M_PI,3.*M_PI/2.);
	cr->line_to(x,y);
	cr->fill();

	// Set color to white
	cr->set_source_rgba(1,1,1,0.5);

	// Display white quaters
	cr->arc(x,y,15,M_PI/2.,M_PI);
	cr->line_to(x,y);
	cr->fill();
	cr->arc(x,y,15,3.*M_PI/2.,0);
	cr->line_to(x,y);
	cr->fill();

	// Set color to black
	cr->set_source_rgba(0,0,0,0.8);

	// Display the cross
	cr->move_to(x-20,y);
	cr->line_to(x+20,y);
	cr->stroke();
	cr->move_to(x,y-20);
	cr->line_to(x,y+20);
	cr->stroke();

	// Display the circle
	cr->arc(x,y,15,0,2*M_PI);
	cr->stroke();
}

gtkmm – example 22

This is part of a more general work dedicated to gtkmm accessible here. This example explains and shows how to resize an image with gtkmm. Let’s have a look at the Gdk::Pixbuf::scale function:

void Gdk::Pixbuf::scale	(
const Glib::RefPtr< Gdk::Pixbuf >& dest,
int 		dest_x,
int 		dest_y,
int 		dest_width,
int 		dest_height,
double 		offset_x,
double 		offset_y,
double 		scale_x,
double 		scale_y,
InterpType 	interp_type 
) const

scale



  • dest is the destination image buffer (Gdk::Pixbuf). The function scales and copies the image in a new one (dest). Memory is not automatically allocated for the destination buffer. It means that the image dest must be created previously to the call of Gdk::Pixbuf::scale. Width and height of dest must be in accordance with the other arguments of the function.
  • dest_x and dest_y are the coordinates of the top left point in the destination image. All the pixels on the left side of dest_x and on the upper side of dest_y will remain unchanged.
  • dest_width and dest_height are the size (width and height) of the area to update in the destination buffer.
  • offset_x and offset_y are the offset of the source image in the destination image’s frame.
  • scale_x and scale_y are the scale factor applied to the source image before the copy. A scale factor of 1 will keep the original image size. A scale factor of 2 will create an image twice the original and so one.
  • interp_type is the interpolation type used for the transformation. Four types can be used :

    • Gdk::INTERP_NEAREST (top left): nearest neighbor sampling; this is the fastest and lowest quality mode. Quality is normally unacceptable when scaling down, but may be OK when scaling up.
    • Gdk::INTERP_TILES (bottom right): this is an accurate simulation of the PostScript image operator without any interpolation enabled. Each pixel is rendered as a tiny parallelogram of solid color, the edges of which are implemented with antialiasing. It resembles nearest neighbor for enlargement, and bilinear for reduction.
    • Gdk::INTERP_BILINEAR (bottom left): Best quality/speed balance; use this mode by default. Bilinear interpolation. For enlargement, it is equivalent to point-sampling the ideal bilinear-interpolated image. For reduction, it is equivalent to laying down small tiles and integrating over the coverage area.
    • Gdk::INTERP_HYPER (top right): This is the slowest and highest quality reconstruction function. It is derived from the hyperbolic filters in Wolberg’s “Digital Image Warping”, and is formally defined as the hyperbolic-filter sampling the ideal hyperbolic-filter interpolated image (the filter is designed to be idempotent for 1:1 pixel mapping).

output2

Download

Source code


main.cpp

#include 
#include 


// Scale used for the demonstration
#define         SCALE           8.



int main(int argc, char* argv[])
{
    // Initialize gtkmm library
    Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");


    // Load the source image
    Glib::RefPtr image = Gdk::Pixbuf::create_from_file("gtk_icon.png");
    int width=image->get_width();
    int height=image->get_height();
    //image2=image; // = image->scale_simple(image->get_width()*scale,image->get_height()*scale,Gdk::INTERP_NEAREST);


    // __________________________
    // ::: Create output1.png :::

    // Create, fill and save the destination image
    Glib::RefPtr image2 = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,true,8,width*SCALE,height*SCALE);
    image2->fill(0x0000FFA0);
    image2->save("output1.png","png");
    std::cout << "output1.png created" << std::endl;


    // __________________________
    // ::: Create output2.png :::

    // Scale and copy the first image in the destination image with several type of scalin method
    // Top left
    image->scale(image2,
                 10,10,
                 (width*SCALE)/2.-10,(height*SCALE)/2-10,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_NEAREST);
    // Top right
    image->scale(image2,
                 (width*SCALE)/2.+10,10,
                 (width*SCALE)/2.-20,(height*SCALE)/2.-10,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_HYPER);
    // Bottom left
    image->scale(image2,
                 10,(height*SCALE)/2.+10,
                 (width*SCALE)/2.-10,(height*SCALE)/2.-20,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_BILINEAR);
    // Bottom right
    image->scale(image2,
                 (width*SCALE)/2.+10,(height*SCALE)/2.+10,
                 (width*SCALE)/2.-20,(height*SCALE)/2.-20,
                 0,0,
                 SCALE,SCALE,
                 Gdk::INTERP_TILES);
    // Save the output image
    image2->save("output2.png","png");
    std::cout << "output2.png created" << std::endl;


    // __________________________
    // ::: Create output3.png :::

    // Scale and translate the source image
    image2->fill(0x70707070);
    image->scale(image2,
                 20,20,
                 width*SCALE-40,height*SCALE-40,
                 -width*SCALE/2.,-height*SCALE/2.,
                 SCALE*2,SCALE*2,
                 Gdk::INTERP_BILINEAR);
    image2->save("output3.png","png");
    std::cout << "output3.png created" << std::endl;

    // __________________________
    // ::: Create output4.png :::

    // Scale and translate the source image
    image2->fill(0x70707070);
    image->scale(image2,
				 image2->get_width()/2.,image2->get_height()/2.,
				 image2->get_width()/2.,image2->get_height()/2.,
				 -width*SCALE,-height*SCALE,
                 SCALE*2,SCALE*2,
                 Gdk::INTERP_TILES);
    image2->save("output4.png","png");
    std::cout << "output4.png created" << std::endl;
    return 0;
}

outputs


output1
output2
output3
output4

gtkmm – example 21

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to create a popup menu (right click contextual menu) inside a drawing Widget (with Cairo). This code can easily be extended to other widgets.

capture

Download


Source code

main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;
	
	// Create the drawing
	DrawingArea Dwg;
	// Insert the drawing in the window
	window.add(Dwg);
	// Resize the window
	window.resize(250,250);
	// Set the window title
	window.set_title("Popup menu");
	// Show the drawing
	Dwg.show();
	
	// Start main loop
	return app->run(window);
}

drawingarea.h

#ifndef DRAWINGAREA_H
#define DRAWINGAREA_H

#include 
#include 


class DrawingArea : public Gtk::DrawingArea
{
public:
	DrawingArea();

protected:
	// Override default signal handler:
	virtual bool                on_draw(const Cairo::RefPtr& cr);

	// Override mouse events
	bool                        on_button_press_event(GdkEventButton *event);

	// Signal handlers (run when a popup item is clicked)
	void                        on_action1_event();
	void                        on_action2_event();

private:

	// Image displayed
	Glib::RefPtr   image;

	// Scale of the image
	double                      scale;

	// Popup menu and submenus
	Gtk::Menu                   m_Menu_Popup;
	Gtk::MenuItem               MenuItem1;
	Gtk::MenuItem               MenuItem2;

};
#endif // DRAWINGAREA_H

drawingarea.cpp

#include "drawingarea.h"



DrawingArea::DrawingArea()
{
	// Load the image
	image = Gdk::Pixbuf::create_from_file("gtk.png");

	// Set masks for mouse events
	add_events(Gdk::BUTTON_PRESS_MASK);

	// ::: Create popup menu :::

	// Add and connect action 1
	MenuItem1.set_label("Action 1");
	MenuItem1.signal_activate().connect(sigc::mem_fun(*this,&DrawingArea::on_action1_event));
	m_Menu_Popup.append(MenuItem1);

	// Add and connect action 2
	MenuItem2.set_label("Action 2");
	MenuItem2.signal_activate().connect(sigc::mem_fun(*this,&DrawingArea::on_action2_event));
	m_Menu_Popup.append(MenuItem2);

	// Show the menu
	m_Menu_Popup.show_all();

	// Connect the menu to this Widget
	m_Menu_Popup.accelerate(*this);
}


// Signal handlers for acion 1
void DrawingArea::on_action1_event()
{
	std::cout << "Action 1 selected" << std::endl;
}


// Signal handlers for acion 2
void DrawingArea::on_action2_event()
{
	std::cout << "Action 2 selected" << std::endl;
}


// Mouse button press event
bool DrawingArea::on_button_press_event(GdkEventButton *event)
{
	// Check if the event is a right button click.
	if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
	{
		// Display the popup menu
		m_Menu_Popup.popup(event->button, event->time);
		// The event has been handled.
		return true;
	}

	// Propagate the event further.
	return false;
}


// Call when the display need to be updated
bool DrawingArea::on_draw(const Cairo::RefPtr& cr)
{
	// Place the image at the center of the window
	Gdk::Cairo::set_source_pixbuf(cr, image, 0,0);
	// Update the whole drawing area
	cr->rectangle(0, 0, image->get_width(), image->get_height());
	// Fill the area with the image
	cr->fill();
	// The event has been handled.
	return true;
}

gtkmm – example 20

This is part of a more general work dedicated to gtkmm accessible here. This code shows how to process mouse wheel in a Cairo widget (for example for zooming).

capture

Download


Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;

	// Create the drawing
	Drawing Dwg;


	// Insert the drawing in the window
	window.add(Dwg);
	// Resize the window
	window.resize(400,400);
	// Set the window title
	window.set_title("Mouse scroll");
	// Show the drawing
	Dwg.show();

	// Start main loop
	return app->run(window);
}

drawing.h

#ifndef DRAWING_H
#define DRAWING_H

#include 
#include 

class Drawing : public Gtk::DrawingArea
{
public:
    Drawing();

protected:
    // Override default signal handler:
    virtual bool on_draw(const Cairo::RefPtr& cr);

    // Override mouse scroll event
    bool on_scroll_event(GdkEventScroll *ev);



private:
    // Image displayed
    Glib::RefPtr   image;
    // Scale of the image
    double                      scale;


};

#endif // DRAWING_H

drawing.cpp

#include "drawing.h"

Drawing::Drawing()
{
    // Load the image
    image = Gdk::Pixbuf::create_from_file("gtk.png");
    add_events(Gdk::BUTTON_PRESS_MASK | Gdk::SCROLL_MASK  |Gdk::SMOOTH_SCROLL_MASK);
    scale=1;
}


bool Drawing::on_scroll_event(GdkEventScroll *ev)
{
    // Update scale according to mouse scroll
    scale-=ev->delta_y/10.;
	if (scale<0.1) scale=0.1;
    std::cout << scale << std::endl;
    std::cout.flush();
    // Update drawing
    queue_draw();
    // There is probably a good reason to do this
    return true;
}




bool Drawing::on_draw(const Cairo::RefPtr& cr)
{
    // Get drawing area size
    Gtk::Allocation allocation = get_allocation();
    const int width = allocation.get_width();
    const int height = allocation.get_height();

    // Scale the image to the area
    cr->scale(scale,scale);

    // Place the image at the center of the window
    Gdk::Cairo::set_source_pixbuf(cr, image, (width/2)/scale-image->get_width()/2,(height/2)/scale-image->get_height()/2);

    // Update the whole drawing area
    cr->rectangle(0, 0, get_allocation().get_width()/scale, get_allocation().get_width()/scale);
    // Fill the area with the image
    cr->fill();

    return true;
}

gtkmm – example 19

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to create secondary window (or multiple windows or child window).

capture

Download


Source code


main.cpp

#include 

int main(int argc, char* argv[])
{
    // Initialize gtkmm and create the main window
    Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");

    // Create the main window with an image
    Gtk::Window window;
    Gtk::Image image1("gtk.png");
    window.add(image1);
    image1.show();
    window.move(200,200);
    window.set_title("Main window");

    // Create the secondary window with another image
    Gtk::Window window2;
    Gtk::Image image2("minirex.png");
    window2.add(image2);
    image2.show();
    window2.set_title("Secondary window");
    window2.show();
    window2.set_deletable(false);
    window2.move(400,200);

    // Start main loop
    return app->run(window);
}

gtkmm – example 18

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to mix images and drawing with Cairo.

capture

Download


Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;
	
	// Create the drawing
	Drawing Dwg;
	
	// Insert the drawing in the window
	window.add(Dwg);
	
	// Show the drawing
	Dwg.show();
	
	// Start main loop
	return app->run(window);
}

drawing.h

#ifndef DRAWING_H
#define DRAWING_H

#include 
#include 

class Drawing : public Gtk::DrawingArea
{
public:
	Drawing();
	
protected:
	//Override default signal handler:
	virtual bool on_draw(const Cairo::RefPtr& cr);
	
private:
	Glib::RefPtr image;
};

#endif // DRAWING_H

drawing.cpp

#include "drawing.h"

Drawing::Drawing()
{
	// Load the image
	image = Gdk::Pixbuf::create_from_file("gtk.png");
}


bool Drawing::on_draw(const Cairo::RefPtr& cr)
{
	// Get drawing area size
	Gtk::Allocation allocation = get_allocation();
	const int width = allocation.get_width();
	const int height = allocation.get_height();
	
	// Scale the image to the area
	cr->scale((double)width/image->get_width(),(double)height/image->get_height());
	
	cr->save();
	// Place the image at 0,0
	Gdk::Cairo::set_source_pixbuf(cr, image, 0,0);
	// Update the area where the image is located
	cr->rectangle(0, 0, image->get_width(), image->get_height());
	// Fill the area with the image
	cr->fill();
	cr->restore();
	
	
	cr->save();
	cr->set_source_rgba(0.,0.,1.,1.);   // blue
	cr->set_line_width(10);
	cr->arc(image->get_width()/2.,image->get_height()/2,width/3,0,2*M_PI);
	cr->stroke();
	cr->restore();
	
	return true;
}

gtkmm – example 17

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to resize the drawing area according to the window size.

capture

Download


Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;
	// Set window size
	window.resize(600,400);

	// Create the drawing
	Drawing Dwg;

	// Insert the drawing in the window
	window.add(Dwg);

	// Show the drawing
	Dwg.show();

	// Start main loop
	return app->run(window);
}

drawing.h

#ifndef DRAWING_H
#define DRAWING_H

#include 
#include 

class Drawing : public Gtk::DrawingArea
{
public:
	Drawing();

protected:
	//Override default signal handler:
	virtual bool on_draw(const Cairo::RefPtr& cr);

private:
	Glib::RefPtr image;
};

#endif // DRAWING_H

drawing.cpp

#include "drawing.h"

Drawing::Drawing()
{
	// Load the image
	image = Gdk::Pixbuf::create_from_file("gtk.png");
}


bool Drawing::on_draw(const Cairo::RefPtr& cr)
{
	// Get drawing area size
	Gtk::Allocation allocation = get_allocation();
	const int width = allocation.get_width();
	const int height = allocation.get_height();

	// Scale the image to the area
	cr->scale((double)width/image->get_width(),(double)height/image->get_height());
	// Place the image at 0,0
	Gdk::Cairo::set_source_pixbuf(cr, image, 0,0);
	// Update the area where the image is located
	cr->rectangle(0, 0, image->get_width(), image->get_height());
	// Fill the area with the image
	cr->fill();

	return true;
}

gtkmm – example 16

This is part of a more general work dedicated to gtkmm accessible here. This example shows ho to display an image in a drawing area created with Cairo.

capture

Download


Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;

	// Create the drawing
	Drawing Dwg;

	// Insert the drawing in the window
	window.add(Dwg);

	// Show the drawing
	Dwg.show();

	// Start main loop
	return app->run(window);
}

drawing.h

#ifndef DRAWING_H
#define DRAWING_H

#include 
#include 

class Drawing : public Gtk::DrawingArea
{
public:
	Drawing();

protected:
	//Override default signal handler:
	virtual bool on_draw(const Cairo::RefPtr& cr);

private:
	Glib::RefPtr image;
};

#endif // DRAWING_H

drawing.cpp

#include "drawing.h"

Drawing::Drawing()
{
	// Load the image
	image = Gdk::Pixbuf::create_from_file("gtk.png");
}


bool Drawing::on_draw(const Cairo::RefPtr& cr)
{

	// Place the image at 0,0
	Gdk::Cairo::set_source_pixbuf(cr, image, 0,0);
	// Update the area where the image is located
	cr->rectangle(0, 0, image->get_width(), image->get_height());
	// Fill the area with the image
	cr->fill();

	return true;
}

gtkmm – example 15

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to use transparency in Cairo.

capture

Download


Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm and create the main window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
	Gtk::Window window;
	
	// Create the drawing
	Drawing Dwg;
	
	// Insert the drawing in the window
	window.add(Dwg);
	
	// Show the drawing
	Dwg.show();
	
	// Start main loop
	return app->run(window);
}

drawing.h

#ifndef DRAWING_H
#define DRAWING_H

#include 
#include 

class Drawing : public Gtk::DrawingArea
{
public:
	Drawing();
	
protected:
	//Override default signal handler:
	virtual bool on_draw(const Cairo::RefPtr& cr);
	
};

#endif // DRAWING_H

drawing.cpp

#include "drawing.h"

Drawing::Drawing()
{
}


bool Drawing::on_draw(const Cairo::RefPtr& cr)
{
	// Draw the first circle
	cr->arc(75,75,50,0,2*M_PI);
	cr->set_source_rgba(0, 0, 1.0,0.5);
	cr->fill();
	cr->stroke();

	cr->set_source_rgba(0, 1, 0,0.5);
	cr->arc(100,125,50,0,2*M_PI);
	cr->fill();
	cr->stroke();

	cr->set_source_rgba(1, 0, 0,0.5);
	cr->arc(125,75,50,0,2*M_PI);
	cr->fill();
	cr->stroke();


	return true;
}

gtkmm – example 14

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to create a drawing area with Cairo.

capture

Download

Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
    // Initialize gtkmm and create the main window
    Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
    Gtk::Window window;
    
    // Create the drawing
    Drawing Dwg;

    // Insert the drawing in the window
    window.add(Dwg);

    // Show the drawing
    Dwg.show();

    // Start main loop
    return app->run(window);
}

drawing.h

#ifndef DRAWING_H
#define DRAWING_H

#include 
#include 

class Drawing : public Gtk::DrawingArea
{
public:
	Drawing();
	
protected:
	//Override default signal handler:
	virtual bool on_draw(const Cairo::RefPtr& cr);
	
};

#endif // DRAWING_H

drawing.cpp

#include "drawing.h"

Drawing::Drawing()
{
}


bool Drawing::on_draw(const Cairo::RefPtr& cr)
{
    // Set color
    cr->set_source_rgb(0, 0.0, 1.0);
    // Set line width
    cr->set_line_width(15.0);
    // Set line cap
    cr->set_line_cap(Cairo::LINE_CAP_ROUND);

    // Draw the lines
    cr->move_to(50, 50);
    cr->line_to(150, 150);
    cr->move_to(150,50);
    cr->line_to(50, 150);

    // Apply drawing
    cr->stroke();

    return true;
}

gtkmm – example 13

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to create a menu bar.

capture

Download

Source code


main.cpp

#include 



int main(int argc, char* argv[])
{
    // Initialize gtkmm and create the window
	Glib::RefPtr app = Gtk::Application::create(argc, argv, "www.lucidarme.me");
    Gtk::Window window;

    // Create the vertical layout
    Gtk::VBox mainLayout;
    window.add(mainLayout);


    // Create and add the menuBar to the layout
    Gtk::MenuBar menuBar;
    mainLayout.pack_start(menuBar, Gtk::PACK_SHRINK);


    // _________________________________
    // ::: Create the sub menu Files :::


    // Create the menu item files
    Gtk::MenuItem menuFiles;
    menuFiles.set_label("Files");
    menuBar.append(menuFiles);

    // Create a sub menu in files
    Gtk::Menu subMenuFiles;
    menuFiles.set_submenu(subMenuFiles);

    // Create a menu item from Stock (New)
    Gtk::ImageMenuItem menuNew(Gtk::Stock::NEW);
    subMenuFiles.append(menuNew);

    // Create a menu item with a sub menu (Recent files)
    Gtk::MenuItem menuRecentFiles("Recent files", true);
    subMenuFiles.append(menuRecentFiles);
    Gtk::Menu subMenuRecentFiles;
    menuRecentFiles.set_submenu(subMenuRecentFiles);
    Gtk::MenuItem recentFile1("File1.txt");
    subMenuRecentFiles.append(recentFile1);
    Gtk::MenuItem recentFile2("File2.txt");
    subMenuRecentFiles.append(recentFile2);
    Gtk::MenuItem recentFile3("File3.txt");
    subMenuRecentFiles.append(recentFile3);

    // Create a menu item from Stock (Open)
    Gtk::ImageMenuItem menuOpen(Gtk::Stock::OPEN);
    subMenuFiles.append(menuOpen);

    // Create a menu item from Stock (Save)
    Gtk::ImageMenuItem menuSave(Gtk::Stock::SAVE);
    subMenuFiles.append(menuSave);

    // Add a separator
    Gtk::SeparatorMenuItem hline;
    subMenuFiles.append(hline);

    // Create a menu item from Stock (Close)
    Gtk::ImageMenuItem menuClose(Gtk::Stock::CLOSE);
    subMenuFiles.append(menuClose);

    //  Create and connect a menu item from Stock (Quit)
    Gtk::ImageMenuItem menuQuit(Gtk::Stock::QUIT);
    menuQuit.signal_activate().connect(sigc::ptr_fun(&Gtk::Main::quit));
    subMenuFiles.append(menuQuit);



    // _________________________________
    // ::: Create the sub menu Edit :::


    // Create the menu item Edit
    Gtk::MenuItem menuEdit("Edit", true);
    menuBar.append(menuEdit);

    // Create a sub menu in Edit
    Gtk::Menu subMenuEdit;
    menuEdit.set_submenu(subMenuEdit);

    // Create a menu item from Stock (Cut)
    Gtk::ImageMenuItem menuCut(Gtk::Stock::CUT);
    subMenuEdit.append(menuCut);

    // Create a menu item from Stock (Copy)
    Gtk::ImageMenuItem menuCopy(Gtk::Stock::COPY);
    subMenuEdit.append(menuCopy);

    // Create a menu item from Stock (Paste)
    Gtk::ImageMenuItem menuPaste(Gtk::Stock::PASTE);
    subMenuEdit.append(menuPaste);

    // Create a menu item
    Gtk::MenuItem menuExample("Example");
    subMenuEdit.append(menuExample);



    // Create and add an image in the window
    Gtk::Image image("gtk.png");
    mainLayout.pack_end(image);

    // Show window itens
    window.show_all();


    // Start main loop
	return app->run(window);
    return 0;
}

gtkmm – example 12

This is part of a more general work dedicated to gtkmm accessible here. This example shows different kind of dialog boxes.

capture

capture2

Download

Source code


main.cpp

#include 
#include 


int main(int argc, char* argv[])
{
	// Initialize gtkmm
	Gtk::Main app(argc, argv);
	// Create the window
	mainwindow w;
	// Start main loop
	Gtk::Main::run(w);
	return 0;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 




// The class mainwindow inherits from Gtk::Window
class mainwindow : public Gtk::Window
{
	// Constructor and destructor
public:    
	mainwindow();
	virtual                 ~mainwindow();
	
protected:
	void                    messageInfo();
	void                    messageWarning();
	void                    messageQuestion();
	void                    messageError();
	void                    messageOther();
	
	//Override default signal handler:
	//    virtual bool on_draw(const Cairo::RefPtr& cr);
	
	//Member widgets:
	Gtk::Button             buttonInfo;
	Gtk::Button             buttonWarning;
	Gtk::Button             buttonQuestion;
	Gtk::Button             buttonError;
	Gtk::Button             buttonOther;
	Gtk::Button             buttonQuit;
	Gtk::VBox               mainLayout;
	
};


#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include 


// Constructor of the main Window (build ui interface).
mainwindow::mainwindow()
{
	this->resize(400,200);
	
	// Add the info message button
	buttonInfo.add_label("Information");
	buttonInfo.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::messageInfo));
	mainLayout.pack_start(buttonInfo);
	
	// Add the warning message button
	buttonWarning.add_label("Warning");
	buttonWarning.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::messageWarning));
	mainLayout.pack_start(buttonWarning);
	
	// Add the question message button
	buttonQuestion.add_label("Question");
	buttonQuestion.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::messageQuestion));
	mainLayout.pack_start(buttonQuestion);
	
	// Add the error message button
	buttonError.add_label("Error");
	buttonError.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::messageError));
	mainLayout.pack_start(buttonError);
	
	// Add the other message button
	buttonOther.add_label("Other");
	buttonOther.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::messageOther));
	mainLayout.pack_start(buttonOther);
	
	// Add the Quit button
	buttonQuit.add_label("Quit");
	buttonQuit.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::close));
	mainLayout.pack_start(buttonQuit);
	
	// Display the main grid in the main window
	mainLayout.show_all();
	
	// Insert the grid in the main window
	add(mainLayout);
	
}


// Destructor of the class
mainwindow::~mainwindow()
{}


// Display message info
void mainwindow::messageInfo()
{
	Gtk::MessageDialog dialog(*this, "This is an information MessageDialog",false,Gtk::MESSAGE_INFO);
	dialog.set_secondary_text("And this is the secondary text that explains things.");
	dialog.run();
}

// Display warning message
void mainwindow::messageWarning()
{
	Gtk::MessageDialog dialog(*this, "This is a warning MessageDialog",false,Gtk::MESSAGE_WARNING);
	dialog.run();
}

// Display a question message
void mainwindow::messageQuestion()
{
	Gtk::MessageDialog dialog(*this, "This is a question MessageDialog",false,Gtk::MESSAGE_QUESTION,Gtk::BUTTONS_OK_CANCEL);
	int Answer=dialog.run();
	
	// Process user choice
	switch(Answer)
	{
	case(Gtk::RESPONSE_OK):
		std::cout << "OK clicked." << std::endl;
		break;
	case(Gtk::RESPONSE_CANCEL):
		std::cout << "Cancel clicked." << std::endl;
		break;
	default:
		std::cout << "Unexpected button clicked." << std::endl;
		break;
	}
}

// Display error message
void mainwindow::messageError()
{
	Gtk::MessageDialog dialog(*this, "This is an error MessageDialog",false,Gtk::MESSAGE_ERROR);
	dialog.run();
}

// Display other message
void mainwindow::messageOther()
{
	Gtk::MessageDialog dialog(*this, "This is an other MessageDialog",true,Gtk::MESSAGE_OTHER);
	dialog.set_secondary_text("Note that the text support HTML markups.",true);
	dialog.run();
}

gtkmm – tutorial examples

You’ll find on this page several links and examples to work with gtkmm.

gtkmm and Qt Creator: how to configure Qt Creator to work with gtkmm.
gtkmm – example 1: simple ‘Hello world’ application.
gtkmm – example 2: simple container (Gtk::Grid) application.
gtkmm – example 3: more complex container.
gtkmm – example 4: simple application with a Gtk::Scale widget.
gtkmm – example 5: simple application with a Gtk::SpinButton widget.
gtkmm – example 6: shows how to place or move the window.
gtkmm – example 7: load and display an image.
gtkmm – example 8: load and display several images.
gtkmm – example 9: change the application icon.
gtkmm – example 10: file chooser dialog box application.
gtkmm – example 11: simple timer application.
gtkmm – example 12: dialog boxes.
gtkmm – example 13: menu bar.
gtkmm – example 14: drawing area with Cairo.
gtkmm – example 15: transparency with Cairo.
gtkmm – example 16: display an image with Cairo.
gtkmm – example 17: resize drawing area with Cairo.
gtkmm – example 18: image and drawing with Cairo.
gtkmm – example 19: multiple window with gtkmm.
gtkmm – example 20: zoom with the mouse wheel.
gtkmm – example 21: popup menu (right click menu).
gtkmm – example 22: scale an image (Pixbuf).
gtkmm – example 23: interactif display of an image with Cairo.
gtkmm – example 24: application with tabs.

gtkmm – example 11

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to emit a signal with a timer:

capture

Download


Source code


main.cpp

#include 
#include 

int main(int argc, char* argv[])
{
	// Initialize gtkmm
	Gtk::Main app(argc, argv);
	// Create the window
	mainwindow w;
	// Start main loop
	Gtk::Main::run(w);
	return 0;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 


// The class mainwindow inherits from Gtk::Window
class mainwindow : public Gtk::Window
{
	// Constructor and destructor
public:    
	mainwindow();
	virtual                 ~mainwindow();
	
protected:
	// Called every timeout
	bool                    on_my_timeout();
	
	//Member widgets:
	Gtk::Label              label;
	Gtk::Button             buttonQuit;
	Gtk::Grid               mainGrid;
	
private:
	int                     seconds;
	
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include 


// Constructor of the main Window (build ui interface).
mainwindow::mainwindow()
{
	// Initialize seconds
	seconds=0;
	
	// Add the label displaying the ellapsed tim
	label.set_text("Elapsed time: 0 s");
	mainGrid.attach(label,0,0,1,1);
	
	// Add the Quit button
	buttonQuit.add_label("Quit");
	buttonQuit.set_size_request(200,50);
	buttonQuit.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::close));
	mainGrid.attach(buttonQuit,0,1,1,1);
	
	// Display the main grid in the main window
	mainGrid.show_all();
	
	// Launch timer every second
	Glib::signal_timeout().connect( sigc::mem_fun(*this, &mainwindow::on_my_timeout), 1000 );
	
	// Insert the grid in the main window
	add(mainGrid);
}


// Destructor of the class
mainwindow::~mainwindow()
{}


bool mainwindow::on_my_timeout()
{
	// Prepare message
	char Text[50];
	sprintf (Text,"Elapsed time: %d s",++seconds);
	// Display message in the label
	label.set_text(Text);
	return true;
}

gtkmm – example 10

This is part of a more general work dedicated to gtkmm accessible here. This example shows how to create a file chooser dialog box:

capture

Download


Source code


main.cpp

#include 
#include 

int main(int argc, char* argv[])
{
	// Initialize gtkmm
	Gtk::Main app(argc, argv);
	// Create the window
	mainwindow w;
	// Start main loop
	Gtk::Main::run(w);
	return 0;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 


// The class mainwindow inherits from Gtk::Window
class mainwindow : public Gtk::Window
{
	// Constructor and destructor
public:    
	mainwindow();
	virtual					~mainwindow();

protected:
	void                    on_button_load();

	//Member widgets:
	Gtk::Button             buttonLoad;
	Gtk::Button             buttonQuit;
	Gtk::Grid               mainGrid;

};


#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include 


// Constructor of the main Window (build ui interface).
mainwindow::mainwindow()
{
    // Initialize the main window and hide the title bar
    this->set_border_width(10);

    // Add the load button
    buttonLoad.add_label("Load file");
    buttonLoad.set_size_request(200,50);
    buttonLoad.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::on_button_load));
    mainGrid.attach(buttonLoad,0,0,1,1);

    // Add the Quit button
    buttonQuit.add_label("Quit");
    buttonQuit.set_size_request(200,50);
    buttonQuit.signal_pressed().connect(sigc::mem_fun(*this,&mainwindow::close));
    mainGrid.attach(buttonQuit,0,1,1,1);

    // Display the main grid in the main window
    mainGrid.show_all();

    // Insert the grid in the main window
    add(mainGrid);
}


// Destructor of the class
mainwindow::~mainwindow()
{}


void mainwindow::on_button_load()
{
    // Create the dialog box FileChooser
    Gtk::FileChooserDialog dialog("Please choose a file",Gtk::FILE_CHOOSER_ACTION_OPEN);
    dialog.set_transient_for(*this);

    //Add response buttons the the dialog:
    dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
    dialog.add_button("_Open", Gtk::RESPONSE_OK);

    //Add filters, so that only certain file types can be selected:
    Glib::RefPtr filter_text = Gtk::FileFilter::create();
    filter_text->set_name("Text files");
    filter_text->add_mime_type("text/plain");
    dialog.add_filter(filter_text);

    Glib::RefPtr filter_cpp = Gtk::FileFilter::create();
    filter_cpp->set_name("C/C++ files");
    filter_cpp->add_mime_type("text/x-c");
    filter_cpp->add_mime_type("text/x-c++");
    filter_cpp->add_mime_type("text/x-c-header");
    dialog.add_filter(filter_cpp);

    Glib::RefPtr filter_any = Gtk::FileFilter::create();
    filter_any->set_name("Any files");
    filter_any->add_pattern("*");
    dialog.add_filter(filter_any);

    //Show the dialog and wait for a user response:
    int result = dialog.run();

    //Handle the response:
    switch(result)
    {
    case(Gtk::RESPONSE_OK):
    {
        // The user selected a file
        std::cout << "Open clicked." << std::endl;
        std::string filename = dialog.get_filename();
        std::cout << "File selected: " <<  filename << std::endl;
        break;
    }
    case(Gtk::RESPONSE_CANCEL):
    {
        // The user clicked cancel
        std::cout << "Cancel clicked." << std::endl;
        break;
    }
    default:
    {
        // The user closed the dialog box
        std::cout << "Unexpected button clicked." << std::endl;
        break;
    }
    }
}