专注于GtkGlArea不会被捕获

Focus on GtkGlArea not getting captured

本文关键字:GtkGlArea 专注      更新时间:2023-10-16

我的应用程序由一个树视图组成,其中包含用户可以单击的文件。根据文件,预览区域将显示用于显示该文件的相应控件。对于某些文件,这是呈现内容的GtkGlArea。它包括一个可以使用键盘和鼠标移动的相机。

单击文件时,将发生以下情况(在GtkTreeViewchanged事件的事件处理程序内)

if (mActiveView->needsOpenGL()) {
    gtk_widget_show(mGlControl);
    gtk_widget_grab_focus(mGlControl);
} else {
    gtk_widget_hide(mGlControl);
}

mGlControl是使用读取我的 Glade UI 模板的GtkBuilder创建的。该控件具有标志VisibleCan focusApplication paintableDouble BufferedSensitive和事件Pointer MotionButton PressButton ReleaseKey PressKey ReleaseFocus ChangeStructure

但是,当在树视图中

单击某个元素时,焦点将停留在该项目上,当我使用键盘时,它会反映在树视图中(例如,使用向上箭头选择下一项)。

是否有可能将焦点放在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});
}

并且应该在处理单击事件之后延迟它,现在树视图项得到适当的散焦。