如何使用箭头键更改窗口小部件之间的焦点?

时间:2014-03-17 07:10:26

标签: user-interface focus fltk

我在 FLTK 中处理用户界面,我的基本问题归结为:

我在主窗口(输入,输出,按钮小部件)上有一堆小部件。说,16项(4rows x 4 coloumns)。我需要使用箭头键在小部件之间导航。

主要是,如果焦点在(r4,c4)(右下角小部件):

右箭头按下应将焦点移至(r1,c1)(左上角小部件)。
左箭头按下应将焦点移至(r4,c3)。
向上箭头按下应将焦点转移到(r3,c4)。
向下箭头按下应将焦点移至(r1,c4)。

即。根据我们习惯的情况,导航应该非常直观地工作。

默认情况下,在使用箭头(或Tab)键时,焦点会按照创建顺序在窗口小部件之间更改。向上和向右总是转到下一个小部件(按创建顺序),向下和向左总是转到上一个小部件(按创建顺序)。

有没有办法在 FLTK 中执行此操作? 或者我需要创建一个算法来执行此操作?

2 个答案:

答案 0 :(得分:0)

在分发测试程序中查看名为demo.cxx的程序。它看起来可以做你想要的,没有任何特殊的编程。

  1. 首先关注退出按钮。
  2. 按Tab键时,焦点会更改为按钮框组
  3. 如果您随后开始使用箭头键,则焦点会改变您期望的方式。
  4. 如果你需要一个

    ,这是一个例子
    #include <FL/FL.H>
    #include <FL/Fl_Window.H>
    #include <FL/Fl_Button.H>
    #include <string>
    #include <vector>
    
    int ROWS = 4;
    int COLS = 4;
    int BUTTON_WID = 40;
    int BUTTON_HGT = 40;
    int BUTTON_SEP = 5;
    
    // These must exist for the duration otherwise
    // we get a load of random text as labels
    std::vector<std::string> buttonLab;
    
    Fl_Window* CreateGrid()
    {
        int gridwid = (BUTTON_WID + BUTTON_SEP) * COLS + BUTTON_SEP;
        int gridhgt = (BUTTON_HGT + BUTTON_SEP) * ROWS + BUTTON_SEP;
        Fl_Window* grid = new Fl_Window(gridwid, gridhgt, "GridTest");
        grid->begin();
    
        // Create the labels first - if the vector reallocates
        // the fltk widgets lose the pointers
        char tag[] = "@";
        for (int rr = 0; rr < ROWS; ++rr)
        {
            for (int cc = 0; cc < COLS; ++cc)
            {
                ++tag[0];
                buttonLab.push_back(tag);
            }
        }
    
        // Create the buttons
        int ix = -1;
        for (int ypos = BUTTON_SEP; ypos < gridhgt; ypos += (BUTTON_HGT + BUTTON_SEP))
        {
            for (int xpos = BUTTON_SEP; xpos < gridwid; xpos += (BUTTON_WID + BUTTON_SEP))
            {
                Fl_Button* button = new Fl_Button(xpos, ypos, BUTTON_WID, BUTTON_HGT, buttonLab[++ix].c_str());
            }
        }
        grid->end();
        return grid;
    }
    
    int main(int argc, char* argv[])
    {
        Fl_Window* grid = CreateGrid();
        grid->show(argc, argv);
        Fl::run();
        return 0;
    }
    

    修改 如果窗口小部件是以随机顺序创建的,则覆盖导航的最简单方法是提供自己的Fl_Group ::导航功能。这可以通过

    完成
    1. 使Fl_Group ::导航虚拟并重建FLTK。然后基于Fl_Group创建一个新的组类并覆盖导航功能。
      • 优势:无论何时更新软件包,都会有所有FLTK更新。
      • 缺点:每当获得新的FLTK时,都必须记住使Fl_Group :: navigation虚拟化。
    2. 复制Fl_Group.c和Fl_Group.h并将它们重命名为新的组类。重写导航功能。
      • 优点:无需乱搞FLTK重建。
      • 缺点:当FLTK更新时,它不会有Fl_Group更新。
    3. 将所有小部件放在这个新的小组课程中,您将掌控导航

答案 1 :(得分:0)

您想要的例程是Fl_Widget-> take_focus()