首页 文章

无法为Motif应用程序获取键盘输入或遍历工作

提问于
浏览
3

我有一个在Raspberry Pi上运行的Motif应用程序 . 出于调试目的,我在PC上使用X Windows服务器,通过Putty SSH隧道X.值得注意的是,当我最初运行应用程序时,输入将转到SSH shell / Putty窗口 . 单击应用程序窗口或其中一个按钮可停止输入到Putty窗口 .

小部件层次结构是:

顶级shell-> Scrolled window-> Form-> RowColumn

然后,行列小部件包含任意数量的按钮小部件 .

我在顶级shell上注册了一个带KeyPressMask的事件处理程序,当它不起作用时,在RowColumn和所有按钮上 . 永远不会被召唤 . 创建的第一个按钮获得焦点(通过其边框可视化显示),但只有当我用鼠标单击另一个按钮时才会更改(单击事件已成功检测到) .

我试过在顶级shell上摆弄XmNkeyboardFocusPolicy . 我试过为行列小部件和第一个按钮调用XtSetKeyboardFocus() . 我在创建按钮时尝试将XmNtraversalOn指定为True . 什么都行不通 . 我很沮丧 .

我已经使按钮单击回调报告XtIsSensitive()的值为它被调用的小部件(应该是按钮)并且它报告值1(== True我假设) .

我很乐意使用内置的Motif遍历例程,只要我还可以在按下返回键时模拟/检测按钮激活 . 我也很乐意通过显式检测推送键来编写自己的遍历例程 . 我真的不在乎 . 我只是希望能够通过按键盘上的按钮轻松导航!

在此先感谢能帮助解决问题的任何人 .

经过更多的实验,我发现如果我通过将它放在我的.xinitrc中直接运行我的应用程序,那么遍历工作正常,按空格使按钮闪烁就像按下一样,但实际上并没有导致按钮做任何事情 .

但是,如果我通过删除我的xinitrc文件并在控制台提示符下键入“startx”来运行标准窗口管理器,然后打开终端并从命令行运行我的应用程序,那么我会得到与在网络上运行它时相同的行为到我的电脑上的窗口管理器 .

在我看来,这可能是基于TTY的 . 当通过.xinitrc运行时,应用程序在启动时没有TTY(我相信),但是当直接从命令提示符启动时,它当然有一个TTY . TTY能以某种方式消耗掉所有的键盘输入吗?

1 回答

  • 2

    默认情况下,使用箭头键导航行列中的按钮,并使用空格键激活按钮 .

    这是因为使用TAB遍历的窗口小部件必须位于TAB组中 . “行列”窗口小部件位于TAB组中,但按钮不在 . TAB键将选择“行列”窗口小部件并选择第一个按钮 . 然后可以使用箭头键移动到其他按钮 .

    激活按钮的默认键是空格键,使用另一个键覆盖默认事件转换表 .

    这是一个示例程序,它使用tab来遍历并返回以激活按钮

    #include <Xm/Xm.h>
    #include <Xm/MainW.h>
    #include <Xm/PushB.h>
    #include <Xm/RowColumn.h>
    
    int main(int argc, char* argv[]) {
      XtSetLanguageProc(NULL, NULL, NULL);
      XtAppContext app;
    
      Widget toplevel = XtVaOpenApplication(&app, "traverse", NULL, 0, &argc, argv, NULL,
                                            sessionShellWidgetClass, NULL);
    
      Widget main_w = XmCreateMainWindow (toplevel, "main_w", NULL, 0);
      Widget mainrc = XtVaCreateWidget("mainrc", xmRowColumnWidgetClass, main_w,
                       XmNpacking, XmPACK_COLUMN,
                       XmNnumColumns, 3,
                       XmNentryBorder, 1,
                       NULL);
      for (int i=0; i<9; i++) {
        Widget b = XtVaCreateWidget("button", xmPushButtonWidgetClass, mainrc,
                    XmNnavigationType, XmTAB_GROUP, // Make button a Tab Group
                    NULL);
        // Specify Return key to activate button
        XtOverrideTranslations (b, XtParseTranslationTable ("<Key>Return: ArmAndActivate()"));
        XtManageChild(b);
      } 
    
      XtManageChild(mainrc);
      XtManageChild(main_w);
      XtRealizeWidget(toplevel);
      XtAppMainLoop(app);
    
      return 0;
    }
    

相关问题