FLTK学习笔记3-随机点名器

  • 所需知识
    • C++ 随机数
    • FLTK中自动重复执行指令
  • 随机点名器
  • 程序示例

前面学习了基本控件以及回调函数的创建,在这里我们利用之前的知识编写一个随机点名程序。

随机点名程序应当有一个显示文本的控件用来显示被点到的人,这里我们用Fl_Input控件;还应该有一个按钮,点击后开始随机显示人名,再点击一下停止更新人名,这里我们用Fl_Button控件。

所需知识

C++ 随机数

随机点名需要产生随机数来代表被点到的人。关于C++随机数可以参考这里。本文中用以下方式产生随机数:

std::mt19937_64 engine(2020);                                    /* 定义随机数引擎,种子为2020 */
std::uniform_int_distribution<> udist(min_number, max_number);    /* 创建均匀分布 */
int random_number = udist(engine);                             /* 产生随机数 */

FLTK中自动重复执行指令

在FLTK中可以通过Fl::add_timeoutFl::repeat_timeout来实现自动重复执行指令。

Fl::add_timeout的作用是添加运行一次的回调函数,其函数原型如下,具体说明见官方文档。

void Fl::add_timeout (double t, Fl_Timeout_Handler cb, void* argp=0);

这里的t代表每t秒触发一次,cb是要重复执行的回调函数。

Fl::repeat_timeout的作用是重复运行回调函数,其函数原型如下,具体说明见官方文档。

void Fl::repeat_timeout (double t, Fl_Timeout_Handler cb, void* argp=0);

这里的tcb含义与上面一样。

因此,可以用如下代码实现自动重复执行指令:

void repeat_cb(Fl_Widget* pw, void* pv){/* some codes */Fl::repeat_timeout(repeat_cb);           /* 重复执行自身指令 */
}
int main(){/* some codes */
Fl::add_timeout(1.0/5, repeat_cb);          /* 执行repeat_cb指令 */
/* some codes */
}

在不需要重复指令时可以通过Fl::remove_timeout来终止自动重复执行。

void Fl::remove_timeout (Fl_Timeout_Handlercb, void* argp=0);

随机点名器

首先,随机点名器中需要一些全局变量来储存状态:

std::mt19937_64 engine;          /* 存储随机数产生器 */
std::vector<std::string> vs;  /* 存储点名名单 */
Fl_Input* pText;                /* 存储文本控件的地址 */

然后需要读取点名名单与产生随机数:(这里的名单是一个.txt文件,每一行是一个人名)

/* 读取点名名单 */
void loadNames(const std::string& dest){std::fstream fs;std::string name;fs.open(dest, std::ios::in);if (!fs){return;}while (std::getline(fs, name)){vs.push_back(name);}fs.close();
}
int getRandom(int min_number, int max_number){std::uniform_int_distribution<> udist(min_number, max_number);return udist(engine);
}

之后是画我们的GUI界面。整个界面非常简单,仅由一个输入框和一个按钮组成:

Fl_Double_Window* window = new Fl_Double_Window(300, 200, "随机点名测试");
pText = new Fl_Input(40, 50, 150, 30);
Fl_Button* pButton = new Fl_Button(190, 50, 70, 30, "开始点名");
window->end();

最后是写回调函数。这里我们需要三个回调函数:start_cbstop_cbrollCall_cb

初始按钮上的文字是“开始点名”,当被点击时调用第一个回调函数start_cb,其作用是将按钮上的文字变为“停止点名”,并且将按钮的回调函数变为第二个回调函数stop_cb,同时将第三个用于随机点名的回调函数rollCall_cb设为重复执行。

void start_cb(Fl_Widget* pw, void* pv){Fl_Button* o1 = (Fl_Button*)pw;o1->label("停止点名");                   /* 变更文字描述 */o1->callback(stop_cb, nullptr);          /* 改变按钮绑定的回调函数 */Fl::add_timeout(1.0/5, rollCall_cb);   /* 将点名回调函数设为重复执行 */
}

在开始点名后,按钮被点击时调用第二个回调函数stop_cb,其作用是将按钮上的文字变为“开始点名”,并且将按钮的回调函数改回第一个回调函数start_cb,同时结束第三个回调函数rollCall_cb的重复执行。

