2012-05-10 2 views
1

우분투 10.04에서 gtkmm2.4를 사용하고 있습니다. (따라서 내 예제에는 on_expose() 대신 on_draw() 루틴이 포함됩니다. on_expose_event()에서 get_window()를 참조하는 VBox에는 윈도우가 존재하지 않는 것으로 보입니다. 그것을 추가해야합니까?gtkmm 2.4 cairo 시계 예제가 주 윈도우 대신 HBox 내부를 그릴 때 수정되지 않습니다.

원본 코드 http://developer.gnome.org/gtkmm-tutorial/2.22/gtkmm-tutorial.html#sec-drawing-clock-example

내 코드입니다

test.h

#ifndef TEST_H 
#define TEST_H 

#include <gtkmm.h> 


class TEST : public virtual Gtk::Window 
{ 

private: 

public: 
    TEST(); 
    virtual ~TEST(); 

protected: 

    Gtk::VBox V;   // Make V Box 
    Gtk::HBox H1;  // Upper H Box 
    Gtk::HBox H2;  // Lower H Box 

class Clock : public virtual Gtk::DrawingArea 
{ 
    public: 
     Clock(); 
     virtual ~Clock(); 

    protected: 
     //Override default signal handler: 
     virtual bool on_expose_event(GdkEventExpose* event); 
     double m_radius; 
     double m_lineWidth; 
     bool onSecondElapsed(void); 


    Glib::RefPtr<Gdk::Window> m_refGdkWindow; 
}; 

}; 



#endif // TEST_H 

test.cc

#include <ctime> 
#include <math.h> 
#include <cairommconfig.h> 
#include <cairomm/context.h> 
#include <cairomm/surface.h> 
#include "test.h" 

TEST::TEST() 
: 
V(true,0), 
H1(true,0), 
H2(true,0) 
{ 

set_title("test clock"); 
    set_border_width(10); 
    set_size_request(500,500); //set Window Size 

    add(V); 
    V.pack_start(H1); 
    V.pack_start(H2); 

    Clock c; 

    H2.pack_start(c); 

    show_all(); 


} 

TEST::~TEST() 
{ 
} 

TEST::Clock::Clock() 
    : m_radius(0.42), m_lineWidth(0.05) 
{ 
    Glib::signal_timeout().connect(
       sigc::mem_fun(*this, &Clock::onSecondElapsed), 1000); 
} 

TEST::Clock::~Clock() 
{ 
} 

bool TEST::Clock::on_expose_event(GdkEventExpose* event) 
{ 
    // This is where we draw on the window 
    Glib::RefPtr<Gdk::Window> window = get_window(); 
    if(window) 
    { 
    Gtk::Allocation allocation = get_allocation(); 
    const int width = allocation.get_width(); 
    const int height = allocation.get_height(); 

    Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context(); 

    if (event) 
    { 
     // clip to the area indicated by the expose event so that we only 
     // redraw the portion of the window that needs to be redrawn 
     cr->rectangle(event->area.x, event->area.y, 
       event->area.width, event->area.height); 
     cr->clip(); 
    } 

    // scale to unit square and translate (0, 0) to be (0.5, 0.5), i.e. 
    // the center of the window 
    cr->scale(width, height); 
    cr->translate(0.5, 0.5); 
    cr->set_line_width(m_lineWidth); 

    cr->save(); 
    //cr->set_source_rgba(0.337, 0.612, 0.117, 0.9); // green 
    cr->set_source_rgba(0.712, 0.437, 0.117, 0.7); // green 
    cr->paint(); 
    cr->restore(); 
    cr->arc(0, 0, m_radius, 0, 2 * M_PI); 
    cr->save(); 
    cr->set_source_rgba(1.0, 1.0, 1.0, 0.8); 
    cr->fill_preserve(); 
    cr->restore(); 
    cr->stroke_preserve(); 
    cr->clip(); 

    //clock ticks 
    for (int i = 0; i < 12; i++) 
    { 
     double inset = 0.05; 

     cr->save(); 
     cr->set_line_cap(Cairo::LINE_CAP_ROUND); 

     if (i % 3 != 0) 
     { 
      inset *= 0.8; 
      cr->set_line_width(0.03); 
     } 

     cr->move_to(
       (m_radius - inset) * cos (i * M_PI/6), 
       (m_radius - inset) * sin (i * M_PI/6)); 
     cr->line_to (
       m_radius * cos (i * M_PI/6), 
       m_radius * sin (i * M_PI/6)); 
     cr->stroke(); 
     cr->restore(); /* stack-pen-size */ 
    } 

    // store the current time 
    time_t rawtime; 
    time(&rawtime); 
    struct tm * timeinfo = localtime (&rawtime); 

    // compute the angles of the indicators of our clock 
    double minutes = timeinfo->tm_min * M_PI/30; 
    double hours = timeinfo->tm_hour * M_PI/6; 
    double seconds= timeinfo->tm_sec * M_PI/30; 

    cr->save(); 
    cr->set_line_cap(Cairo::LINE_CAP_ROUND); 

    // draw the seconds hand 
    cr->save(); 
    cr->set_line_width(m_lineWidth/3); 
    cr->set_source_rgba(0.7, 0.7, 0.7, 0.8); // gray 
    cr->move_to(0, 0); 
    cr->line_to(sin(seconds) * (m_radius * 0.9), 
      -cos(seconds) * (m_radius * 0.9)); 
    cr->stroke(); 
    cr->restore(); 

    // draw the minutes hand 
    cr->set_source_rgba(0.117, 0.337, 0.612, 0.9); // blue 
    cr->move_to(0, 0); 
    cr->line_to(sin(minutes + seconds/60) * (m_radius * 0.8), 
      -cos(minutes + seconds/60) * (m_radius * 0.8)); 
    cr->stroke(); 

    // draw the hours hand 
    cr->set_source_rgba(0.337, 0.612, 0.117, 0.9); // green 
    cr->move_to(0, 0); 
    cr->line_to(sin(hours + minutes/12.0) * (m_radius * 0.5), 
      -cos(hours + minutes/12.0) * (m_radius * 0.5)); 
    cr->stroke(); 
    cr->restore(); 

    // draw a little dot in the middle 
    cr->arc(0, 0, m_lineWidth/3.0, 0, 2 * M_PI); 
    cr->fill(); 

    } 

    return true; 
} 


bool TEST::Clock::onSecondElapsed(void) 
{ 
    // force our program to redraw the entire clock. 
    Glib::RefPtr<Gdk::Window> win = get_window(); 
    if (win) 
    { 
     Gdk::Rectangle r(0, 0, get_allocation().get_width(), 
       get_allocation().get_height()); 
     win->invalidate_rect(r, false); 
    } 
    return true; 
} 

main.cc

#include "test.h" 
#include <gtkmm.h> 

int main(int argc, char** argv) 
{ 
    Gtk::Main kit(argc, argv); 

    //Gtk::Window win; 
    //win.set_title("Cairomm Clock"); 

    //Clock c; 
    //win.add(c); 
    //c.show(); 

    TEST t; 


    Gtk::Main::run(t); 

    return 0; 
} 

g++ -g test.cc main.cc -o test `pkg-config gtkmm-2.4 cairomm-1.0` 

답변

5

이 부분은 나에게 의심 컴파일이 범위 C의 끝에서

Clock c; 
H2.pack_start(c); 

가 파괴된다. 나는 그것이 실제로 충돌하지 않는 이유는 모르겠지만, 아마도 다른 누군가가 그것에 대해 밝힐 수 있습니다. TEST에서 시계가 올바른 수명을 갖도록 선언하려고합니다.

class TEST { 
    ... 
    class Clock ... { 
    ... 
    }; 
    Clock c; // new code 
    ... 
}; 
+0

젠장, 나쁘지. 예, 나는 이것을 깨달았고 당신의 대답을 보았을 때 게시했습니다. 어쨌든 +1 해줘서 고마워. – enthusiasticgeek