检测到 Gtk::Image 上的点击吗?

发布于 2024-11-18 07:57:45 字数 1509 浏览 4 评论 0原文

我一直在尝试用 gtkmm 检测对 Gtk::Image 的点击超过 2 小时,但我无法让它工作。它确实可以正常编译和执行,但该事件从不触发。

我尝试过的一些东西,可以编译,不会崩溃,但不起作用:

m_image = manage(new Gtk::Image(Gtk::Stock::APPLY, Gtk::ICON_SIZE_BUTTON));
m_image->add_events(Gdk::ALL_EVENTS_MASK); 
m_hbox->pack_start(*m_image, Gtk::PACK_SHRINK);

m_image->signal_button_release_event()
    .connect(sigc::hide(sigc::mem_fun(*this, &Todo::switchStatus)));

m_image->show();

或者

#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/button.h>
#include <gtkmm/stock.h>
#include <gtkmm/image.h>

#include <iostream>

using namespace std;

class Win : public Gtk::Window
{
    public:
        Win();
        bool link(GdkEventButton* e);

    private:
        Gtk::Image image;
};

Win::Win()
    : image(Gtk::Stock::APPLY, Gtk::ICON_SIZE_BUTTON)
{
    cerr << "created" << endl;

    image.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
    image.signal_button_release_event().connect(sigc::mem_fun(*this, &Win::link));
    image.show();

    add(image);
}

bool Win::link(GdkEventButton* e)
{
    cerr << "kuh" << endl;
}

int main(int argc, char *argv[])
{
    Gtk::Main   app(argc, argv);

    Gtk::Window window;
    window.resize(300, 500);

    Win win;

    Gtk::Main::run(win);

    return 0;
}

I've been trying to detect click on a Gtk::Image with gtkmm for over 2 hours, but I couldn't get it to work. It does compile and execute fine, but the event is never triggered.

Some stuff I tried, that compiles, does not crash, but doesn't work:

m_image = manage(new Gtk::Image(Gtk::Stock::APPLY, Gtk::ICON_SIZE_BUTTON));
m_image->add_events(Gdk::ALL_EVENTS_MASK); 
m_hbox->pack_start(*m_image, Gtk::PACK_SHRINK);

m_image->signal_button_release_event()
    .connect(sigc::hide(sigc::mem_fun(*this, &Todo::switchStatus)));

m_image->show();

or

#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/button.h>
#include <gtkmm/stock.h>
#include <gtkmm/image.h>

#include <iostream>

using namespace std;

class Win : public Gtk::Window
{
    public:
        Win();
        bool link(GdkEventButton* e);

    private:
        Gtk::Image image;
};

Win::Win()
    : image(Gtk::Stock::APPLY, Gtk::ICON_SIZE_BUTTON)
{
    cerr << "created" << endl;

    image.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
    image.signal_button_release_event().connect(sigc::mem_fun(*this, &Win::link));
    image.show();

    add(image);
}

bool Win::link(GdkEventButton* e)
{
    cerr << "kuh" << endl;
}

