GTK自定义RTL复选框如何从标签部件触发CheckButton悬停事件
要实现标签悬停时同步触发复选框的悬停效果,你只需要监听Gtk::EventBox的鼠标进入/离开事件,手动控制复选框的悬停状态即可,具体修改步骤如下:
- 在
MyWindow类的私有方法部分新增两个事件回调声明:
bool on_label_enter(GdkEventCrossing *); bool on_label_leave(GdkEventCrossing *);
- 在
MyWindow构造函数中,新增这两个事件的信号绑定:
eventbox.signal_enter_notify_event().connect(sigc::mem_fun(*this, &MyWindow::on_label_enter)); eventbox.signal_leave_notify_event().connect(sigc::mem_fun(*this, &MyWindow::on_label_leave));
- 实现这两个回调函数:
bool MyWindow::on_label_enter(GdkEventCrossing *event) { // 给复选框添加悬停状态标志 checkbutton.set_state_flags(Gtk::STATE_FLAG_PRELIGHT, false); return true; } bool MyWindow::on_label_leave(GdkEventCrossing *event) { // 清除复选框的悬停状态标志 checkbutton.unset_state_flags(Gtk::STATE_FLAG_PRELIGHT); return true; }
修改完成后运行代码,当鼠标悬停在自定义标签上时,复选框就会和原生复选框一样触发悬停高亮效果,符合预期交互逻辑。
完整修改后可运行代码
#include <gtkmm.h> using Gtk::Application; using Gtk::Button; using Gtk::CheckButton; using Gtk::EventBox; using Gtk::Grid; using Gtk::Label; using Gtk::Window; class MyWindow : public Window { Button button; CheckButton checkbutton; EventBox eventbox; Grid grid; Label label; bool on_label_clicked(GdkEventButton *); bool on_label_enter(GdkEventCrossing *); bool on_label_leave(GdkEventCrossing *); void arrange_content_layout(); public: MyWindow(); }; bool MyWindow::on_label_clicked(GdkEventButton *event) { if (event->button == 1 && event->type == GDK_BUTTON_PRESS) { checkbutton.set_active(!checkbutton.get_active()); return true; } return false; } bool MyWindow::on_label_enter(GdkEventCrossing *event) { checkbutton.set_state_flags(Gtk::STATE_FLAG_PRELIGHT, false); return true; } bool MyWindow::on_label_leave(GdkEventCrossing *event) { checkbutton.unset_state_flags(Gtk::STATE_FLAG_PRELIGHT); return true; } void MyWindow::arrange_content_layout() { checkbutton.set_margin_start(6); button.set_margin_top(24); grid.child_property_width(button) = 2; grid.set_margin_top(24); grid.set_margin_start(24); grid.set_margin_end(24); grid.set_margin_bottom(24); } MyWindow::MyWindow() : button("Click to steal focus") , label ("Our custom RTL label") { eventbox.add(label); eventbox.signal_button_press_event().connect(sigc::mem_fun( *this, &MyWindow::on_label_clicked)); eventbox.signal_enter_notify_event().connect(sigc::mem_fun(*this, &MyWindow::on_label_enter)); eventbox.signal_leave_notify_event().connect(sigc::mem_fun(*this, &MyWindow::on_label_leave)); grid.add(eventbox); grid.add(checkbutton); grid.attach(button, 0, 1); add(grid); arrange_content_layout(); set_default_size(120, 60); show_all(); } int main() { auto app = Application::create("domain.reverse.sample.rtl-checkbutton"); MyWindow window; return app->run(window); }
内容的提问来源于stack exchange,提问作者Keyikedalube Ndang
相关产品推荐
相关产品推荐

