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 【问题描述】:我对@987654321@ 进行了子类化,这样我可以在修改小部件时为其赋予颜色,但用户尚未按下回车键。
愚蠢的是,如果事件是FL_KEYDOWN
事件,则永远不会调用handle(int e)
函数,而其他事件(例如FL_KEYUP
、FL_DRAG
、FL_FOCUS
等)正在正常传播。
小部件是小部件层次结构的一部分...可能是这个层次结构中它的一个父级正在吸收这个特定的FL_KEYDOWN
事件?
编辑:显然,小部件也没有焦点(通过比较 this
与 Fl::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)的主要内容,如果未能解决你的问题,请参考以下文章
以 UIScrollView 作为子类的 UIView 不接收触摸事件