void stop_cb(Fl_Widget* pw, void* pv){Fl_Button* o1 = (Fl_Button*)pw;o1->label("开始点名");                    /* 变更文字描述 */o1->callback(start_cb, nullptr);     /* 改变按钮绑定的回调函数 */Fl::remove_timeout(rollCall_cb);       /* 结束点名回调函数的重复执行 */
}

之后是随机点名回调函数:

void rollCall_cb(void*){int i = getRandom(0, vs.size()-1);      /* 产生代表某个人的随机数 */pText->value(vs[i].c_str());            /* 将对应人名显示到输入框内 */Fl::repeat_timeout(1.0/5, rollCall_cb); /* 重复执行自身指令 */
}

程序示例

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Button.H>#include <fstream>
#include <random>
#include <string>
#include <vector>std::mt19937_64 engine(2020);   /* 存储随机数产生器 */
std::vector<std::string> vs;    /* 存储点名名单 */
Fl_Input* pText;                /* 存储文本控件的地址 */void loadNames(const std::string& dest){std::fstream fs;std::string name;fs.open(dest, std::ios::in);if (!fs){return;}while (std::getline(fs, name)){vs.push_back(name);}fs.close();
}
int getRandom(int min_number, int max_number){std::uniform_int_distribution<> udist(min_number, max_number);return udist(engine);
}void start_cb(Fl_Widget* pw, void* pv);
void stop_cb(Fl_Widget* pw, void* pv);
void rollCall_cb(void*);void start_cb(Fl_Widget* pw, void* pv){Fl_Button* o1 = (Fl_Button*)pw;o1->label("停止点名");                   /* 变更文字描述 */o1->callback(stop_cb, nullptr);         /* 改变按钮绑定的回调函数 */Fl::add_timeout(1.0/5, rollCall_cb);   /* 将点名回调函数设为重复执行 */
}
void stop_cb(Fl_Widget* pw, void* pv){Fl_Button* o1 = (Fl_Button*)pw;o1->label("开始点名");                   /* 变更文字描述 */o1->callback(start_cb, nullptr);        /* 改变按钮绑定的回调函数 */Fl::remove_timeout(rollCall_cb);        /* 结束点名回调函数的重复执行 */
}
void rollCall_cb(void*){int i = getRandom(0, vs.size()-1);      /* 产生代表某个人的随机数 */pText->value(vs[i].c_str());            /* 将对应人名显示到输入框内 */Fl::repeat_timeout(1.0/5, rollCall_cb); /* 重复执行自身指令 */
}int main(){loadNames("Names.txt");Fl_Double_Window* window = new Fl_Double_Window(300, 200, "随机点名测试");pText = new Fl_Input(40, 50, 150, 30);Fl_Button* pButton = new Fl_Button(190, 50, 70, 30, "开始点名");pButton->callback(start_cb, pText);window->end();window->show();return Fl::run();
}

这里注意在编译的时候记得加上-lfltk命令(在MSYS2上还要加上-mwindows -DWIN32 -lole32 -luuid -lcomctl32)。
运行结果:
相关链接:
专栏:FLTK
FLTK学习笔记2-回调函数
FLTK学习笔记4-在FLTK中显示图片(上)

