按下按钮时,Gtkmm scroll_event不起作用

时间:2013-04-20 11:40:46

标签: c++ events gtk signals gtkmm

我有一个连接了两个事件的Gtk :: EventBox:button_press_event和scroll_event。 所有这两个事件都可以正常工作,但是当我按住鼠标按钮时,不会发出滚动事件。

我在课堂上实现了两个函数bool on_button_press_event (GdkEventButton *e)bool on_scroll_event (GdkEventScroll *e)。这两个函数返回false以进一步传播事件。

我正在使用gtkmm3。

我该如何解决这个问题?

重现问题的代码示例:

#include <gtkmm.h>
#include <iostream>

class MyWindow : public Gtk::Window
{
  Gtk::EventBox event_box;
  Gtk::ScrolledWindow scrolled;
public:
  bool on_button_press_event(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;
    return false;
  }

  bool on_scroll_event(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;
    return false;
  }

  MyWindow ()
  {
    add(scrolled);
    scrolled.add(event_box);
    set_default_size(640, 480);
    show_all();
  }
};

int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  MyWindow window;
  kit.run(window);
  return 0;
}

2 个答案:

答案 0 :(得分:3)

看起来在Windows上,scrolledWindow是观看滚动事件而不是主窗口的正确位置。

使用以下修改,我能够在Windows 7上处理滚动事件。

#include <gtkmm.h>
#include <iostream>

class MyScrolledWindow : public Gtk::ScrolledWindow
{
public:
  bool on_scroll_event(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;
    return false;
  }

  MyScrolledWindow()
  {
  }
};

class MyWindow : public Gtk::Window
{
  Gtk::EventBox event_box;
  MyScrolledWindow scrolled;
public:
  bool on_button_press_event(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;
    return false;
  }

  MyWindow ()
  {
    add(scrolled);
    scrolled.add(event_box);
    set_default_size(640, 480);
    show_all();
  }
};

int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  MyWindow window;
  kit.run(window);
  return 0;
}

======旧答案:================

我无法重现你的意思。这是我用来尝试重现您的问题的代码:

#include <gtkmm.h>
#include <iostream>

class MyEventBox : public Gtk::EventBox
{
  bool on_button_press_event(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;

    return false;
  }

  bool on_scroll_event(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;

    return false;
  }
};


int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  Gtk::Window window;
  MyEventBox eventBox;

  eventBox.show();
  window.add(eventBox);

  kit.run(window);

  return 0;
}

为了编译,我使用了下面的命令行(使用Linux):

g++ main.cpp $(pkg-config --cflags --libs gtkmm-3.0)

  • 如果您可以使用此最低示例重现您的问题,则问题可能是特定于平台的,并且可能需要使用窗口/事件框“Gdk::Window”进行解决方法。
  • 如果您无法使用此代码重现您的问题,则问题会在代码中的其他位置引起,您需要发布更多信息。

答案 1 :(得分:3)

您展示的示例代码有两个问题。

  • 首先,你说“我有一个连接了两个事件的Gtk :: EventBox”。但是在您的示例中,您连接到MyWindow的事件,并使EventBox的事件保持未连接状态。

  • EventBox允许您接收活动,但您仍需明确说明您希望接收哪些活动。

这是更正后的代码:

#include <gtkmm.h>
#include <iostream>

class MyWindow : public Gtk::Window
{
  Gtk::EventBox event_box;

  bool event_box_button_press(GdkEventButton *b)
  {
    std::cout << "button press" << std::endl;
    return false;
  }

  bool event_box_scroll(GdkEventScroll *e)
  {
    std::cout << "scrollEvent" << std::endl;
    return false;
  }

public:
  MyWindow ()
  {
    event_box.add_events(Gdk::BUTTON_MOTION_MASK);
    event_box.add_events(Gdk::SCROLL_MASK);

    event_box.signal_button_press_event().connect(
        sigc::mem_fun(*this, &MyWindow::event_box_button_press));
    event_box.signal_scroll_event().connect(
        sigc::mem_fun(*this, &MyWindow::event_box_scroll));

    add(event_box);

    set_default_size(640, 480);
    show_all();
  }
};

int main(int argc, char** argv)
{
  Gtk::Main kit(argc, argv);
  MyWindow window;
  kit.run(window);
  return 0;
}

关于此代码的一些注意事项:

  • 我省略了ScrolledWindow,因为这与示例无关。你不需要它来捕捉滚动事件。如果您确实需要应用程序的滚动窗口,可以将其添加回来。

  • 如果您使用所需的行为派生自定义EventBox,则代码可能会更整洁。我没有这样做,以便更接近原始代码。

  • 有关连接信号和sigc::mem_fun内容的信息,请参阅this documentation