int main(int argc, char *argv[])
{
    Gtk::Main   app(argc, argv);

    Gtk::Window window;
    window.resize(300, 500);

    Win win;

    Gtk::Main::run(win);

    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陌若浮生 2024-11-25 07:57:45

来自 http://developer.gnome.org/gtkmm/unstable/classGtk_1_1Image.html

Gtk::Image 是一个“无窗口”小部件(没有自己的 Gdk::Window),因此默认情况下不接收事件。如果您想接收图像上的事件,例如按钮单击,请将图像放入 Gtk::EventBox 中,然后连接到事件框上的事件信号

所以我想尝试在包装图像后在事件框上放置一个信号与事件框。

From http://developer.gnome.org/gtkmm/unstable/classGtk_1_1Image.html:

Gtk::Image is a "no window" widget (has no Gdk::Window of its own), so by default does not receive events. If you want to receive events on the image, such as button clicks, place the image inside a Gtk::EventBox, then connect to the event signals on the event box

So I guess try to put a signal on an eventbox after wrapping the image with the EventBox.

§普罗旺斯的薰衣草 2024-11-25 07:57:45

这个线程很老了,但仍然很受欢迎。我遇到了同样的问题,我编写了这段代码,也许它可以帮助别人拯救蒂姆。仅当指针悬停在图像上时,我的代码才会检测到单击。

#include <gtk/gtk.h>

//compile with cc `pkg-config --cflags gtk+-3.0` text.c `pkg-config --libs gtk+-3.0` -o text

static void click_callback(GtkWidget *widget, GdkEventButton *event, gpointer );
static gboolean inRange(gint value, gint min, gint max);
static gboolean pointInRect(gint mouseX, gint mouseY, gint wx, gint wy, gint width, gint height);

GtkWidget *image;
GtkWidget *image2;
   
int main (int argc, char *argv[])
{
  GtkWidget *event_box;
  GtkWidget *window;
  GtkWidget *box;
 
  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  
  box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);

  /* GTK_ALIGN_CENTER is necessary otherwise 
   * the callback triggers from the space on
   * the top and the bottom of the image */
   
  gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
  
  image  = gtk_image_new_from_file("image1.png");
  image2 = gtk_image_new_from_file("image2.png");
  gtk_box_pack_start(GTK_BOX(box), image, TRUE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(box), image2, TRUE, FALSE, 0);
  
  event_box = gtk_event_box_new ();
  gtk_container_add (GTK_CONTAINER (event_box), box);

  gtk_container_add (GTK_CONTAINER (window), event_box);
  
  g_signal_connect(window, "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  g_signal_connect( event_box, "button_press_event", G_CALLBACK( click_callback ), image);
  
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_title(GTK_WINDOW(window), "Image click event");

  gtk_widget_show_all(window);

 gtk_main();

  return 0;
}

static void click_callback(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    GtkAllocation alloc;
    GtkAllocation alloc2;

    gtk_widget_get_allocation(image, &alloc);
    gtk_widget_get_allocation(image2, &alloc2);
    
    if (pointInRect(event->x, event->y, alloc.x, alloc.y, alloc.width, alloc.height))
        g_print("You clicked from image\n");

    if (pointInRect(event->x, event->y, alloc2.x, alloc2.y, alloc2.width, alloc2.height))
        g_print("You clicked from image2\n");

}

static gboolean pointInRect(gint mouseX, gint mouseY, gint wx, gint wy, gint width, gint height)
{
    return inRange(mouseX, wx, wx + width) && 
            inRange(mouseY, wy, wy + height);
}

static gboolean inRange(gint value, gint min, gint max)
{
    return (value >= min && value <= max);
}

This thread is quite old but still popular. I came across the same problem and I coded this code, maybe it can help someone save tim. My code detects the click ONLY if the pointer is hovering the image.

#include <gtk/gtk.h>

//compile with cc `pkg-config --cflags gtk+-3.0` text.c `pkg-config --libs gtk+-3.0` -o text

static void click_callback(GtkWidget *widget, GdkEventButton *event, gpointer );
static gboolean inRange(gint value, gint min, gint max);
static gboolean pointInRect(gint mouseX, gint mouseY, gint wx, gint wy, gint width, gint height);

GtkWidget *image;
GtkWidget *image2;
   
int main (int argc, char *argv[])
{
  GtkWidget *event_box;
  GtkWidget *window;
  GtkWidget *box;
 
  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  
  box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);

  /* GTK_ALIGN_CENTER is necessary otherwise 
   * the callback triggers from the space on
   * the top and the bottom of the image */
   
  gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
  
  image  = gtk_image_new_from_file("image1.png");
  image2 = gtk_image_new_from_file("image2.png");
  gtk_box_pack_start(GTK_BOX(box), image, TRUE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(box), image2, TRUE, FALSE, 0);
  
  event_box = gtk_event_box_new ();
  gtk_container_add (GTK_CONTAINER (event_box), box);

  gtk_container_add (GTK_CONTAINER (window), event_box);
  
  g_signal_connect(window, "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  g_signal_connect( event_box, "button_press_event", G_CALLBACK( click_callback ), image);
  
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_title(GTK_WINDOW(window), "Image click event");

  gtk_widget_show_all(window);

 gtk_main();

  return 0;
}

static void click_callback(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    GtkAllocation alloc;
    GtkAllocation alloc2;

    gtk_widget_get_allocation(image, &alloc);
    gtk_widget_get_allocation(image2, &alloc2);
    
    if (pointInRect(event->x, event->y, alloc.x, alloc.y, alloc.width, alloc.height))
        g_print("You clicked from image\n");

    if (pointInRect(event->x, event->y, alloc2.x, alloc2.y, alloc2.width, alloc2.height))
        g_print("You clicked from image2\n");

}

static gboolean pointInRect(gint mouseX, gint mouseY, gint wx, gint wy, gint width, gint height)
{
    return inRange(mouseX, wx, wx + width) && 
            inRange(mouseY, wy, wy + height);
}

static gboolean inRange(gint value, gint min, gint max)
{
    return (value >= min && value <= max);
}
终遇你 2024-11-25 07:57:45

我喜欢在图像上方放置一个不透明度为 0 的按钮。然后您可以使用其中的单击事件。

I like to put a button overtop of the image with an opacity of 0. Then you can use the click event from it instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文