Gtkmm绘制线与鼠标事件

时间:2014-07-09 19:09:01

标签: mouseevent line cairo gtkmm drawingarea

我希望在Gtk::DrawableArea上使用mouseevents绘制一条线。 我想要的是:

  1. 点击“线路按钮”以激活线路事件
  2. 在drawingarea中选择第一个点(已绘制)
  3. 现在在drawingarea
  4. 中选择第二个点(已经绘制过) 应在两点之间绘制
  5. 我已经拥有的东西:

    1. Gtk::DrawingArea
    2. 使用cairo绘制的2点(手动圆圈),需要创建线
    3. 以下是调用on_draw函数的构造函数。

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

      on_draw函数绘制背景:

      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:我可以在这个on_draw函数中轻松添加两个点。我是Gtkmm的新手,所以请帮助阐明它。

1 个答案:

答案 0 :(得分:3)

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

DrawingArea.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

DrawingArea.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;
}

的main.cpp

#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);
}