Qt 5 和 Qt 6 在引入 lambda 槽后,对动态创建控件提供了更多的方便。动态创建的多类控件,可以在创建的时候就在代码内部指定槽。
1.技术背景
taskBus软件无线电平台使用一种多进程的合作框架,允许由多个非专业的开发者开发模块,基于stdio (stdin, stdout) 完成吞吐。但与GNURadio相比,缺少全局的变量控制是一个软肋。全局变量很重要,能够在模块之间同步采样率、频率、增益等重要参数。为了解决这个问题,我们利用了taskBus的广播策略。该策略在平台的管理下,可通过广播专题subject (subject_id=0xffffffffu) 交换指令。
利用广播策略,设计两条简单的指令,即可完成功能发现与参数同步。
1.1 功能声明
一个模块要告诉所有部位,自己在运行时,有哪些可操作的变量。同时,要广播的还有变量的类型、范围,取值等等。这个指令可以看做功能声明,指令类似:
或者:
当模块启动时,向所有人广播这个功能声明,以便发现相应的功能。
1.2 参数同步
一旦要进行参数同步,则由修改方发起,发给被修改方。这种修改可以是双向的,即参数使用进程如果发现参数变更,可以发起同步给界面控制台。界面控制台接到修改请求,发给参数使用进程。
指令类似:
1.3 控制台界面效果
我们要构造一个统一的控制台给用户,动态的为运行时的各个模块创建控件。动态的创建控件,需要考虑多种类型,如Combox, doublespinbox。典型的控制台界面是这样的:
2.1 页面创建
2.2 控件创建
创建控件时,我们以前很复杂,因为把多个控件的事件弄到一个槽里面:
- 创建控件
- 连接槽
- 用一个数据结构记忆控件的指针以及额外数据的映射。这样在槽里我们可以根据sender()获取额外的数据。
但现在,有了Qt lambda槽,就简单了:
2.3 实现回显逻辑
不但如此,可以进一步使用一个数据结构,记住设置控件值的函数(回显):
这样,我们在收到更新指令时,直接调用这个函数,就可以把新的值刷新到界面上了。在处理命令时,丝毫不用关心具体如何刷新控件。刷新逻辑已经在上文创建控件时指定了。
3 后记
functional+lambda表达式的关键作用有两个:
- 延迟调用。
- 变量捕获。
有了这两个功能,就可以大大节约代码长度了。
具体的完整代码参考这里:
https://gitcode.net/coloreaglestdio/taskbus/-/tree/master/modules/pannel/control_pannel
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!