带有更新/验证循环的 C++ FLTK 的 Fl_Input 数据

Posted

技术标签:

【中文标题】带有更新/验证循环的 C++ FLTK 的 Fl_Input 数据【英文标题】:C++ FLTK's Fl_Input data with update/validate loop 【发布时间】:2016-04-20 03:54:22 【问题描述】:

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

这似乎需要更新小部件,收集答案,然后在答案有效时返回。

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

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

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

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

Embeddable Common Lisp 需要包装 get_int 函数,但我不确定如何使用中断更新所有小部件,并使用不能直接影响循环的回调中断循环。 (可能是布尔标志?)

#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 主循环没有运行。想想如何解决这个问题。 您是否尝试过使用 WHEN 指令?看看 NumericInput 我附上了一些应该解释得更好的代码。由于我不希望您拥有 Embeddable Common Lisp,因此我让按钮单击模拟了尝试从包装的 get_int 或 get_float 或 get_text 函数中获取字段值时所需的内容。都处理同一个 Fl_Input 实例。 您希望何时完成验证?如果是用户输入CR的时候,在回调前加上b->when(FL_WHEN_ENTER_KEY|FL_WHEN_NOT_CHANGED) 【参考方案1】:

在获得 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++ FLTK 的 Fl_Input 数据的主要内容,如果未能解决你的问题,请参考以下文章

C++ 错误:Fltk 中的“FL/Fl_xyz_Button.H:没有这样的文件或目录”?

如何绘制多个矩形 FLTK C++

FLTK C++ Fl_line 不画

如何在 FLTK 库中使用 Fl::awake

c++ FLTK 图像重绘

C++ FLTK FL_INPUT 检测何时按下输入然后将文本添加到 FL_TEXT_DISPLAY