专注于GtkGlArea不会被捕获
Focus on GtkGlArea not getting captured
我的应用程序由一个树视图组成,其中包含用户可以单击的文件。根据文件,预览区域将显示用于显示该文件的相应控件。对于某些文件,这是呈现内容的GtkGlArea
。它包括一个可以使用键盘和鼠标移动的相机。
单击文件时,将发生以下情况(在GtkTreeView
的changed
事件的事件处理程序内)
if (mActiveView->needsOpenGL()) {
gtk_widget_show(mGlControl);
gtk_widget_grab_focus(mGlControl);
} else {
gtk_widget_hide(mGlControl);
}
mGlControl
是使用读取我的 Glade UI 模板的GtkBuilder
创建的。该控件具有标志Visible
、Can focus
、Application paintable
、Double Buffered
、Sensitive
和事件Pointer Motion
、Button Press
、Button Release
、Key Press
、Key Release
、Focus Change
、Structure
单击某个元素时,焦点将停留在该项目上,当我使用键盘时,它会反映在树视图中(例如,使用向上箭头选择下一项)。
是否有可能将焦点放在GtkGlArea上?
事实证明,在重新阅读我发布的问题后,我的直觉是正确的。似乎在树视图更改事件的事件处理程序内切换焦点不起作用。我认为事件链可能是这样的:
- 项目被点击
- 处理和委派更改的事件 ->焦点设置在 gl 控件上
- 处理项上的"单击"事件 ->树视图项上设置焦点
似乎单击项目的焦点逻辑是在发出更改事件后完成的。
我调整了我的代码,如下所示:
if (mActiveView->needsOpenGL()) {
gtk_widget_show(mGlControl);
runInMainThread([this]() { gtk_widget_grab_focus(mGlControl); });
} else {
gtk_widget_hide(mGlControl);
}
这是一种方便的方法:
void MainWindow::runInMainThread(const std::function<void()> &callback) {
g_idle_add(callbacks::mainThreadCallback, new callbacks::FunctionHolder{callback});
}
并且应该在处理单击事件之后延迟它,现在树视图项得到适当的散焦。