3

button_press_event と scroll_event の 2 つのイベントが接続された Gtk::EventBox があります。2 つのイベントはすべて正常に動作しますが、マウス ボタンを押したままにすると、スクロール イベントが発生しません。

クラスに と の 2 つの関数を実装しましbool on_button_press_event (GdkEventButton *e)bool on_scroll_event (GdkEventScroll *e)。この 2 つの関数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;
}
4

2 に答える 2

3

あなたが示すコード例には 2 つの問題があります。

  • まず、「2 つのイベントが接続された 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

于 2013-04-28T13:06:40.833 に答える
3

ウィンドウのように見えますが、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が必要になる場合があります。
  • このコードを使用して問題を再現できない場合、問題はコードの別の場所で発生しているため、詳細情報を投稿する必要があります。
于 2013-04-27T09:27:12.287 に答える