3

I wish to draw a line using mouseevents on Gtk::DrawableArea. What I want is something like:

  1. Click on Line Button to activate line event
  2. Select first point(already drawn) in the drawingarea
  3. Now Select second point(again already drawn) in the drawingarea
  4. line should be drawn between two points

What I already have:

  1. Gtk::DrawingArea
  2. 2 points(manual circles) drawn using cairo, needed to create the line

The follwing is my constructor that calls the on_draw function.

 drawingArea:: drawingArea()
 {
    signal_draw().connect(sigc::mem_fun(*this, &drawingArea::on_draw), false);
 }

And the on_draw function draws the background:

bool drawingArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
    cr->set_source_rgb(1.0, 1.0, 1.0);   // white background
    cr->paint();

    cr->save();
    cr->arc(10.0, 10.0, 1.0, 0.0, 2 * M_PI); // full circle        
    cr->set_source_rgba(0.0, 0.0, 0.8, 0.6); // partially translucent
    cr->fill_preserve();
    cr->restore();  
    cr->stroke();

    return true;
}

P.S: I can easily add two points in this on_draw function. I'm a newbie in Gtkmm so kindly help shed some light on it.

4

1 回答 1

4

您应该使用 add_events(Gdk::BUTTON_PRESS_MASK) 方法设置鼠标按钮按下事件的掩码。然后你有 on_button_press_event(GdkEventButton *event) 函数,当鼠标按钮按下事件发生时调用。下面是这个程序的一个例子:

绘图区.h

#ifndef DRAWINGAREA_H
#define DRAWINGAREA_H

#include <gtkmm.h>


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

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

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

    private:

        //display Pixbuf
        Glib::RefPtr < Gdk::Pixbuf > display;

        //two coordinates
        int x1;
        int y1;
        int x2;
        int y2;
        //two bools for the clicks
        bool firstclick;
        bool secondclick;

};
#endif // DRAWINGAREA_H

绘图区.cpp

#include "DrawingArea.h"

DrawingArea::DrawingArea()
{
    // Set masks for mouse events
    add_events(Gdk::BUTTON_PRESS_MASK);
    //startvalues
    firstclick=false;
    secondclick=false;
}

// Mouse button press event
bool DrawingArea::on_button_press_event(GdkEventButton *event)
{
    // Check if the event is a left(1) button click.
    if( (event->type == GDK_BUTTON_PRESS) && (event->button == 1) )
    {
        //check whether this is the first click
        if(!firstclick&&!secondclick)
        {
            //the first coordinate
            x1=event->x;
            y1=event->y;
            firstclick=true;
        }
        //check whether this is the second click, and not on the same point as the previous
        if(firstclick&&!secondclick&&(int)event->x!=x1&&(int)event->y!=y1)
        {
            //the second coordinate
            x2=event->x;
            y2=event->y;
            secondclick=true;
            //refresh the screen
            queue_draw();
        }
        // The event has been handled.
        return true;
    }
}
// Call when the display need to be updated
bool DrawingArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
    //check whether it was clicked two times
    if(firstclick&&secondclick)
    {
        //set the width of the line
        cr->set_line_width(2);
        //set the color: black
        cr->set_source_rgb(0,0,0);
        //move the "brush" to the first point
        cr->move_to(x1,y1);
        //draw the line to the second point
        cr->line_to(x2,y2);
        //draw the line
        cr->stroke();
    }
    return true;
}

主文件

#include <DrawingArea.h>
#include <gtkmm.h>


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

    // Create the drawing
    DrawingArea Dwg;
    // Insert the drawing in the window
    window.add(Dwg);
    // Size of the window
    window.resize(720,640);
    // Set the window title
    window.set_title("Line");
    // Show the drawing
    Dwg.show();

    // Start main loop
    return app->run(window);
}
于 2015-03-02T21:08:02.787 回答