Flutter信号槽通信机制插件signals_slots的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter信号槽通信机制插件signals_slots的使用

pub package Contributors Forks Stargazers Issues MIT License

简介

signals_slots 是一个基于 Boost signals2 C++ 库实现的信号槽系统。信号代表具有多个目标的回调,也称为发布者或事件。信号连接到一组槽(回调接收器),当信号被“发出”时调用这些槽。

更多信息请查看 Boost signals2 库文档

此插件与 Boost 及其贡献者无关。

请注意,该库在信号组行为和使用索引而不是定义的 ‘back’ 和 ‘front’ 选项方面有所不同。Dart(JavaScript)没有析构函数,因此没有范围实现,这限制了该库的可用性。断开连接需要手动调用信号和连接。

使用方法

要在项目中使用此插件,请在 pubspec.yaml 文件中添加 signals_slots 作为依赖项。

创建信号并使用 emit

可以为任何函数签名创建信号,但应仅用于它所创建的签名。信号可用于创建槽连接,或重新连接现有槽连接。

import 'package:signals_slots/signals_slots.dart';

void main() {
  Signal0 sig = Signal0();
  sig.connect(() { print("Hello, "); });
  sig.connect(() { print("World"); });
  sig.emit(); // 输出 "Hello, World"
}

发出带参数的信号及可选结果

信号可以带有参数。每个处理信号的连接的结果将以返回列表中的任何类型提供。

import 'package:signals_slots/signals_slots.dart';

void main() {
  Signal1<String> sig = Signal1<String>();
  sig.connect((String name) { return "Hello, $name."; });
  sig.connect((String name) { return "Goodbye, $name."; });
  List<dynamic> result = sig.emit("John");
  print(result); // 输出 ["Hello, John.", "Goodbye, John."]
}

使用连接

连接是在连接到信号时返回的,或者可以在无法获取返回值的情况下创建并重新连接。连接用于跟踪槽。

import 'package:signals_slots/signals_slots.dart';

void main() {
  Signal0 sig = Signal0();
  Connection connection = sig.connect(() {});
  
  // 检查连接状态
  print(connection.isConnected());
  
  // 临时阻止信号到连接
  connection.blocked = true;
  
  connection = Connection(null, () {});
  sig.reconnect(connection);
}

断开连接和处置

连接可能在页面或其他临时实体上进行。当页面被销毁或连接失去作用域时,必须断开连接。对于信号,应调用 dispose 方法。

import 'package:signals_slots/signals_slots.dart';

void main() {
  Connection connection; // 假设已创建连接
  connection.disconnect();

  ConnectionGroup connectionGroup; // 假设已创建连接组
  connectionGroup.add(connection1);
  connectionGroup.add(connection2);
  connectionGroup.disconnectAll();
}

组和索引

信号按它们连接的顺序发送到槽,除非原始连接中包含优先级。组和索引用于实现这一点。组可以看作是优先级,索引用于在特定组内插入。

如果没有提供组,则默认使用组 0。 如果没有提供索引,则连接将插入到组的末尾。

如果提供的索引为负数,则将插入到组的开头。如果索引大于组大小,则将插入到组的末尾。

// 示例:无组和索引
String text = "";
Signal0 sig = Signal0();
sig.connect((){ text += "func1 "; });
sig.connect((){ text += "func2 "; });
sig.connect((){ text += "func3 "; });
sig.emit();
print(text); // 输出 "func1 func2 func3"

// 示例:有组和索引
text = "";
sig = Signal0();
sig.connect((){ text += "func1"; }, group: 1);
sig.connect((){ text += "func2"; });
sig.connect((){ text += "func3"; }, group: 1, insertAtIndex: 0);
sig.emit();
print(text); // 输出 "func2 func3 func1"

阻止信号和连接

信号和连接可以通过 ‘blocked’ 成员变量进行阻止。信号被阻止以防止在调用 emit 时发出。连接被阻止以防止信号执行与其订阅的槽。

import 'package:signals_slots/signals_slots.dart';

