根据鼠标 enter/leave 事件打开和关闭小部件的焦点
Turn widget's focus on and off based on mouse enter/leave event
我想在鼠标指针进入此小部件时打开 Gtk::SpinButton
进入焦点,然后在鼠标指针离开时再次关闭它。
信号事件似乎没有响应,而 window 仍然是 运行。但是 std::cout
输出是在我关闭 window.
之后打印的
如何实现预期的小部件行为?
#include <gtkmm.h>
#include <iostream>
class SpinButtonExample : public Gtk::Window {
Gtk::Grid grid;
Gtk::Label label;
Glib::RefPtr<Gtk::Adjustment> adjustment;
Gtk::SpinButton spinbutton;
public:
SpinButtonExample();
bool on_enter_notify_event(GdkEventCrossing *);
bool on_leave_notify_event(GdkEventCrossing *);
};
SpinButtonExample::SpinButtonExample()
: label ("Hi")
, adjustment(Gtk::Adjustment::create(0, 0, 10))
, spinbutton(adjustment)
{
add_events(Gdk::ENTER_NOTIFY_MASK);
add_events(Gdk::LEAVE_NOTIFY_MASK);
spinbutton.signal_enter_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_enter_notify_event));
spinbutton.signal_leave_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_leave_notify_event));
grid.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
grid.set_column_homogeneous(true);
grid.set_margin_start(10);
grid.set_margin_end(10);
grid.set_margin_top(10);
grid.set_margin_bottom(10);
grid.add(label);
grid.add(spinbutton);
add(grid);
show_all();
}
bool
SpinButtonExample::on_enter_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_SCROLL) {
std::cout << "Mouse entered\n";
spinbutton.set_can_focus();
return true;
}
return false;
}
bool
SpinButtonExample::on_leave_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_LEAVE_NOTIFY) {
std::cout << "Mouse left\n";
spinbutton.set_can_focus(false);
return true;
}
return false;
}
int
main()
{
auto application = Gtk::Application::create("test.focus.spinbutton");
SpinButtonExample test;
return application->run(test);
}
非常感谢 underscore_d 上面的评论。
答案是当鼠标指针离开 Gtk::SpinButton
小部件时将我们的焦点指向另一个小部件,对于进入事件,夺回焦点。
仅使用 set_can_focus()
打开和关闭是行不通的。
以下是更正的解决方案:
#include <gtkmm.h>
#include <iostream>
class SpinButtonExample : public Gtk::Window {
Gtk::Grid grid;
Gtk::Label label;
Glib::RefPtr<Gtk::Adjustment> adjustment;
Gtk::SpinButton spinbutton;
Gtk::Button button;
public:
SpinButtonExample();
bool on_enter_notify_event(GdkEventCrossing *);
bool on_leave_notify_event(GdkEventCrossing *);
};
SpinButtonExample::SpinButtonExample()
: label ("Hi")
, adjustment(Gtk::Adjustment::create(0, 0, 10))
, spinbutton(adjustment)
, button ("Default")
{
add_events(Gdk::ENTER_NOTIFY_MASK);
add_events(Gdk::LEAVE_NOTIFY_MASK);
button.set_margin_start(10);
button.set_can_default();
button.grab_focus();
spinbutton.set_can_default(false);
spinbutton.signal_enter_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_enter_notify_event));
spinbutton.signal_leave_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_leave_notify_event));
grid.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
grid.set_column_homogeneous(true);
grid.set_margin_start(10);
grid.set_margin_end(10);
grid.set_margin_top(10);
grid.set_margin_bottom(10);
grid.add(label);
grid.add(spinbutton);
grid.add(button);
add(grid);
show_all();
}
bool
SpinButtonExample::on_enter_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_ENTER_NOTIFY) {
std::cout << "Mouse entered" << std::endl;
spinbutton.grab_focus();
return true;
}
return false;
}
bool
SpinButtonExample::on_leave_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_LEAVE_NOTIFY) {
std::cout << "Mouse left" << std::endl;
button.grab_focus();
return true;
}
return false;
}
int
main()
{
auto application = Gtk::Application::create("test.focus.spinbutton");
SpinButtonExample test;
return application->run(test);
}
我想在鼠标指针进入此小部件时打开 Gtk::SpinButton
进入焦点,然后在鼠标指针离开时再次关闭它。
信号事件似乎没有响应,而 window 仍然是 运行。但是 std::cout
输出是在我关闭 window.
如何实现预期的小部件行为?
#include <gtkmm.h>
#include <iostream>
class SpinButtonExample : public Gtk::Window {
Gtk::Grid grid;
Gtk::Label label;
Glib::RefPtr<Gtk::Adjustment> adjustment;
Gtk::SpinButton spinbutton;
public:
SpinButtonExample();
bool on_enter_notify_event(GdkEventCrossing *);
bool on_leave_notify_event(GdkEventCrossing *);
};
SpinButtonExample::SpinButtonExample()
: label ("Hi")
, adjustment(Gtk::Adjustment::create(0, 0, 10))
, spinbutton(adjustment)
{
add_events(Gdk::ENTER_NOTIFY_MASK);
add_events(Gdk::LEAVE_NOTIFY_MASK);
spinbutton.signal_enter_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_enter_notify_event));
spinbutton.signal_leave_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_leave_notify_event));
grid.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
grid.set_column_homogeneous(true);
grid.set_margin_start(10);
grid.set_margin_end(10);
grid.set_margin_top(10);
grid.set_margin_bottom(10);
grid.add(label);
grid.add(spinbutton);
add(grid);
show_all();
}
bool
SpinButtonExample::on_enter_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_SCROLL) {
std::cout << "Mouse entered\n";
spinbutton.set_can_focus();
return true;
}
return false;
}
bool
SpinButtonExample::on_leave_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_LEAVE_NOTIFY) {
std::cout << "Mouse left\n";
spinbutton.set_can_focus(false);
return true;
}
return false;
}
int
main()
{
auto application = Gtk::Application::create("test.focus.spinbutton");
SpinButtonExample test;
return application->run(test);
}
非常感谢 underscore_d 上面的评论。
答案是当鼠标指针离开 Gtk::SpinButton
小部件时将我们的焦点指向另一个小部件,对于进入事件,夺回焦点。
仅使用 set_can_focus()
打开和关闭是行不通的。
以下是更正的解决方案:
#include <gtkmm.h>
#include <iostream>
class SpinButtonExample : public Gtk::Window {
Gtk::Grid grid;
Gtk::Label label;
Glib::RefPtr<Gtk::Adjustment> adjustment;
Gtk::SpinButton spinbutton;
Gtk::Button button;
public:
SpinButtonExample();
bool on_enter_notify_event(GdkEventCrossing *);
bool on_leave_notify_event(GdkEventCrossing *);
};
SpinButtonExample::SpinButtonExample()
: label ("Hi")
, adjustment(Gtk::Adjustment::create(0, 0, 10))
, spinbutton(adjustment)
, button ("Default")
{
add_events(Gdk::ENTER_NOTIFY_MASK);
add_events(Gdk::LEAVE_NOTIFY_MASK);
button.set_margin_start(10);
button.set_can_default();
button.grab_focus();
spinbutton.set_can_default(false);
spinbutton.signal_enter_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_enter_notify_event));
spinbutton.signal_leave_notify_event().connect(
sigc::mem_fun(*this, &SpinButtonExample::on_leave_notify_event));
grid.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
grid.set_column_homogeneous(true);
grid.set_margin_start(10);
grid.set_margin_end(10);
grid.set_margin_top(10);
grid.set_margin_bottom(10);
grid.add(label);
grid.add(spinbutton);
grid.add(button);
add(grid);
show_all();
}
bool
SpinButtonExample::on_enter_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_ENTER_NOTIFY) {
std::cout << "Mouse entered" << std::endl;
spinbutton.grab_focus();
return true;
}
return false;
}
bool
SpinButtonExample::on_leave_notify_event(GdkEventCrossing *event)
{
if (event->type == GDK_LEAVE_NOTIFY) {
std::cout << "Mouse left" << std::endl;
button.grab_focus();
return true;
}
return false;
}
int
main()
{
auto application = Gtk::Application::create("test.focus.spinbutton");
SpinButtonExample test;
return application->run(test);
}