FLTK是基于回调的GUI系统,但有时我需要用户在Fl_Input小部件中输入可接受的答案,然后函数才能返回。

这似乎需要更新小部件,收集答案,然后返回答案(如果有效)。

因此,从本质上讲,我有一个名为int get_int(Fl_Input i)的函数。此函数需要不断更新Fl_Input,通过尝试将value()强制转换为int来验证内容,如果验证失败则清除Fl_Input,最后从函数返回强制转换的int。该确认应在按Enter键时进行。 (我计划还具有返回转换字符串和浮点数的函数,但它们将以相同的方式工作)

这实际上是脚本系统的一部分,FLTK是GUI。嵌入式语言正在等待从我的Fl_Input获取适当的int,但是FLTK无法更新和处理事件,因为它尚未完成主循环。我似乎无法通过普通的FLTK回调轻松完成此操作,因为它们必须返回void,并且根据从其读取的对象的上下文,我将在单一输入上进行多种类型的转换和验证。

感谢任何可以帮助我的人!

这里的编辑是我需要的一些粗略示例代码。

Embeddable Common Lisp需要包装get_int函数,但是我不确定如何使用中断更新所有小部件,以及如何通过不会直接影响循环的回调中断循环。 (也许是 bool(boolean) 型标志?)

#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <Fl/Fl_Input.H>
#include <Fl/Fl_Button.H>
#include <stdexcept>

int get_int(Fl_Input* i)
{
  int temp = 0;
  while(True)
  {

    // not sure how to update here
    // at this point, button and field need to update
    // also somehow validate needs to be done on Enter button press
    // but callbacks can't interact with this part of the code directly
    // to validate and end the loop here

    try
    {
      temp = std::stoi(i->value());
    }
    catch(...)
    {
      std::cout << "Invalid conversion to int" << i->value() << std::endl;
      i->value("");
    }
  }
  return temp;
}

void field_callback(Fl_Widget * w, void *d)
{
  // This callback simulates Embeddable Common Lisp calling wrapped get_int
  // Once a number is valid, it is converted and passed to back to Lisp
  int something = get_int((Fl_Input*)w);
  std::cout << something << std::endl;
}

int main()
{
  Fl_Window *w = new Fl_Window(200, 32);
  Fl_Input *i = new Fl_Input(0, 0, 128, 24, "");
  Fl_Button *b = new Fl_Button(128, 0, 32, 24, "Simulate Request");
  b->callback(field_callback);
  w->show();

  return(Fl::run());
}

最佳答案

在获得FLTK邮件列表的帮助后,我为那些希望做类似事情的人提供了一个示例。这只是袖手旁观,可能会在生产中使用。确保进行调试,而不是直接复制/粘贴。

#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <string>
#include <iostream>


Fl_Window* win = new Fl_Window(240, 128, "Loop n Prompt");
Fl_Button* button = new Fl_Button(5, 5, 128, 24, "Simulate Prompt");
Fl_Input* input = new Fl_Input(5, 96, 230, 24, "");
Fl_Box* prompt_msg = new Fl_Box(5, 48, 230, 24, "");

std::string get_input(const char* prompt,  Fl_Input *input)
{
  // Lock all widgets not pertaining to field here
  button->deactivate();
  prompt_msg->label(prompt);

  // Open up the input for value entry
  input->readonly(false);
  input->activate();

  while(! input->readonly())
  {
    Fl::wait();
  }

  // other groups activate here
  button->activate();

  // Have a funny feeling about c -> std::string conversion double check...
  std::string return_string = input->value();

  // Reset input and prompt to ""
  input->value("");
  prompt_msg->label("");

  return return_string;
}

void input_CB(Fl_Widget *w, void* data)
{
  Fl_Input* ptr = (Fl_Input*)w;
  ptr->readonly(true);
}

void button_CB(Fl_Widget *w, void* data)
{
  // Simulate something needing these values RIGHT NOW
  std::cout << "Got " << get_input("Please enter name", input) << std::endl;
  std::cout << "Got " << get_input("Please enter mother's name", input) << std::endl;
  std::cout << "Got " << get_input("Please enter father's name", input) << std::endl;

  // Now try a standard loop until thing
  std::string password = "";
  while(password != "password")
  {
    password = get_input("You must enter 'password'", input);
  }

  std::cout << "Nice job you answered correctly to exit the loop!" << std::endl;
}

int main()
{
  // Callback setup
  input->callback((Fl_Callback*)input_CB);
  button->callback((Fl_Callback*)button_CB);

  // Entry field does callback when enter key pressed
  input->when(FL_WHEN_ENTER_KEY_ALWAYS);

  // Show the window and all children
  win->show();
  return(Fl::run());
}

关于c++ - 具有更新/验证循环的C++ FLTK的Fl_Input数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36733529/

10-11 22:46