【问题标题】:Gtkmm draw line with mouse eventsGtkmm 用鼠标事件画线
【发布时间】:2014-07-09 19:09:01
【问题描述】:

我希望在Gtk::DrawableArea 上使用鼠标事件画一条线。 我想要的是这样的:

  1. 点击线路按钮激活线路事件
  2. 在绘图区域中选择第一个点(已绘制)
  3. 现在在绘图区域中选择第二个点(再次已绘制)
  4. 应该在两点之间画线

我已经拥有的:

  1. Gtk::DrawingArea
  2. 使用 cairo 绘制的 2 个点(手动圆圈),用于创建线条

下面是我调用 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 的新手,所以请帮忙解释一下。

【问题讨论】:

    标签: mouseevent line cairo gtkmm drawingarea


    【解决方案1】:

    您应该使用 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
    

    绘图区.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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多