FLTK学习笔记3-随机点名器相关推荐

  1. numpy学习笔记之随机采样函数

    numpy的随机采样函数 np.random.choice(a, size=None,replace=None, p=None) 功能:Generates a random sample from a ...

  2. SystemVerilog学习笔记5——随机约束和分布

    目录 随机约束和分布 为何需要随机? 为何需要约束? 需要随机什么? 声明随机变量的类 什么是约束? 权重分布 约束块控制 打开或关闭约束 内嵌约束 随机函数 数组约束 数组的属性约束 随机化句柄数组 ...

  3. Li‘s 影像组学视频学习笔记(10)-T检验+lasso+随机森林、Li‘s have a solution and plan.

    本笔记来源于B站Up主: 有Li 的影像组学系列教学视频 本节(10)主要介绍: T检验+lasso+随机森林 李博士借用和女朋友一起吃饭这个实例来说明:爱情和机器学习一样,复杂深奥.难以揣测. im ...

  4. [学习笔记] [机器学习] 7. 集成学习(Bagging、随机森林、Boosting、GBDT)

    视频链接 数据集下载地址:无需下载 1. 集成学习算法简介 学习目标: 了解什么是集成学习 知道机器学习中的两个核心任务 了解集成学习中的 Boosting 和 Bagging 1.1 什么是集成学习 ...

  5. 【基于CART的随机森林学习笔记】

    目录 算法描述 知识储备 举个栗子 实现代码 算法分析 资料引用 算法描述 1.随机森林是指一片森林的每棵树都表决,进而根据少数服从多数的原则决断出最后的结果.此篇以CART作为每一棵树的基本模型来说 ...

  6. java学习笔记---5

    IO流 I〇流概述: lO:输入/输出(Input/Output) 流:是一种抽象概念,是对数据传输的总称.也就是说数据在设备间的传输称为流,流的本质是数据传输IO流就是用来处理设备间数据传输问题的: ...

  7. atomic原子类实现机制_JUC学习笔记--Atomic原子类

    Atomic 原子操作类包 Atomic包 主要是在多线程环境下,无锁的进行原子操作.核心操作是基于UnSafe类实现的CAS方法 CAS CAS: compareAndSwap :传入两个值:期望值 ...

  8. 调度框架学习笔记(3)—— 集群调度框架的架构演进过程

    本章是 The evolution of cluster scheduler architectures 文章的学习笔记.这篇文章讨论了这些年调度架构是如何发展的以及为什么会这样发展. 首先介绍一下这 ...

  9. OracleDesigner学习笔记1――安装篇

    OracleDesigner学习笔记1――安装篇   QQ:King MSN:qiutianwh@msn.com Email:qqking@gmail.com 一.       前言 Oracle是当 ...

  10. 笔记 | 吴恩达Coursera Deep Learning学习笔记

    向AI转型的程序员都关注了这个号☝☝☝ 作者:Lisa Song 微软总部云智能高级数据科学家,现居西雅图.具有多年机器学习和深度学习的应用经验,熟悉各种业务场景下机器学习和人工智能产品的需求分析.架 ...

最新文章

  1. python 遍历字符串
  2. Mybatis源码解读-设计模式总结
  3. linux 编辑脚本 vi,linux中vi编辑器的练习心得
  4. 1,1 一维运动公式
  5. 165-PHP 文本替换函数str_replace(六)
  6. python getattr_python __getattr__
  7. html固定表的属性是什么,css如何固定表头
  8. WordPress 主题教程 #5c:日志元数据
  9. 技术实操丨HBase 2.X版本的元数据修复及一种数据迁移方式
  10. 《健康报》携手健康之路帮助医院医生免费搭建微官网
  11. 查询相关股票十档行情的方法
  12. IntelliJ IDEA导入maven项目
  13. @interface自定义注解
  14. 基于KELI5 新建一个STM32 project流程
  15. mac 微信不能设置代理服务器,mac微信能用但是浏览器上不了网
  16. 10个切片动作过渡PR预设
  17. 计算机键盘快速指南,MagicBook热键/功能键切换指南,快捷键介绍
  18. Win10 IE浏览器无法打开HTTPS网站的解决方法--win10专业版
  19. 32位CPU最大支持4G内存
  20. 一位MIT计算机博士对数学知识的思考

热门文章

  1. abaqus结果名称
  2. c语言自动生成邻接矩阵,01邻接矩阵的创建C语言实现
  3. OAI LTE系统搭建 -- OAI EPC
  4. 分页,在第一页不显示上一页或禁止使用上一页
  5. 水系图一般在哪里找得到_厦大赵金保团队EnSM:新型聚阴离子锌盐水凝胶电解质实现具有高择优取向沉积的超稳定、高可逆水系锌金属负极...
  6. Labelme标注软件下载安装教程
  7. Junit原生断言和hamcrest断言的不同与使用
  8. 海伊视讯布控球对接海康Ehome协议平台安装调试手册
  9. Android 编程经典200例 (pdf)资源
  10. IAR (10.10.1) 安装与破解教程