Я работаю над оптимизированным по скорости генератором фракталов, используя Glade и C++, и мне трудно разобраться в некоторых тонкостях gtkmm.
Я пытаюсь уловить событие щелчка из Gtk::DrawingArea, т. е. вызов функции при нажатии на него.
Я не могу создать объект Gtk::EventBox со стандартным конструктором. После долгих проб и ошибок мне удалось поймать событие щелчка в главном окне:
#include
#include
#include
#include
Gtk::Window* W_Main;
Gtk::DrawingArea* D_Fractal;
//Gtk::EventBox EB_CatchClick;
int AWidth;
int AHeight;
bool test;
gboolean on_D_Fractal_draw(const Cairo::RefPtr cr) {
AWidth = D_Fractal->get_width();
AHeight = D_Fractal->get_height();
//Draw background
cr->set_source_rgb(1.0, 1.0, 1.0);
if(test) {
cr->set_source_rgb(0.0, 0.0, 0.0);
}
cr->rectangle(10, 10, AWidth-20, AHeight-20);
cr->fill();
return 0;
}
gboolean on_W_Main_button_press_event(GdkEventButton *event) {
switch ( event->type )
{
case GDK_BUTTON_PRESS :
test = true;
std::cout get_widget("W_Main", W_Main);
builder->get_widget("D_Fractal", D_Fractal);
D_Fractal->signal_draw().connect(sigc::ptr_fun(on_D_Fractal_draw));
W_Main->signal_button_press_event().connect(sigc::ptr_fun(on_W_Main_button_press_event));
app->run(*W_Main);
}
Но простое включение строки EB_CatchClick = Gtk::EventBox() в main(int argc, char** argv) вместе с раскомментированием соответствующее объявление приводит к следующей ошибке.
Невозможно создать GtkStyleContext без подключения к экрану
Я нашел эту страницу, но структура их программы значительно отличается от моей, поэтому любая прямая передача вряд ли сработает. Буду признателен за любые предложения.
РЕДАКТИРОВАТЬ: я немного поработал над проблемой, и теперь код выглядит так:
#include
#include
#include
#include
Gtk::Window* W_Main;
Gtk::DrawingArea* D_Fractal;
Gtk::EventBox* EB_CatchClick;
int AWidth;
int AHeight;
bool test;
gboolean on_D_Fractal_draw(const Cairo::RefPtr cr) {
AWidth = D_Fractal->get_width();
AHeight = D_Fractal->get_height();
//Draw background
cr->set_source_rgb(1.0, 1.0, 1.0);
if(test) {
cr->set_source_rgb(0.0, 0.0, 0.0);
}
cr->rectangle(10, 10, AWidth-20, AHeight-20);
cr->fill();
return 0;
}
gboolean on_D_Fractal_button_press_event(GdkEventButton *event) {
switch ( event->type )
{
case GDK_BUTTON_PRESS :
test = true;
std::cout get_widget("W_Main", W_Main);
builder->get_widget("D_Fractal", D_Fractal);
EB_CatchClick = new Gtk::EventBox;
EB_CatchClick->set_size_request(600,400);
EB_CatchClick->add(*D_Fractal);
D_Fractal->signal_draw().connect(sigc::ptr_fun(on_D_Fractal_draw));
EB_CatchClick->signal_button_press_event().connect(sigc::ptr_fun(on_D_Fractal_button_press_event));
app->run(*W_Main);
delete EB_CatchClick;
}
Каким-то образом размещение Gtk::EventBox в куче привело к его компиляции. Однако теперь я получаю следующее сообщение об ошибке во время выполнения:
Attempting to add a widget with type
gtkmm__GtkDrawingArea to a container of type
gtkmm__GtkEventBox, but the widget is already
inside a container of type gtkmm__GtkWindow,
please remove the widget from its existing
container first.
Означает ли это, что мне нужно удалить Gtk::DrawingArea из моего Gtk::Window, добавить его в Gtk::EventBox > а затем добавить Gtk::EventBox в Gtk::Window? Это кажется ужасно неэлегантным решением (если оно вообще работает), и я хотел бы узнать об альтернативах.
РЕДАКТИРОВАТЬ 2: В комментариях был запрошен файл Glade, так вот:
False
Mandelbronatoor
600
400
True
False
True
True
False
True
True
0
0
Подробнее здесь: https://stackoverflow.com/questions/786 ... rawingarea