FLTK:Fl_Value_Input 子类不接收 FL_KEYDOWN 事件(仅 FL_KEYUP)

Posted

技术标签:

【中文标题】FLTK:Fl_Value_Input 子类不接收 FL_KEYDOWN 事件(仅 FL_KEYUP)【英文标题】:FLTK: Fl_Value_Input subclass does not receive FL_KEYDOWN events (only FL_KEYUP) 【发布时间】:2016-10-27 12:01:40 【问题描述】:

我对@9​​87654321@ 进行了子类化,这样我可以在修改小部件时为其赋予颜色,但用户尚未按下回车键。

愚蠢的是,如果事件是FL_KEYDOWN 事件,则永远不会调用handle(int e) 函数,而其他事件(例如FL_KEYUPFL_DRAGFL_FOCUS 等)正在正常传播。

小部件是小部件层次结构的一部分...可能是这个层次结构中它的一个父级正在吸收这个特定的FL_KEYDOWN 事件?

编辑:显然,小部件也没有焦点(通过比较 thisFl::focus() 进行测试),这很奇怪,因为我正在输入它。

任何帮助将不胜感激。

Fx_Value_Input::Fx_Value_Input(int x, int y, int w, int h, const char* l)
: Fl_Value_Input(x, y, w, h, l)


int Fx_Value_Input::handle(int e)

    int r = Fl_Value_Input::handle(e);

    if (e == FL_KEYBOARD)
    
            if ((Fl::event_key() != FL_Enter && Fl::event_key() != FL_KP_Enter ) )
                    color(Fx::get_modified_color());
            else if ((Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter) &&             color() == Fx::get_modified_color())
                    color(FL_WHITE);
            redraw();
        

    return r;

【问题讨论】:

嗯,原来 Fl_Value_Input 不是 Fl_Input,而是包含一个 Fl_Input 作为成员(封装)。这个特定成员接收并处理 FL_KEYDOWN 事件并获得焦点...我需要找到一种方法将 FL_KEYDOWN 传播到 Fl_Value_Input ... 【参考方案1】:

使用 FL_KEYDOWN 是 Windows 的处理方式,正如您所发现的那样,它不起作用,因为您需要继承 Fl_Input_: 而不是 Fl_Input,即使这样,它也不能正常工作。

改为使用 when(FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY)。按下键时检查 changed() 和 clear_changed()。按下回车键时未设置。当满足该条件时,您可以更改颜色。

inputkey = new Fl_Input...
inputkey->when(FL_WHEN_CHANGED| FL_WHEN_ENTER_KEY);
inputkey->callback(cb);
....

void cb(Fl_Widget *ob)

   Fl_Input* ip = dynamic_cast<Fl_Input*>(ob);
   if (ip->changed())
   
       // change colour
       ip->clear_changed();
   
   else
   
      // change colour
   

【讨论】:

【参考方案2】:

在FLTK Google group 上得到了回复,解释了问题...没有简单的解决方法...

FLTK 将击键直接传递给焦点小部件。 Fl_Value_Input 包括一个 Fl_Input 小部件,当您在输入字段中单击时,该小部件将成为焦点小部件。

因此,“父级”Fl_Value_Input 永远不会看到 Fl_KEYDOWN 事件。 请注意,我引用了“父级”,因为 Fl_Value_Input 是 非常 特例。它不是从 Fl_Group 派生的,但它的行为有点 就像一个 Fl_Group 小部件。

那么为什么您的派生小部件会获得 FL_KEYUP 事件?那是另一个 FLTK 的特性:FL_KEYUP 事件也被传递到焦点 首先是小部件。但是,AFAICT 没有核心 FLTK 小部件 处理 FL_KEYUP 事件 - 它们都在它们的 handle() 中返回 0 方法。如果焦点小部件不处理 FLTK 尝试处理的事件 将其传递给父小部件,然后通过小部件向上传递 层次结构,直到它到达顶层窗口。因此(而这个 恕我直言,很奇怪)最终所有小部件都会收到所有 FL_KEYUP 事件 除非一个小部件从它的 handle() 方法中返回 1(即 通常情况并非如此)。取决于焦点小部件的深度 总的小部件层次结构可能是某些小部件得到相同的 FL_KEYUP 事件多次,因为焦点的所有父组 小部件尝试将事件传递给他们的所有孩子。

【讨论】:

以上是关于FLTK:Fl_Value_Input 子类不接收 FL_KEYDOWN 事件(仅 FL_KEYUP)的主要内容,如果未能解决你的问题,请参考以下文章

Fl_Window 子类不起作用

Cygwin 中的 FLTK 应用程序:GUI 不显示?

以 UIScrollView 作为子类的 UIView 不接收触摸事件

我收到一个链接器错误,我不理解 VC++ 和 FLTK [关闭]

FLTK 中的线程

fltk:无法解析 GlutWindow