void main() {
  Signal0 sig = Signal0();
  Connection connection0 = sig.connect((){ print("slot 0"); });
  Connection connection1 = sig.connect((){ print("slot 1"); });
  sig.emit(); // 输出 "slot 0" 和 "slot 1"

  // 阻止信号示例
  sig.blocked = true;
  sig.emit(); // 无输出
  sig.blocked = false;

  // 阻止连接示例
  connection0.blocked = true;
  sig.emit(); // 仅输出 "slot 1"
}

感谢与建议

当我们从事一个项目时,我们会将任何可能对社区有益的内部库公开供免费使用。请考虑贡献,因为创建和维护此库需要付出努力。如果有改进的地方,请在项目仓库中为此创建一个问题,我们将很高兴讨论!


这个 Markdown 文档详细描述了如何在 Flutter 中使用 `signals_slots` 插件进行信号槽通信,并提供了完整的示例代码。希望这对您有所帮助!

更多关于Flutter信号槽通信机制插件signals_slots的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter信号槽通信机制插件signals_slots的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,虽然原生开发环境(如Qt)中的信号槽机制非常常见,但Flutter本身作为一个跨平台的UI框架,并没有直接提供信号槽通信机制。不过,我们可以利用Flutter的响应式编程模式以及插件机制来实现类似的功能。

signals_slots 并不是Flutter官方或广泛认知的一个插件,但我们可以基于Flutter的事件监听机制(如ValueNotifierValueListenableBuilder,或者通过自定义的事件发射器)来模拟信号槽的行为。以下是一个使用ValueNotifierValueListenableBuilder来实现信号槽通信机制的示例:

示例代码

1. 创建一个Flutter项目

首先,确保你已经有一个Flutter项目。如果没有,可以使用以下命令创建一个新的Flutter项目:

flutter create flutter_signals_slots_example
cd flutter_signals_slots_example

2. 定义信号源(类似信号发射器)

lib目录下创建一个新的Dart文件,比如signal_source.dart,用于定义信号源:

import 'package:flutter/material.dart';

class SignalSource with ChangeNotifier {
  ValueNotifier<String> _signal;

  SignalSource() {
    _signal = ValueNotifier<String>('');
  }

  ValueNotifier<String> get signal => _signal;

  void emit(String value) {
    _signal.value = value;
    notifyListeners();
  }
}

3. 使用信号源和信号槽(类似槽函数)

lib/main.dart中,我们将创建一个简单的UI来展示如何使用信号源和监听信号变化:

import 'package:flutter/material.dart';
import 'signal_source.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SignalSlotExample(),
    );
  }
}

class SignalSlotExample extends StatefulWidget {
  @override
  _SignalSlotExampleState createState() => _SignalSlotExampleState();
}

class _SignalSlotExampleState extends State<SignalSlotExample> {
  final SignalSource signalSource = SignalSource();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Signal-Slot Example'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ValueListenableBuilder<String>(
            valueListenable: signalSource.signal,
            builder: (context, value, child) {
              return Text(
                'Received Signal: $value',
                style: TextStyle(fontSize: 24),
              );
            },
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {
              signalSource.emit('Hello, Flutter!');
            },
            child: Text('Emit Signal'),
          ),
        ],
      ),
    );
  }
}

运行项目

确保你的开发环境已经配置好,然后在项目根目录下运行:

flutter run

解释

  1. SignalSource: 这个类继承自ChangeNotifier,并包含一个ValueNotifier<String>类型的私有成员_signalemit方法用于发射信号,即更新_signal的值,并通知监听器。

  2. ValueListenableBuilder: 这个组件用于监听signalSource.signal的变化,并在信号变化时更新UI。

  3. ElevatedButton: 点击按钮时,调用signalSource.emit方法发射信号。

通过这种方式,我们模拟了信号槽的通信机制。虽然Flutter没有原生的信号槽机制,但利用Flutter的响应式编程模式,我们可以轻松地实现类似的功能。

回到顶部