首页 > 基础资料 博客日记

山外青山楼外楼 : 详解 Qt信号与槽的100种用法 (眼界篇)

2025-01-14 04:30:10基础资料围观190

Java资料网推荐山外青山楼外楼 : 详解 Qt信号与槽的100种用法 (眼界篇)这篇文章给大家,欢迎收藏Java资料网享受知识的乐趣

在 Qt 信号与槽的应用中,基于其核心机制和可扩展性,理论上有无限种组合和变种。具体来说,常见的信号与槽用法和场景应用大约可以总结出以下 100 多种主要方式,分为几个大类:


1. 基本用法(5+ 种)

  1. 直接连接:信号直接绑定到槽函数。
  2. 多信号单槽:多个信号连接到同一个槽函数。
  3. 单信号多槽:一个信号连接到多个槽函数。
  4. 信号链:信号触发另一个信号形成链式调用。
  5. 自定义信号与槽:定义自己的信号和槽函数。

2. 高级用法(20+ 种)

  1. Lambda 表达式作为槽:使用匿名函数替代传统槽函数。
  2. 函数指针作为槽:连接到普通 C++ 函数。
  3. 动态信号参数:通过 QVariant 支持动态类型参数。
  4. 信号重定向:通过中间代理转发信号。
  5. 信号参数过滤:仅传递符合条件的信号。
  6. 信号组合:多个信号合并为一个。
  7. 信号拆分:将一个信号的参数分发到多个子信号。
  8. 信号参数转换:将信号的参数进行类型或格式转换。
  9. 信号的优先级队列:通过队列管理信号的槽调用顺序。
  10. 信号广播:将信号转发给多个接收者。

3. 动态和延迟机制(15+ 种)

  1. 延迟槽执行:通过 QTimer 延迟槽函数的执行。
  2. 信号防抖(Debounce):信号停止一段时间后才触发槽。
  3. 信号节流(Throttle):限制信号触发频率。
  4. 动态信号注册:运行时动态绑定信号与槽。
  5. 懒加载信号:根据条件在需要时连接信号。
  6. 信号重连:断开旧连接并绑定到新槽。
  7. 信号的缓存重发:缓存信号数据以便稍后重发。
  8. 信号递归优化:将递归调用转为异步队列。
  9. 信号生命周期管理:自动或手动管理信号的连接与断开。
  10. 信号的异步执行:在多线程中异步调用槽函数。

4. 多线程场景(10+ 种)

  1. 跨线程信号传递:通过 Qt::QueuedConnection 实现。
  2. 线程池中的信号处理:结合 QtConcurrent 异步处理信号。
  3. 信号触发的任务调度:将信号与任务分配机制结合。
  4. 信号的线程安全优化:通过 QMutex 或线程队列管理信号。
  5. 信号的线程分发:将信号分发到特定线程。
  6. 多线程信号链:跨线程连接多个信号形成链式调用。

5. 特殊场景(25+ 种)

  1. 信号与状态机结合:用于触发状态迁移。
  2. 信号与 QML 结合:在 QML 和 C++ 之间绑定信号。
  3. 信号的条件绑定:仅当某些条件满足时触发槽。
  4. 信号的取消机制:允许信号传播到槽之前被取消。
  5. 多语言信号支持:结合 QLocale 本地化信号数据。
  6. 信号的时间限制:限制信号在特定时间内有效。
  7. 信号的日志记录:跟踪信号的触发和处理。
  8. 信号的序列化:将信号数据序列化用于网络传输。
  9. 信号的事件化处理:将信号转为标准 Qt 事件。
  10. 信号的批处理:批量收集信号数据后统一处理。

6. 工具与辅助机制(20+ 种)

  1. 信号监控工具:检测信号的触发频率和时间。
  2. 信号与槽的工具类封装:创建批量管理器。
  3. 信号的延迟队列:为信号数据提供定时队列。
  4. 信号的优先级调度工具:按优先级顺序分配槽。
  5. 信号动态生成工具:批量生成和连接信号。
  6. 信号与槽的调试工具:记录信号的所有触发历史。
  7. 信号的模块化工具:创建模块间信号桥梁。
  8. 信号与事件桥接:将信号和 Qt 事件机制结合。
  9. 信号代理工具:代理和修改信号数据。
  10. 信号的反射机制:通过元对象系统动态操作信号与槽。

7. 综合场景(10+ 种)

  1. 信号的动态拆解与合并:结合复杂对象进行信号管理。
  2. 信号与槽的图形化配置:动态连接图形控件的信号。
  3. 信号的多层次触发:通过代理实现模块化传递。
  4. 信号与实时数据绑定:与数据模型直接连接。
  5. 信号的分组绑定:为一组对象批量绑定信号。
  6. 信号与 AI/机器学习结合:触发机器学习模型预测。
  7. 信号与实时动画:控制动画的触发和停止。
  8. 信号的跨平台同步:与远程服务同步信号。
  9. 信号与日志系统整合:捕获信号以增强调试功能。
  10. 信号的负载均衡:根据槽的处理能力分配信号。

1. 自定义信号与槽

在自定义类中定义信号和槽,可以让你的类具备灵活的通信能力。

class MyClass : public QObject {
    Q_OBJECT

public:
    explicit MyClass(QObject* parent = nullptr) : QObject(parent) {}

signals:
    void mySignal(int value);  // 自定义信号

public slots:
    void mySlot(int value) {   // 自定义槽
        qDebug() << "Value received in slot:" << value;
    }
};

// 使用
MyClass obj1, obj2;
QObject::connect(&obj1, &MyClass::mySignal, &obj2, &MyClass::mySlot);
emit obj1.mySignal(42);  // 触发信号

2. Lambda 表达式作为槽

在现代 C++(C++11及以上)中,可以使用 Lambda 表达式代替传统槽函数。这对于一次性处理或简化代码非常有用。

QPushButton button("Click me");

QObject::connect(&button, &QPushButton::clicked, [](bool checked) {
    qDebug() << "Button clicked! Checked state:" << checked;
});

button.show();

3. 函数指针的使用

Qt 5 引入了基于函数指针的信号与槽连接方式,比字符串形式更加安全和高效。

QObject::connect(&button, &QPushButton::clicked, &app, &QApplication::quit);

4. 信号与槽的多线程使用

Qt 的信号与槽机制可以用于多线程编程。当信号与槽连接的对象位于不同线程时,连接的方式(ConnectionType)会默认使用 Qt::QueuedConnection

跨线程信号与槽的例子:
class Worker : public QObject {
    Q_OBJECT

public slots:
    void doWork() {
        qDebug() << "Work done in thread:" << QThread::currentThread();
    }
};

// 主线程中:
QThread* thread = new QThread;
Worker* worker = new Worker;

worker->moveToThread(thread);
QObject::connect(thread, &QThread::started, worker, &Worker::doWork);
thread->start();

5. 动态信号与槽连接

可以通过 QMetaObject::invokeMethod 实现运行时动态调用槽函数。

QObject::invokeMethod(&obj, "mySlot", Qt::QueuedConnection, Q_ARG(int, 42));

6. 信号链

将一个信号直接连接到另一个信号,可以实现信号的传递。

QObject::connect(&obj1, &MyClass::mySignal, &obj2, &MyClass::mySignal);

7. 信号与槽参数的类型转换

在某些情况下,可以在信号与槽之间传递不同类型的参数。通过中间层(如 Lambda 表达式或中间槽),可以实现类型转换。

QObject::connect(&spinBox, QOverload<int>::of(&QSpinBox::valueChanged), [](int value) {
    qDebug() << "SpinBox value changed to:" << value;
});

8. 带返回值的槽

槽函数也可以返回值,但信号不能捕获这些返回值。你可以使用 QMetaObject::invokeMethod 捕获返回值。

int result;
bool success = QMetaObject::invokeMethod(&obj, "mySlot", Q_RETURN_ARG(int, result), Q_ARG(int, 10));

if (success) {
    qDebug() << "Slot returned:" << result;
}

9. 高级连接类型

Qt 提供了多种连接方式,可通过 Qt::ConnectionType 指定:

  • Qt::AutoConnection:根据线程自动选择 DirectQueued
  • Qt::DirectConnection:槽在信号线程中直接调用。
  • Qt::QueuedConnection:信号会被放入槽所在线程的事件队列中异步调用。
  • Qt::BlockingQueuedConnection:阻塞调用,仅适用于多线程场景。
  • Qt::UniqueConnection:确保同一对信号与槽的连接只存在一次。

10. 使用信号与槽的批量连接

当有大量类似的信号需要连接到同一个槽时,可以使用循环或模板方法来实现批量连接。

QVector<QPushButton*> buttons = {button1, button2, button3};

for (auto button : buttons) {
    QObject::connect(button, &QPushButton::clicked, [button]() {
        qDebug() << "Button clicked:" << button->text();
    });
}

或者,通过模板实现动态的批量处理:

template <typename T>
void connectAll(const QVector<T*>& widgets, const char* signal, const QObject* receiver, const char* method) {
    for (auto widget : widgets) {
        QObject::connect(widget, signal, receiver, method);
    }
}

11. 动态槽绑定

在运行时根据特定条件绑定不同的槽函数,可以通过 Lambda 或 std::function 实现动态行为。

std::function<void()> dynamicSlot = []() { 
    qDebug() << "Dynamic slot executed"; 
};

// 连接信号到动态槽
QObject::connect(&button, &QPushButton::clicked, dynamicSlot);

12. 延迟信号处理

通过 QTimer::singleShot 实现对信号的延迟处理。

QObject::connect(&button, &QPushButton::clicked, []() {
    QTimer::singleShot(1000, []() {
        qDebug() << "This is a delayed slot execution.";
    });
});

13. 信号与槽的分离与重新绑定

在某些动态场景下,需要临时断开信号与槽,稍后再重新绑定,可以通过 QObject::disconnectQObject::connect 动态控制。

QObject::disconnect(sender, &SenderClass::someSignal, receiver, &ReceiverClass::someSlot);

// 条件满足时重新绑定
if (someCondition) {
    QObject::connect(sender, &SenderClass::someSignal, receiver, &ReceiverClass::someSlot);
}

14. 信号拦截与增强

可以在信号触发前后执行额外逻辑,例如添加日志、统计等。

QObject::connect(&button, &QPushButton::clicked, [&]() {
    qDebug() << "Signal intercepted before processing";
    emit button.clicked();  // 手动触发信号
    qDebug() << "Signal processed";
});

15. 信号和槽的层级管理

在复杂项目中,可能需要多个信号串联形成一个信号链。这种场景中,可以使用中间处理器类统一管理。

class SignalProcessor : public QObject {
    Q_OBJECT

public:
    explicit SignalProcessor(QObject* parent = nullptr) : QObject(parent) {}

signals:
    void processedSignal(int result);

public slots:
    void processSignal(int value) {
        int result = value * 2;  // 模拟处理逻辑
        emit processedSignal(result);
    }
};

// 使用
SignalProcessor processor;
QObject::connect(&source, &SourceClass::originalSignal, &processor, &SignalProcessor::processSignal);
QObject::connect(&processor, &SignalProcessor::processedSignal, &target, &TargetClass::targetSlot);

16. 信号与槽的调试与监控

在调试复杂项目时,可以通过以下方法监控信号与槽的行为:

  1. 安装事件过滤器
    通过自定义事件过滤器捕获信号事件。

    bool eventFilter(QObject* obj, QEvent* event) override {
        if (event->type() == QEvent::MetaCall) {
            qDebug() << "Signal emitted from" << obj;
        }
        return QObject::eventFilter(obj, event);
    }
    
  2. 使用 Qt::ConnectionType 打印连接信息

    QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName, Qt::UniqueConnection);
    qDebug() << QObject::connections(sender);
    

17. 跨模块的信号传递

在大型项目中,信号可能需要在不同模块间传递。使用 单例模式 管理公共信号,可以简化模块间通信。

class SignalBus : public QObject {
    Q_OBJECT

public:
    static SignalBus* instance() {
        static SignalBus instance;
        return &instance;
    }

signals:
    void globalSignal(int value);

private:
    SignalBus() = default;
    Q_DISABLE_COPY(SignalBus)
};

// 使用:
SignalBus::instance()->globalSignal(42);

18. 结合元对象系统动态调用槽

通过 QMetaObject 可以实现更动态的信号调用。

QObject::connect(&button, &QPushButton::clicked, [&]() {
    QMetaObject::invokeMethod(&target, "dynamicSlot", Q_ARG(int, 42));
});

19. 避免重复信号的性能优化

信号触发时,如果与大量槽连接,可能会影响性能。以下方法可优化:

  1. 去重连接
    使用 Qt::UniqueConnection 防止重复连接。

    QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName, Qt::UniqueConnection);
    
  2. 使用条件触发
    仅在需要时触发信号。

    if (conditionMet) {
        emit someSignal();
    }
    

20. 多线程环境中的信号与槽

在多线程项目中使用信号与槽时,需要注意线程安全和连接方式:

使用 Qt::BlockingQueuedConnection

确保信号发出后,接收线程处理完毕才继续执行:

QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName, Qt::BlockingQueuedConnection);
定期检查跨线程调用:

可以通过 QThread::isRunningQThread::currentThread 检查信号和槽是否处于不同线程中。


21. 自定义信号的继承

如果你的类需要从父类继承信号,可以直接通过 Q_OBJECT 宏处理,或通过子类扩展信号功能。

class Base : public QObject {
    Q_OBJECT

signals:
    void baseSignal(int value);
};

class Derived : public Base {
    Q_OBJECT

signals:
    void derivedSignal(QString message);
};

在使用时,子类对象可以发出父类和子类的信号。


22. 多参数信号与槽

信号可以携带多个参数,槽也可以选择性地接收这些参数。

class MyClass : public QObject {
    Q_OBJECT

signals:
    void complexSignal(int a, QString b, double c);

public slots:
    void simpleSlot(int a) {
        qDebug() << "Only received int:" << a;
    }
};

// 部分参数连接
QObject::connect(&obj, &MyClass::complexSignal, &obj, [](int a, QString, double) {
    qDebug() << "Received int:" << a;
});

// 全参数连接
QObject::connect(&obj, &MyClass::complexSignal, &obj, [](int a, QString b, double c) {
    qDebug() << "Received all params:" << a << b << c;
});

23. 信号与槽的弱绑定

为了避免对象销毁后信号仍触发的问题,可以使用弱绑定技术。

QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName, Qt::UniqueConnection);
QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName, Qt::AutoConnection);

// 检查是否接收器依然有效
if (!receiver->isWidgetType()) {
    qDebug() << "Receiver no longer exists!";
}

24. 信号分发与聚合

信号可以被转发到多个对象,或者从多个信号聚合为一个信号。

信号分发
QObject::connect(source, &SourceClass::someSignal, receiver1, &ReceiverClass::slot1);
QObject::connect(source, &SourceClass::someSignal, receiver2, &ReceiverClass::slot2);
信号聚合

使用中间类统一处理多个信号,生成一个总信号。

class SignalAggregator : public QObject {
    Q_OBJECT

signals:
    void aggregatedSignal(int value);

public slots:
    void onSignal1(int value) { emit aggregatedSignal(value); }
    void onSignal2(int value) { emit aggregatedSignal(value * 2); }
};

25. 信号的分组管理

在大型应用中,可以通过为信号分组管理,提高代码的清晰度和可维护性。例如,使用 std::map 保存连接信息:

std::map<QString, QList<QMetaObject::Connection>> connectionGroups;

// 记录连接
connectionGroups["group1"].append(QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName));

// 断开特定组的所有连接
for (auto connection : connectionGroups["group1"]) {
    QObject::disconnect(connection);
}
connectionGroups["group1"].clear();

26. 信号队列优化

对于高频信号,可以优化处理方式避免性能问题:

  • 合并信号:避免频繁触发。

    QTimer* timer = new QTimer(this);
    timer->setInterval(100); // 每 100 毫秒触发一次
    connect(timer, &QTimer::timeout, [&]() {
        qDebug() << "Batch signal processed.";
    });
    timer->start();
    
  • 批量信号处理
    可以通过队列收集信号数据,并在槽中统一处理。

    QVector<int> signalQueue;
    
    connect(sender, &SenderClass::someSignal, [&signalQueue](int value) {
        signalQueue.append(value);
    });
    
    QTimer::singleShot(100, [&]() {
        qDebug() << "Processing signal queue:" << signalQueue;
        signalQueue.clear();
    });
    

27. 阻塞信号

在特定情况下,你可能需要暂时阻止信号的传播。可以通过 blockSignals 实现。

QObject* obj = new QObject(this);
obj->blockSignals(true);  // 阻止信号传播

emit obj->someSignal();   // 不会触发槽

obj->blockSignals(false); // 恢复信号传播

28. 信号与槽的调试工具

为了更好地调试复杂场景中的信号与槽,可以使用以下工具和技术:

使用 Qt 自带的调试功能
qDebug() << QObject::connections(sender);
自定义日志记录

通过 qInstallMessageHandler 捕获信号与槽的调试输出。

void customMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) {
    QFile file("debug.log");
    if (file.open(QIODevice::Append)) {
        QTextStream stream(&file);
        stream << msg << endl;
    }
}

qInstallMessageHandler(customMessageHandler);

29. 性能监控

信号与槽在大规模项目中可能会导致性能瓶颈,特别是高频信号。以下是优化方法:

  1. 减少信号触发频率
    信号的频繁触发可能导致性能下降,可以通过计时器或批量处理降低频率。

  2. 移除未使用的连接
    定期检查未使用或重复的信号连接,避免浪费资源。


30. 信号与槽的动态注册

对于动态生成的对象,可以使用 Qt 的元对象系统动态注册信号和槽。

QObject* dynamicObject = new QObject();
QMetaObject::invokeMethod(dynamicObject, "dynamicSlot", Q_ARG(int, 42));

31. 信号的条件触发

信号的触发可以根据特定条件动态决定,这可以避免不必要的开销。

if (conditionMet) {
    emit mySignal();
} else {
    qDebug() << "Signal not emitted due to unmet conditions.";
}

32. 信号的队列传递(Queued Signal)

信号可以在事件队列中排队,通过 Qt::QueuedConnection 强制异步传递信号。

QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName, Qt::QueuedConnection);

以下是 Qt 信号与槽机制的更高级应用技巧和一些特殊场景的解决方案,包括动态场景、跨模块通信、性能优化及自定义工具开发等内容:


33. 信号与槽的优先级

在某些场景中,你可能希望槽函数按优先级执行。虽然 Qt 信号与槽机制本身不支持优先级,但可以通过中间管理器实现。

实现方法:
  1. 使用 std::priority_queuestd::map 存储优先级。
  2. 创建中间层槽,按优先级调用实际槽函数。
#include <QMap>

class PriorityDispatcher : public QObject {
    Q_OBJECT

public:
    void addSlot(int priority, std::function<void()> slot) {
        slots.insert(priority, slot);
    }

public slots:
    void dispatch() {
        for (auto it = slots.begin(); it != slots.end(); ++it) {
            it.value()(); // 按优先级执行槽
        }
    }

private:
    QMap<int, std::function<void()>> slots;
};

// 使用
PriorityDispatcher dispatcher;
dispatcher.addSlot(1, [] { qDebug() << "Low-priority slot"; });
dispatcher.addSlot(0, [] { qDebug() << "High-priority slot"; });
QObject::connect(&button, &QPushButton::clicked, &dispatcher, &PriorityDispatcher::dispatch);

34. 动态创建对象的信号与槽连接

当对象是动态创建的,需要在运行时连接其信号与槽,可以使用工厂模式或 QList 动态管理对象。

QList<QPushButton*> buttons;

for (int i = 0; i < 5; ++i) {
    QPushButton* button = new QPushButton(QString("Button %1").arg(i));
    buttons.append(button);

    QObject::connect(button, &QPushButton::clicked, [button]() {
        qDebug() << "Clicked:" << button->text();
    });
}

35. 信号的反向连接(Back-propagation)

有时候,需要通过信号实现 “反向传播” 数据。例如,子模块处理后需要通知父模块结果。

class Parent : public QObject {
    Q_OBJECT
public slots:
    void onChildSignal(int result) {
        qDebug() << "Child signal received with result:" << result;
    }
};

class Child : public QObject {
    Q_OBJECT

signals:
    void processed(int result);

public:
    void doSomething() {
        int result = 42; // 模拟计算
        emit processed(result);
    }
};

// 使用
Parent parent;
Child child;

QObject::connect(&child, &Child::processed, &parent, &Parent::onChildSignal);
child.doSomething();

36. 跨模块信号与槽的解耦

在大型项目中,模块之间的信号与槽可能导致强耦合,可以通过以下方式解耦:

使用中介者模式

通过中介者对象转发信号。

class Mediator : public QObject {
    Q_OBJECT

signals:
    void moduleSignal(QString data);

public slots:
    void onModule1Signal(QString data) { emit moduleSignal(data); }
    void onModule2Signal(QString data) { emit moduleSignal(data); }
};

// 模块间通信
Mediator mediator;
QObject::connect(module1, &Module1::signal1, &mediator, &Mediator::onModule1Signal);
QObject::connect(module2, &Module2::signal2, &mediator, &Mediator::onModule2Signal);
QObject::connect(&mediator, &Mediator::moduleSignal, [](QString data) {
    qDebug() << "Unified signal received:" << data;
});

37. 使用信号与槽实现事件总线

事件总线是一种消息分发机制,可以通过信号与槽实现。

class EventBus : public QObject {
    Q_OBJECT

public:
    static EventBus* instance() {
        static EventBus bus;
        return &bus;
    }

signals:
    void eventOccurred(QString event);

private:
    EventBus() = default;
};

// 使用
EventBus::instance()->eventOccurred("Test Event");
QObject::connect(EventBus::instance(), &EventBus::eventOccurred, [](QString event) {
    qDebug() << "Event received:" << event;
});

38. 信号连接到多个槽的负载均衡

如果需要将信号分发到多个槽,且希望按负载均衡的方式选择槽,可以通过记录每个槽的调用次数来实现。

class LoadBalancer : public QObject {
    Q_OBJECT
public:
    void addSlot(std::function<void()> slot) {
        slots.append({slot, 0});
    }

    void dispatch() {
        // 按调用次数最少的槽执行
        auto minSlot = std::min_element(slots.begin(), slots.end(), [](const SlotInfo& a, const SlotInfo& b) {
            return a.callCount < b.callCount;
        });
        minSlot->slot();
        ++minSlot->callCount;
    }

private:
    struct SlotInfo {
        std::function<void()> slot;
        int callCount = 0;
    };

    QVector<SlotInfo> slots;
};

// 使用
LoadBalancer balancer;
balancer.addSlot([] { qDebug() << "Slot 1"; });
balancer.addSlot([] { qDebug() << "Slot 2"; });
QObject::connect(&button, &QPushButton::clicked, [&]() { balancer.dispatch(); });

39. 在静态方法中使用信号与槽

Qt 信号与槽默认依赖于 QObject 的实例,但通过 std::function 或函数指针,也可以在静态上下文中使用。

class StaticHandler {
public:
    static void handleSignal() {
        qDebug() << "Static method called!";
    }
};

// 连接静态方法
QObject::connect(&button, &QPushButton::clicked, &StaticHandler::handleSignal);

40. 信号与槽的依赖注入

通过依赖注入(Dependency Injection),将信号与槽的连接管理分离到配置层。

class SignalConnector {
public:
    static void connect(QObject* sender, const char* signal, QObject* receiver, const char* slot) {
        QObject::connect(sender, signal, receiver, slot);
    }
};

// 配置层
SignalConnector::connect(&button, SIGNAL(clicked()), &app, SLOT(quit()));

41. 在 QML 中使用信号与槽

在基于 QML 的项目中,可以使用 Connections 类型实现信号与槽的绑定。

import QtQuick 2.0

Rectangle {
    width: 200
    height: 200

    signal customSignal(int value)

    Connections {
        target: parent
        onCustomSignal: {
            console.log("Signal received with value:", value);
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: customSignal(42)
    }
}

42. 测试信号与槽

为了测试信号是否正常触发,可以使用 QSignalSpy

QSignalSpy spy(&object, &ObjectClass::signalName);

// 触发信号
emit object.signalName();

// 检查信号是否被触发
QCOMPARE(spy.count(), 1);


43. 动态信号与槽参数类型

在某些场景下,信号与槽的参数类型可能在运行时动态变化。可以通过 QVariant 实现参数的动态解析。

class DynamicSignalEmitter : public QObject {
    Q_OBJECT

signals:
    void dynamicSignal(QVariant data);

public:
    void emitSignal(const QVariant& value) {
        emit dynamicSignal(value);
    }
};

class DynamicSlotHandler : public QObject {
    Q_OBJECT

public slots:
    void handleDynamicSignal(QVariant data) {
        if (data.canConvert<int>()) {
            qDebug() << "Received int:" << data.toInt();
        } else if (data.canConvert<QString>()) {
            qDebug() << "Received QString:" << data.toString();
        } else {
            qDebug() << "Unknown data type.";
        }
    }
};

// 使用
DynamicSignalEmitter emitter;
DynamicSlotHandler handler;

QObject::connect(&emitter, &DynamicSignalEmitter::dynamicSignal, &handler, &DynamicSlotHandler::handleDynamicSignal);
emitter.emitSignal(42);
emitter.emitSignal("Hello, QVariant!");

44. 信号与槽的延迟初始化

在某些场景下,信号与槽的连接可能依赖于运行时环境,可以使用延迟初始化技术。

void setupConnections(QObject* sender, QObject* receiver) {
    QMetaObject::invokeMethod(receiver, [sender, receiver]() {
        QObject::connect(sender, SIGNAL(dynamicSignal()), receiver, SLOT(dynamicSlot()));
        qDebug() << "Connections initialized at runtime.";
    });
}

45. 信号强制广播

通过 QMetaObject::invokeMethod,可以模拟一个广播信号,强制所有接收者调用槽。

class GlobalBroadcaster : public QObject {
    Q_OBJECT

public:
    void broadcastSignal(const QString& message) {
        for (QObject* obj : QObject::children()) {
            QMetaObject::invokeMethod(obj, "onBroadcast", Q_ARG(QString, message));
        }
    }
};

// 使用
class Receiver : public QObject {
    Q_OBJECT
public slots:
    void onBroadcast(const QString& message) {
        qDebug() << "Received broadcast:" << message;
    }
};

GlobalBroadcaster broadcaster;
Receiver receiver1, receiver2;

broadcaster.broadcastSignal("Hello to all receivers!");

46. 组合信号与槽

在某些复杂场景下,可以组合多个信号为一个输出信号,类似于流式处理。

class SignalCombiner : public QObject {
    Q_OBJECT

signals:
    void combinedSignal(QString result);

public:
    void setInputSignals(QObject* sender1, QObject* sender2) {
        QObject::connect(sender1, SIGNAL(signalA(QString)), this, SLOT(processSignal1(QString)));
        QObject::connect(sender2, SIGNAL(signalB(int)), this, SLOT(processSignal2(int)));
    }

private slots:
    void processSignal1(const QString& str) {
        buffer1 = str;
        tryCombine();
    }

    void processSignal2(int num) {
        buffer2 = num;
        tryCombine();
    }

    void tryCombine() {
        if (!buffer1.isEmpty() && buffer2 != -1) {
            emit combinedSignal(QString("%1-%2").arg(buffer1).arg(buffer2));
        }
    }

private:
    QString buffer1;
    int buffer2 = -1;
};

47. 信号与槽链式调用

通过链式调用,可以实现多个信号的串联。例如:

QObject::connect(sender1, &SenderClass::signal1, sender2, &SenderClass::signal2);
QObject::connect(sender2, &SenderClass::signal2, receiver, &ReceiverClass::slot);

这可以用于构建复杂的信号链,方便事件流的追踪。


48. 线程安全的信号与槽

在多线程环境中,信号与槽可能涉及线程同步问题。以下是一些实现方式:

使用 Qt::QueuedConnection 自动处理线程间通信
QObject::connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot, Qt::QueuedConnection);
使用 QMutex 保证线程安全
QMutex mutex;

QObject::connect(sender, &SenderClass::signal, [&]() {
    QMutexLocker locker(&mutex);
    // 线程安全的操作
});

49. 批量断开信号与槽

在动态场景中,可能需要批量断开某些信号与槽。以下是实现方法:

QList<QMetaObject::Connection> connections;

connections.append(QObject::connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot));

// 批量断开
for (const QMetaObject::Connection& conn : connections) {
    QObject::disconnect(conn);
}
connections.clear();

50. 信号与槽的性能分析

在大型项目中,频繁触发信号可能导致性能瓶颈,可以通过以下方法优化:

  1. 减少信号触发的频率

    • 合并信号(批量处理事件)。
    • 仅在必要时触发信号。
  2. 使用 QSignalSpy 分析信号触发次数

    QSignalSpy spy(sender, &SenderClass::signal);
    emit sender->signal();
    qDebug() << "Signal emitted" << spy.count() << "times.";
    
  3. 避免重复连接
    使用 Qt::UniqueConnection 确保信号与槽的连接唯一性。


51. 信号与槽的脚本化支持

在动态环境中,使用 Qt 的脚本模块(如 QJSEngine)可以动态处理信号与槽:

QJSEngine engine;
QObject::connect(sender, &SenderClass::signal, [&]() {
    QJSValue func = engine.evaluate("(function() { console.log('Signal received'); })");
    func.call();
});

52. 延迟槽触发

为了延迟槽的执行,可以结合 QTimer 和信号与槽:

QObject::connect(sender, &SenderClass::signal, [&]() {
    QTimer::singleShot(500, [&]() {
        qDebug() << "Delayed slot executed.";
    });
});

53. 结合元对象系统进行信号重定向

通过 QMetaObject::invokeMethod,实现信号的动态重定向。

QObject::connect(sender, &SenderClass::signal, [&](int value) {
    QMetaObject::invokeMethod(receiver, "dynamicSlot", Q_ARG(int, value));
});

54. QML 与 C++ 的信号与槽交互

通过 QML 定义信号,并在 C++ 中绑定槽函数:

QML 侧:
Rectangle {
    signal customSignal(string message)
    MouseArea {
        anchors.fill: parent
        onClicked: customSignal("Hello from QML!")
    }
}
C++ 侧:
QObject::connect(qmlObject, SIGNAL(customSignal(QString)), receiver, SLOT(handleSignal(QString)));

以下是 Qt 信号与槽机制更高级的实践与拓展,深入探索其在各种应用场景中的用法,进一步帮助您掌握和优化 Qt 项目中的通信机制。


55. 信号与槽的动态注册与反射机制

通过 QObject::metaObjectQMetaObject,可以动态解析信号和槽的名称,实现运行时注册。

动态注册信号与槽:
QObject::connect(sender, sender->metaObject()->method(sender->metaObject()->indexOfSignal("signalName()")),
                 receiver, receiver->metaObject()->method(receiver->metaObject()->indexOfSlot("slotName()")));
动态遍历信号与槽:
const QMetaObject* meta = sender->metaObject();
for (int i = 0; i < meta->methodCount(); ++i) {
    QMetaMethod method = meta->method(i);
    if (method.methodType() == QMetaMethod::Signal) {
        qDebug() << "Signal found:" << method.name();
    }
}

56. 信号连接到非 QObject 的函数

虽然信号默认需要连接到继承自 QObject 的槽函数,但可以通过函数指针和 std::function 连接到普通函数或 Lambda 表达式。

void globalFunction(int value) {
    qDebug() << "Global function called with value:" << value;
}

QObject::connect(sender, &SenderClass::signalName, globalFunction);

或者使用 std::bind 和捕获参数:

QObject::connect(sender, &SenderClass::signalName, std::bind(&globalFunction, std::placeholders::_1));

57. 信号参数的自动转换

通过中间层或 Lambda 实现信号参数的自动类型转换。

QObject::connect(sender, &SenderClass::intSignal, [](int value) {
    QString converted = QString::number(value);
    qDebug() << "Converted value:" << converted;
});

或者通过额外的转换层:

class Converter : public QObject {
    Q_OBJECT

signals:
    void stringSignal(QString value);

public slots:
    void convert(int value) {
        emit stringSignal(QString::number(value));
    }
};

// 使用
Converter converter;
QObject::connect(sender, &SenderClass::intSignal, &converter, &Converter::convert);
QObject::connect(&converter, &Converter::stringSignal, receiver, &ReceiverClass::stringSlot);

58. 信号与槽的链式触发优化

通过事件流优化信号与槽的链式触发,避免性能瓶颈。

QObject::connect(sender, &SenderClass::signalA, [&](int value) {
    qDebug() << "Step 1 with value:" << value;
    emit sender->signalB(value * 2);
});

QObject::connect(sender, &SenderClass::signalB, [&](int value) {
    qDebug() << "Step 2 with value:" << value;
});

这种方式减少了槽函数中的复杂逻辑,分布式处理事件。


59. 信号与槽的生命周期管理

信号与槽的连接会随着对象销毁而断开,但在复杂场景中,手动管理生命周期更安全。

自动管理生命周期:
QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName, Qt::AutoConnection);
手动管理:
QMetaObject::Connection connection = QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);

// 断开特定连接
QObject::disconnect(connection);

60. 信号与槽的批量管理工具

开发一个通用工具类管理信号与槽的批量连接和断开。

class SignalManager {
    QList<QMetaObject::Connection> connections;

public:
    void addConnection(QMetaObject::Connection connection) {
        connections.append(connection);
    }

    void disconnectAll() {
        for (const auto& conn : connections) {
            QObject::disconnect(conn);
        }
        connections.clear();
    }
};

// 使用
SignalManager manager;
manager.addConnection(QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName));
manager.disconnectAll();

61. 信号与槽的性能监控工具

实现一个工具类监控信号的触发频率与延迟。

class SignalProfiler : public QObject {
    Q_OBJECT

    QElapsedTimer timer;

public slots:
    void profileSignal() {
        qint64 elapsed = timer.restart();
        qDebug() << "Signal triggered after" << elapsed << "ms";
    }
};

// 使用
SignalProfiler profiler;
profiler.timer.start();

QObject::connect(sender, &SenderClass::signalName, &profiler, &SignalProfiler::profileSignal);

62. 结合模板实现泛型信号与槽管理

通过模板实现对信号与槽的泛型管理。

template <typename SignalType, typename SlotType>
void connectSignals(SignalType signal, SlotType slot) {
    QObject::connect(signal, slot);
}

// 使用
connectSignals(&SenderClass::signalName, &ReceiverClass::slotName);

63. 信号与槽的日志记录

在调试环境中记录所有信号的触发情况,帮助分析程序运行过程。

class SignalLogger : public QObject {
    Q_OBJECT

public slots:
    void logSignal(QString signalName) {
        qDebug() << "Signal triggered:" << signalName;
    }
};

// 使用
SignalLogger logger;
QObject::connect(sender, &SenderClass::signalName, [&logger]() {
    logger.logSignal("signalName");
});

64. 信号与槽的序列化与网络传输

在分布式系统中,信号与槽可以用于跨网络通信,信号数据可以序列化后通过 QNetwork 模块传输。

class SignalNetworkBridge : public QObject {
    Q_OBJECT

signals:
    void remoteSignal(QByteArray data);

public:
    void sendSignalOverNetwork(int value) {
        QByteArray data;
        QDataStream stream(&data, QIODevice::WriteOnly);
        stream << value;
        emit remoteSignal(data);
    }

public slots:
    void receiveSignal(QByteArray data) {
        QDataStream stream(data);
        int value;
        stream >> value;
        qDebug() << "Received value over network:" << value;
    }
};

65. 结合状态机管理信号与槽

在复杂项目中,信号可以与状态机结合,用于触发状态切换。

QStateMachine machine;
QState* state1 = new QState();
QState* state2 = new QState();

state1->addTransition(sender, &SenderClass::signalName, state2);
state2->addTransition(sender, &SenderClass::signalName, state1);

machine.addState(state1);
machine.addState(state2);
machine.setInitialState(state1);
machine.start();

66. 通过 std::optional 实现信号延迟处理

使用 std::optional 缓存信号数据,延迟执行槽函数。

std::optional<int> cachedSignalValue;

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    cachedSignalValue = value;
});

if (cachedSignalValue) {
    qDebug() << "Delayed execution with value:" << cachedSignalValue.value();
}

67. 使用信号优先级队列

通过优先级队列实现信号的动态调度,使某些信号比其他信号具有更高的优先级。

实现:
#include <QQueue>
#include <QPair>

class SignalScheduler : public QObject {
    Q_OBJECT

private:
    QQueue<QPair<int, std::function<void()>>> signalQueue;

public slots:
    void scheduleSignal(int priority, std::function<void()> callback) {
        signalQueue.enqueue(qMakePair(priority, callback));
        processQueue();
    }

private:
    void processQueue() {
        while (!signalQueue.isEmpty()) {
            auto task = signalQueue.dequeue();
            task.second();  // 执行回调函数
        }
    }
};

// 使用
SignalScheduler scheduler;

QObject::connect(sender, &SenderClass::signalName, [&]() {
    scheduler.scheduleSignal(1, []() { qDebug() << "High-priority signal"; });
    scheduler.scheduleSignal(2, []() { qDebug() << "Low-priority signal"; });
});

68. 信号触发的条件绑定

通过条件绑定,只有当某些条件满足时,信号才触发相应的槽。

QObject::connect(sender, &SenderClass::signalName, [&]() {
    if (someCondition) {
        qDebug() << "Condition met, executing slot";
    } else {
        qDebug() << "Condition not met, skipping slot";
    }
});

或者封装条件检查:

class ConditionalSlot : public QObject {
    Q_OBJECT

public:
    ConditionalSlot(std::function<bool()> condition, std::function<void()> action)
        : condition(condition), action(action) {}

public slots:
    void execute() {
        if (condition()) {
            action();
        }
    }

private:
    std::function<bool()> condition;
    std::function<void()> action;
};

// 使用
ConditionalSlot* slot = new ConditionalSlot(
    []() { return someCondition; },
    []() { qDebug() << "Condition met, performing action"; });

QObject::connect(sender, &SenderClass::signalName, slot, &ConditionalSlot::execute);

69. 跨线程信号调度

对于多线程程序,可以通过信号调度器优化跨线程通信。

使用 QThreadQt::QueuedConnection
QThread* thread = new QThread();
Worker* worker = new Worker();
worker->moveToThread(thread);

QObject::connect(thread, &QThread::started, worker, &Worker::doWork);
QObject::connect(worker, &Worker::finished, thread, &QThread::quit);
QObject::connect(worker, &Worker::finished, worker, &QObject::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);

thread->start();
自定义线程信号调度器:
class ThreadSignalDispatcher : public QObject {
    Q_OBJECT

public:
    void dispatchToThread(QObject* target, std::function<void()> callback) {
        QMetaObject::invokeMethod(target, [callback]() { callback(); }, Qt::QueuedConnection);
    }
};

// 使用
ThreadSignalDispatcher dispatcher;

dispatcher.dispatchToThread(targetObject, []() {
    qDebug() << "This is executed in another thread.";
});

70. 信号批处理

在某些场景下,信号频繁触发可能带来性能问题,通过批量处理优化性能。

示例:
QList<int> signalBuffer;

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    signalBuffer.append(value);
    if (signalBuffer.size() >= batchSize) {
        qDebug() << "Processing batch:" << signalBuffer;
        signalBuffer.clear();
    }
});

71. 信号的链式处理

使用信号链实现数据流式传递,类似于函数式编程的管道。

示例:
QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    int step1 = value * 2;
    emit sender->signalStep2(step1);
});

QObject::connect(sender, &SenderClass::signalStep2, [&](int step1Result) {
    int step2 = step1Result + 10;
    qDebug() << "Final result:" << step2;
});

72. 信号延迟传递

通过延迟将信号放入事件队列,从而避免阻塞当前操作。

使用 QTimer::singleShot 延迟信号:
QObject::connect(sender, &SenderClass::signalName, [&]() {
    QTimer::singleShot(100, []() {
        qDebug() << "Delayed execution.";
    });
});
自定义延迟队列:
class DelayedSignalQueue : public QObject {
    Q_OBJECT

public:
    void enqueueSignal(std::function<void()> callback, int delay) {
        QTimer::singleShot(delay, [callback]() { callback(); });
    }
};

// 使用
DelayedSignalQueue queue;
queue.enqueueSignal([]() { qDebug() << "Delayed action."; }, 500);

73. 信号的中间代理

使用代理类拦截和修改信号的传递。

class SignalInterceptor : public QObject {
    Q_OBJECT

signals:
    void interceptedSignal(int modifiedValue);

public slots:
    void intercept(int value) {
        emit interceptedSignal(value * 2);  // 修改参数后重新发出信号
    }
};

// 使用
SignalInterceptor interceptor;
QObject::connect(sender, &SenderClass::signalName, &interceptor, &SignalInterceptor::intercept);
QObject::connect(&interceptor, &SignalInterceptor::interceptedSignal, receiver, &ReceiverClass::slot);

74. 信号调试工具

创建工具类,用于监控和记录信号触发的时间与频率。

class SignalMonitor : public QObject {
    Q_OBJECT

public:
    SignalMonitor(QObject* parent = nullptr) : QObject(parent) {}

public slots:
    void logSignal(const QString& signalName) {
        qDebug() << "Signal triggered:" << signalName << "at" << QDateTime::currentDateTime();
    }
};

// 使用
SignalMonitor monitor;
QObject::connect(sender, &SenderClass::signalName, [&]() {
    monitor.logSignal("signalName");
});

75. 动态槽绑定

允许在运行时绑定不同的槽函数,根据上下文灵活处理。

QMap<QString, std::function<void(int)>> dynamicSlots;

dynamicSlots["action1"] = [](int value) { qDebug() << "Action 1 executed with value:" << value; };
dynamicSlots["action2"] = [](int value) { qDebug() << "Action 2 executed with value:" << value; };

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    QString currentAction = determineAction();  // 动态决定当前行为
    if (dynamicSlots.contains(currentAction)) {
        dynamicSlots[currentAction](value);
    }
});

76. 信号触发频率限制

当信号触发过于频繁时,可以通过限流器实现频率控制。

class SignalRateLimiter : public QObject {
    Q_OBJECT

    QElapsedTimer timer;
    int minInterval;

public:
    explicit SignalRateLimiter(int interval, QObject* parent = nullptr)
        : QObject(parent), minInterval(interval) {
        timer.start();
    }

public slots:
    void rateLimitedSlot(int value) {
        if (timer.elapsed() >= minInterval) {
            qDebug() << "Signal processed with value:" << value;
            timer.restart();
        }
    }
};

// 使用
SignalRateLimiter limiter(100);  // 最小间隔 100 毫秒
QObject::connect(sender, &SenderClass::signalName, &limiter, &SignalRateLimiter::rateLimitedSlot);

77. 信号触发的节流与防抖

信号触发频繁可能导致性能下降,可以通过节流和防抖技术优化。

节流(Throttle):

限制信号触发的频率。

class Throttler : public QObject {
    Q_OBJECT

    QElapsedTimer timer;
    int interval;

public:
    Throttler(int throttleInterval, QObject* parent = nullptr)
        : QObject(parent), interval(throttleInterval) {
        timer.start();
    }

public slots:
    void handleSignal() {
        if (timer.elapsed() >= interval) {
            timer.restart();
            qDebug() << "Signal processed.";
        } else {
            qDebug() << "Signal ignored due to throttling.";
        }
    }
};

// 使用
Throttler throttler(500);  // 500 毫秒节流
QObject::connect(sender, &SenderClass::signalName, &throttler, &Throttler::handleSignal);
防抖(Debounce):

仅在信号停止一段时间后才触发槽。

class Debouncer : public QObject {
    Q_OBJECT

    QTimer timer;

public:
    Debouncer(int debounceInterval, QObject* parent = nullptr) : QObject(parent) {
        timer.setInterval(debounceInterval);
        timer.setSingleShot(true);

        connect(&timer, &QTimer::timeout, this, &Debouncer::processSignal);
    }

public slots:
    void handleSignal() {
        timer.start();
    }

signals:
    void signalProcessed();

private slots:
    void processSignal() {
        emit signalProcessed();
    }
};

// 使用
Debouncer debouncer(300);  // 300 毫秒防抖
QObject::connect(sender, &SenderClass::signalName, &debouncer, &Debouncer::handleSignal);
QObject::connect(&debouncer, &Debouncer::signalProcessed, receiver, &ReceiverClass::slot);

78. 信号与槽的优先级处理

在复杂场景中,不同槽可能需要不同的优先级。可以使用 QQueue 实现自定义优先级。

class PrioritySignalHandler : public QObject {
    Q_OBJECT

    QMap<int, QList<std::function<void()>>> priorityQueue;

public:
    void addHandler(int priority, std::function<void()> handler) {
        priorityQueue[priority].append(handler);
    }

    void executeHandlers() {
        for (auto it = priorityQueue.begin(); it != priorityQueue.end(); ++it) {
            for (const auto& handler : it.value()) {
                handler();
            }
        }
    }
};

// 使用
PrioritySignalHandler handler;

handler.addHandler(1, [] { qDebug() << "Low priority task"; });
handler.addHandler(0, [] { qDebug() << "High priority task"; });

QObject::connect(sender, &SenderClass::signalName, &handler, &PrioritySignalHandler::executeHandlers);

79. 基于事件的信号调度

通过自定义事件机制处理信号,而非直接调用槽。

class SignalEvent : public QEvent {
public:
    static const QEvent::Type EventType;

    explicit SignalEvent(const QString& message) : QEvent(EventType), message(message) {}

    QString message;
};

const QEvent::Type SignalEvent::EventType = static_cast<QEvent::Type>(QEvent::User + 1);

class EventHandler : public QObject {
    Q_OBJECT

protected:
    bool event(QEvent* e) override {
        if (e->type() == SignalEvent::EventType) {
            auto* signalEvent = static_cast<SignalEvent*>(e);
            qDebug() << "Handled event with message:" << signalEvent->message;
            return true;
        }
        return QObject::event(e);
    }
};

// 使用
EventHandler handler;
QCoreApplication::postEvent(&handler, new SignalEvent("Hello from event system"));

80. 信号转发机制

在模块化设计中,可以通过转发机制将信号从一个对象传递到另一个对象。

class SignalForwarder : public QObject {
    Q_OBJECT

public:
    SignalForwarder(QObject* parent = nullptr) : QObject(parent) {}

signals:
    void forwardedSignal(int value);

public slots:
    void forwardSignal(int value) {
        emit forwardedSignal(value);
    }
};

// 使用
SignalForwarder forwarder;

QObject::connect(sender, &SenderClass::signalName, &forwarder, &SignalForwarder::forwardSignal);
QObject::connect(&forwarder, &SignalForwarder::forwardedSignal, receiver, &ReceiverClass::slot);

81. 带有上下文信息的信号

通过包装器向信号添加上下文信息,便于调试或扩展。

class ContextualSignalEmitter : public QObject {
    Q_OBJECT

public:
    void emitSignalWithContext(int value, const QString& context) {
        emit signalWithContext(value, context);
    }

signals:
    void signalWithContext(int value, const QString& context);
};

// 使用
ContextualSignalEmitter emitter;

QObject::connect(&emitter, &ContextualSignalEmitter::signalWithContext, [](int value, const QString& context) {
    qDebug() << "Received signal:" << value << "with context:" << context;
});

emitter.emitSignalWithContext(42, "Data Processing Module");

82. 信号日志记录

开发日志记录工具,用于捕获和保存信号的触发历史。

class SignalLogger : public QObject {
    Q_OBJECT

    QStringList log;

public slots:
    void logSignal(const QString& signalName) {
        log.append(signalName + " at " + QDateTime::currentDateTime().toString());
    }

    void printLog() {
        for (const QString& entry : log) {
            qDebug() << entry;
        }
    }
};

// 使用
SignalLogger logger;

QObject::connect(sender, &SenderClass::signalName, [&]() {
    logger.logSignal("signalName");
});
logger.printLog();

83. 多条件信号触发

当多个信号需要组合满足某些条件时再触发,可以使用布尔逻辑实现多条件绑定。

class MultiConditionTrigger : public QObject {
    Q_OBJECT

    bool condition1Met = false;
    bool condition2Met = false;

public slots:
    void setCondition1(bool met) {
        condition1Met = met;
        checkConditions();
    }

    void setCondition2(bool met) {
        condition2Met = met;
        checkConditions();
    }

signals:
    void conditionsMet();

private:
    void checkConditions() {
        if (condition1Met && condition2Met) {
            emit conditionsMet();
        }
    }
};

// 使用
MultiConditionTrigger trigger;

QObject::connect(signalSource1, &Source1::signalName, [&]() { trigger.setCondition1(true); });
QObject::connect(signalSource2, &Source2::signalName, [&]() { trigger.setCondition2(true); });
QObject::connect(&trigger, &MultiConditionTrigger::conditionsMet, receiver, &ReceiverClass::slot);

84. 信号的批量管理工具

创建一个通用管理器,批量管理信号的连接和断开。

class SignalManager : public QObject {
    Q_OBJECT

    QList<QMetaObject::Connection> connections;

public:
    void connectSignals(QObject* sender, const char* signal, QObject* receiver, const char* slot) {
        connections.append(QObject::connect(sender, signal, receiver, slot));
    }

    void disconnectAll() {
        for (const QMetaObject::Connection& conn : connections) {
            QObject::disconnect(conn);
        }
        connections.clear();
    }
};

// 使用
SignalManager manager;

manager.connectSignals(sender, SIGNAL(signalName()), receiver, SLOT(slotName()));
manager.disconnectAll();

85. 信号与槽的递归调用

在某些算法中,递归调用信号与槽可能会导致堆栈溢出。可以通过事件队列将递归转为迭代。

示例:递归调用问题
QObject::connect(sender, &SenderClass::signalName, [&]() {
    emit sender->signalName();  // 可能导致堆栈溢出
});
解决方案:利用事件队列
QObject::connect(sender, &SenderClass::signalName, [&]() {
    QTimer::singleShot(0, sender, [&]() {
        emit sender->signalName();  // 递归调用被转为异步处理
    });
});

86. 信号的延迟加载与动态生成

对于某些大型系统,可以根据需要动态加载信号与槽,避免提前加载所有模块。

动态生成信号与槽:
class DynamicSignalHandler : public QObject {
    Q_OBJECT

public:
    void createDynamicConnection(QObject* sender, const QString& signalName, std::function<void()> slot) {
        QMetaObject::Connection connection = QObject::connect(sender, sender->metaObject()->method(sender->metaObject()->indexOfSignal(signalName.toStdString().c_str())),
                                                              this, [slot]() { slot(); });
        connections.append(connection);
    }

    void clearConnections() {
        for (const auto& conn : connections) {
            QObject::disconnect(conn);
        }
        connections.clear();
    }

private:
    QList<QMetaObject::Connection> connections;
};
使用:
DynamicSignalHandler handler;

handler.createDynamicConnection(sender, "signalName()", []() {
    qDebug() << "Dynamic signal handled.";
});

87. 使用 QFutureWatcher 与信号结合处理异步任务

通过 QFutureWatcher 管理耗时任务,并用信号处理结果。

QFutureWatcher<int>* watcher = new QFutureWatcher<int>();

QObject::connect(watcher, &QFutureWatcher<int>::finished, [&]() {
    qDebug() << "Task completed with result:" << watcher->result();
    watcher->deleteLater();
});

QFuture<int> future = QtConcurrent::run([]() {
    QThread::sleep(2);
    return 42;
});

watcher->setFuture(future);

88. 信号的广播模式

在大型系统中,可以通过广播机制通知所有订阅者。

基于 QList 的简单广播实现:
class Broadcaster : public QObject {
    Q_OBJECT

public:
    void registerListener(QObject* listener, const char* slot) {
        listeners.append(qMakePair(listener, slot));
    }

    void broadcast(int value) {
        for (const auto& pair : listeners) {
            QMetaObject::invokeMethod(pair.first, pair.second, Q_ARG(int, value));
        }
    }

private:
    QList<QPair<QObject*, const char*>> listeners;
};
使用:
Broadcaster broadcaster;

broadcaster.registerListener(receiver1, SLOT(handleBroadcast(int)));
broadcaster.registerListener(receiver2, SLOT(handleBroadcast(int)));

broadcaster.broadcast(42);

89. 自定义信号与槽的队列管理

通过自定义队列管理信号的触发顺序与执行。

示例:自定义信号队列
class SignalQueue : public QObject {
    Q_OBJECT

    QQueue<std::function<void()>> queue;

public:
    void enqueue(std::function<void()> task) {
        queue.enqueue(task);
        if (queue.size() == 1) {
            processNext();
        }
    }

signals:
    void taskProcessed();

private:
    void processNext() {
        if (!queue.isEmpty()) {
            std::function<void()> task = queue.dequeue();
            task();
            emit taskProcessed();
        }
    }
};

// 使用
SignalQueue signalQueue;

QObject::connect(&signalQueue, &SignalQueue::taskProcessed, [&]() {
    qDebug() << "Task completed.";
});

signalQueue.enqueue([]() { qDebug() << "Task 1"; });
signalQueue.enqueue([]() { qDebug() << "Task 2"; });

90. 信号的多语言支持

对于多语言项目,可以为信号添加翻译或本地化信息。

class TranslatorSignal : public QObject {
    Q_OBJECT

signals:
    void localizedSignal(QString translatedMessage);

public:
    void emitLocalizedSignal(const QString& message, const QLocale& locale) {
        QString translated = QCoreApplication::translate("TranslatorSignal", message.toUtf8().constData(), nullptr, locale);
        emit localizedSignal(translated);
    }
};

// 使用
TranslatorSignal translator;

QObject::connect(&translator, &TranslatorSignal::localizedSignal, [](QString translated) {
    qDebug() << "Translated message:" << translated;
});

translator.emitLocalizedSignal("Hello, world!", QLocale::French);

91. 信号的并行处理

在多核 CPU 环境下,可以利用线程池并行处理信号。

QThreadPool::globalInstance()->setMaxThreadCount(4);

QObject::connect(sender, &SenderClass::signalName, [](int value) {
    QtConcurrent::run([=]() {
        qDebug() << "Processing in parallel thread:" << QThread::currentThread() << "with value:" << value;
    });
});

92. 信号的聚合与拆分

将多个信号合并成一个,或将一个信号拆分为多个子信号。

聚合信号:
class SignalAggregator : public QObject {
    Q_OBJECT

signals:
    void aggregatedSignal(int combinedValue);

public slots:
    void aggregate(int value1, int value2) {
        emit aggregatedSignal(value1 + value2);
    }
};

// 使用
SignalAggregator aggregator;

QObject::connect(sender1, &SenderClass::signal1, [&aggregator](int value) { aggregator.aggregate(value, 0); });
QObject::connect(sender2, &SenderClass::signal2, [&aggregator](int value) { aggregator.aggregate(0, value); });
QObject::connect(&aggregator, &SignalAggregator::aggregatedSignal, receiver, &ReceiverClass::slot);
拆分信号:
class SignalSplitter : public QObject {
    Q_OBJECT

signals:
    void subSignal1(int value);
    void subSignal2(int value);

public slots:
    void splitSignal(int combinedValue) {
        emit subSignal1(combinedValue / 2);
        emit subSignal2(combinedValue / 2);
    }
};

93. 信号的时序控制

通过 QTimerQElapsedTimer 控制信号的时间行为。

class TimedSignal : public QObject {
    Q_OBJECT

    QElapsedTimer timer;

signals:
    void timedSignal(int elapsed);

public slots:
    void emitTimedSignal() {
        int elapsed = timer.elapsed();
        timer.restart();
        emit timedSignal(elapsed);
    }
};

// 使用
TimedSignal timed;

QObject::connect(sender, &SenderClass::signalName, &timed, &TimedSignal::emitTimedSignal);
QObject::connect(&timed, &TimedSignal::timedSignal, [](int elapsed) {
    qDebug() << "Signal processed after" << elapsed << "ms";
});

94. 信号的缓存与重发

缓存信号数据以便重新发送或延迟发送。

class SignalCache : public QObject {
    Q_OBJECT

    QVariant cachedValue;

signals:
    void cachedSignal(QVariant value);

public slots:
    void cacheSignal(QVariant value) {
        cachedValue = value;
    }

    void resendCachedSignal() {
        emit cachedSignal(cachedValue);
    }
};

// 使用
SignalCache cache;

QObject::connect(sender, &SenderClass::signalName, &cache, &SignalCache::cacheSignal);
QObject::connect(&cache, &SignalCache::cachedSignal, receiver, &ReceiverClass::slot);

cache.resendCachedSignal();

95. 信号的循环检测与阻止

在复杂场景中,信号可能会引发循环调用,导致意外行为。可以通过布尔标志检测和阻止循环。

class CycleDetector : public QObject {
    Q_OBJECT

    bool inProgress = false;

public slots:
    void handleSignal() {
        if (inProgress) {
            qDebug() << "Signal loop detected, ignoring.";
            return;
        }

        inProgress = true;
        emit anotherSignal();  // 可能引发回调
        inProgress = false;
    }

signals:
    void anotherSignal();
};

// 使用
CycleDetector detector;
QObject::connect(sender, &SenderClass::signalName, &detector, &CycleDetector::handleSignal);
QObject::connect(&detector, &CycleDetector::anotherSignal, sender, &SenderClass::triggerAnotherSignal);

96. 信号过滤器

对信号的数据进行过滤,只允许满足条件的数据触发槽。

class SignalFilter : public QObject {
    Q_OBJECT

signals:
    void filteredSignal(int value);

public slots:
    void filterSignal(int value) {
        if (value > 10) {  // 过滤条件
            emit filteredSignal(value);
        } else {
            qDebug() << "Signal ignored, value too small:" << value;
        }
    }
};

// 使用
SignalFilter filter;
QObject::connect(sender, &SenderClass::signalName, &filter, &SignalFilter::filterSignal);
QObject::connect(&filter, &SignalFilter::filteredSignal, receiver, &ReceiverClass::slot);

97. 信号的参数解构

通过结构化绑定拆解信号参数,简化槽函数处理。

QObject::connect(sender, &SenderClass::signalWithStruct, [](const DataStruct& data) {
    auto [id, name, value] = data;  // C++17 解构
    qDebug() << "ID:" << id << "Name:" << name << "Value:" << value;
});

98. 信号参数的动态绑定

根据上下文动态决定槽处理信号的方式。

class DynamicBinder : public QObject {
    Q_OBJECT

    QMap<QString, std::function<void(int)>> handlers;

public:
    void addHandler(const QString& key, std::function<void(int)> handler) {
        handlers[key] = handler;
    }

    void handleSignal(const QString& key, int value) {
        if (handlers.contains(key)) {
            handlers[key](value);
        } else {
            qDebug() << "No handler for key:" << key;
        }
    }
};

// 使用
DynamicBinder binder;
binder.addHandler("typeA", [](int value) { qDebug() << "Handler A:" << value; });
binder.addHandler("typeB", [](int value) { qDebug() << "Handler B:" << value; });

QObject::connect(sender, &SenderClass::signalName, [&binder](const QString& key, int value) {
    binder.handleSignal(key, value);
});

99. 信号的优先级执行顺序

实现多个槽按优先级顺序接收信号。

class PriorityDispatcher : public QObject {
    Q_OBJECT

    QMap<int, QList<std::function<void()>>> priorityHandlers;

public:
    void addHandler(int priority, std::function<void()> handler) {
        priorityHandlers[priority].append(handler);
    }

    void dispatch() {
        for (auto it = priorityHandlers.constBegin(); it != priorityHandlers.constEnd(); ++it) {
            for (const auto& handler : it.value()) {
                handler();
            }
        }
    }
};

// 使用
PriorityDispatcher dispatcher;
dispatcher.addHandler(1, [] { qDebug() << "Low priority task"; });
dispatcher.addHandler(0, [] { qDebug() << "High priority task"; });

QObject::connect(sender, &SenderClass::signalName, &dispatcher, &PriorityDispatcher::dispatch);

100. 信号的事件整合

将信号与事件系统集成,使信号行为与 Qt 事件循环一致。

class SignalToEventAdapter : public QObject {
    Q_OBJECT

signals:
    void eventGenerated(QEvent* event);

public:
    void emitEvent(QEvent* event) {
        emit eventGenerated(event);
    }
};

// 使用
SignalToEventAdapter adapter;
QObject::connect(&adapter, &SignalToEventAdapter::eventGenerated, [&](QEvent* event) {
    qDebug() << "Event handled:" << event->type();
});

QEvent* event = new QEvent(QEvent::User);
adapter.emitEvent(event);

101. 信号的重连机制

动态断开并重新连接信号,用于切换模块或更新逻辑。

QObject::disconnect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slot);

// 重新连接
QObject::connect(sender, &SenderClass::signalName, newReceiver, &NewReceiverClass::newSlot);

或者封装成通用函数:

void reconnectSignal(QObject* sender, const char* signal, QObject* oldReceiver, const char* oldSlot,
                     QObject* newReceiver, const char* newSlot) {
    QObject::disconnect(sender, signal, oldReceiver, oldSlot);
    QObject::connect(sender, signal, newReceiver, newSlot);
}

102. 信号与槽的延迟加载

通过懒加载机制只在需要时连接信号与槽。

class LazyLoader : public QObject {
    Q_OBJECT

    bool isConnected = false;

public:
    void lazyConnect(QObject* sender, const char* signal, QObject* receiver, const char* slot) {
        if (!isConnected) {
            QObject::connect(sender, signal, receiver, slot);
            isConnected = true;
        }
    }
};

// 使用
LazyLoader loader;
loader.lazyConnect(sender, SIGNAL(signalName()), receiver, SLOT(slotName()));

103. 信号的批量生成与处理

为动态生成的控件批量绑定信号与槽。

for (int i = 0; i < 10; ++i) {
    QPushButton* button = new QPushButton(QString("Button %1").arg(i));
    QObject::connect(button, &QPushButton::clicked, [i]() {
        qDebug() << "Button clicked:" << i;
    });
    layout->addWidget(button);
}

104. 信号的取消机制

为信号提供取消功能,以阻止后续槽的执行。

class CancellableSignal : public QObject {
    Q_OBJECT

    bool cancelled = false;

public:
    void cancel() { cancelled = true; }

signals:
    void cancellableSignal();

public slots:
    void handleSignal() {
        if (cancelled) {
            qDebug() << "Signal cancelled, skipping.";
            return;
        }
        emit cancellableSignal();
    }
};

// 使用
CancellableSignal signalHandler;
QObject::connect(sender, &SenderClass::signalName, &signalHandler, &CancellableSignal::handleSignal);
signalHandler.cancel();

105. 信号的异步执行

通过线程池将信号的槽函数放到线程中异步执行。

QObject::connect(sender, &SenderClass::signalName, [](int value) {
    QtConcurrent::run([value]() {
        qDebug() << "Processing in thread:" << QThread::currentThread() << "Value:" << value;
    });
});

106. 信号与槽的时序依赖

为信号设置触发时序依赖,比如只在特定时间内有效。

class TimedSignalHandler : public QObject {
    Q_OBJECT

    QTimer timer;

public:
    TimedSignalHandler(int validDuration, QObject* parent = nullptr) : QObject(parent) {
        timer.setInterval(validDuration);
        timer.setSingleShot(true);
        timer.start();
    }

public slots:
    void handleSignal(int value) {
        if (timer.isActive()) {
            qDebug() << "Signal processed:" << value;
        } else {
            qDebug() << "Signal ignored due to timeout.";
        }
    }
};

// 使用
TimedSignalHandler handler(5000);  // 5 秒有效期
QObject::connect(sender, &SenderClass::signalName, &handler, &TimedSignalHandler::handleSignal);

107. 信号的动态优先级调整

动态调整信号对应槽的优先级,以适应运行时的场景变化。

class DynamicPriorityHandler : public QObject {
    Q_OBJECT

    QMap<int, std::function<void()>> handlers;

public:
    void addHandler(int priority, std::function<void()> handler) {
        handlers[priority] = handler;
    }

    void adjustPriority(int oldPriority, int newPriority) {
        if (handlers.contains(oldPriority)) {
            handlers[newPriority] = handlers.take(oldPriority);
        }
    }

    void executeHandlers() {
        for (auto it = handlers.constBegin(); it != handlers.constEnd(); ++it) {
            it.value()();
        }
    }
};

// 使用
DynamicPriorityHandler handler;
handler.addHandler(1, [] { qDebug() << "Handler with priority 1"; });
handler.addHandler(2, [] { qDebug() << "Handler with priority 2"; });

handler.adjustPriority(2, 0);  // 动态调整优先级
handler.executeHandlers();

108. 信号的静默触发

允许信号触发而不实际执行对应槽,用于某些特殊场景下的占位。

class SilentSignal : public QObject {
    Q_OBJECT

signals:
    void actualSignal();

public:
    void emitSilently() {
        // 静默触发,不连接任何槽
        emit actualSignal();
    }
};

109. 信号的链式延迟

多层信号通过定时器链式触发。

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    QTimer::singleShot(100, [value]() { emit sender->signalStep2(value * 2); });
});

QObject::connect(sender, &SenderClass::signalStep2, [&](int value) {
    QTimer::singleShot(200, [value]() { emit sender->signalStep3(value - 10); });
});

110. 信号的自动恢复机制

为信号引入自动恢复机制,当某些条件恢复后重新启用信号。

class RecoverableSignal : public QObject {
    Q_OBJECT

    bool isPaused = false;

signals:
    void recoverableSignal(int value);

public:
    void pauseSignal() { isPaused = true; }
    void resumeSignal() { isPaused = false; }

public slots:
    void handleSignal(int value) {
        if (!isPaused) {
            emit recoverableSignal(value);
        } else {
            qDebug() << "Signal paused.";
        }
    }
};

111. 信号的回滚机制

通过信号记录和回滚数据状态。

class RollbackSignalHandler : public QObject {
    Q_OBJECT

    QStack<int> history;

signals:
    void processedSignal(int value);

public slots:
    void handleSignal(int value) {
        history.push(value);
        emit processedSignal(value);
    }

    void rollback() {
        if (!history.isEmpty()) {
            int lastValue = history.pop();
            qDebug() << "Rolled back to:" << lastValue;
        }
    }
};

112. 信号的跨平台远程调用

结合 QWebSocketQNetwork 实现信号的跨网络传输。

class RemoteSignal : public QObject {
    Q_OBJECT

    QWebSocket socket;

signals:
    void remoteSignal(QString message);

public:
    void connectToServer(const QUrl& url) {
        socket.open(url);
    }

public slots:
    void sendRemoteSignal(const QString& message) {
        socket.sendTextMessage(message);
    }
};

// 使用
RemoteSignal remote;
remote.connectToServer(QUrl("ws://localhost:1234"));

QObject::connect(sender, &SenderClass::signalName, &remote, [&](QString message) {
    remote.sendRemoteSignal(message);
});

113. 信号的组绑定与解绑

为多个对象批量绑定和解绑信号。

class SignalGroup : public QObject {
    Q_OBJECT

    QList<QObject*> members;

public:
    void addMember(QObject* member, const char* signal, const QObject* receiver, const char* slot) {
        QObject::connect(member, signal, receiver, slot);
        members.append(member);
    }

    void removeAllConnections(const QObject* receiver, const char* slot) {
        for (auto* member : members) {
            QObject::disconnect(member, nullptr, receiver, slot);
        }
    }
};

114. 信号的上下文信息传递

为信号附加上下文信息,通过包装器扩展信号内容。

class ContextualSignal : public QObject {
    Q_OBJECT

signals:
    void contextualSignal(QString context, QVariant value);

public:
    void emitWithContext(const QString& context, const QVariant& value) {
        emit contextualSignal(context, value);
    }
};

// 使用
ContextualSignal contextual;

QObject::connect(&contextual, &ContextualSignal::contextualSignal, [](QString context, QVariant value) {
    qDebug() << "Context:" << context << "Value:" << value;
});

contextual.emitWithContext("ModuleA", 42);

115. 信号的负载均衡处理

根据槽的处理能力分配信号负载。

class LoadBalancer : public QObject {
    Q_OBJECT

    QList<std::function<void(int)>> workers;
    int currentWorker = 0;

public:
    void addWorker(std::function<void(int)> worker) {
        workers.append(worker);
    }

    void distributeWork(int value) {
        if (!workers.isEmpty()) {
            workers[currentWorker](value);
            currentWorker = (currentWorker + 1) % workers.size();
        }
    }
};

// 使用
LoadBalancer balancer;
balancer.addWorker([](int value) { qDebug() << "Worker 1 handling" << value; });
balancer.addWorker([](int value) { qDebug() << "Worker 2 handling" << value; });

QObject::connect(sender, &SenderClass::signalName, &balancer, [&](int value) {
    balancer.distributeWork(value);
});

116. 信号与 AI 模型集成

触发信号调用机器学习模型进行预测或处理。

class AIModelHandler : public QObject {
    Q_OBJECT

signals:
    void predictionReady(float result);

public slots:
    void handleSignal(QVector<float> input) {
        // 模拟 AI 模型预测
        float result = std::accumulate(input.begin(), input.end(), 0.0f) / input.size();
        emit predictionReady(result);
    }
};

// 使用
AIModelHandler aiHandler;

QObject::connect(sender, &SenderClass::signalName, &aiHandler, [&](QVector<float> input) {
    aiHandler.handleSignal(input);
});

QObject::connect(&aiHandler, &AIModelHandler::predictionReady, [](float result) {
    qDebug() << "Prediction result:" << result;
});

117. 信号与 UI 动态绑定

将信号动态绑定到 UI 控件,适应实时变化。

QObject::connect(sender, &SenderClass::signalName, ui->progressBar, &QProgressBar::setValue);

或者通过中间处理动态映射:

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    ui->progressBar->setValue(value * 2);  // 动态调整值
});

118. 信号与槽的递归限制

防止槽函数触发信号引发递归。

class RecursionLimiter : public QObject {
    Q_OBJECT

    bool inProgress = false;

public slots:
    void handleSignal() {
        if (inProgress) {
            qDebug() << "Recursive signal ignored.";
            return;
        }

        inProgress = true;
        emit nestedSignal();  // 可能触发递归
        inProgress = false;
    }

signals:
    void nestedSignal();
};

119. 信号的动态条件路由

信号根据特定条件动态路由到不同的槽。

class SignalRouter : public QObject {
    Q_OBJECT

    QMap<QString, std::function<void(int)>> routes;

public:
    void addRoute(const QString& key, std::function<void(int)> handler) {
        routes[key] = handler;
    }

    void routeSignal(const QString& key, int value) {
        if (routes.contains(key)) {
            routes[key](value);
        } else {
            qDebug() << "No route for key:" << key;
        }
    }
};

// 使用
SignalRouter router;
router.addRoute("pathA", [](int value) { qDebug() << "Path A with value:" << value; });
router.addRoute("pathB", [](int value) { qDebug() << "Path B with value:" << value; });

QObject::connect(sender, &SenderClass::signalName, [&router](const QString& key, int value) {
    router.routeSignal(key, value);
});

120. 信号的动态切换

允许在运行时动态切换信号的处理逻辑。

class DynamicSwitcher : public QObject {
    Q_OBJECT

    std::function<void(int)> currentHandler;

public:
    void setHandler(std::function<void(int)> handler) {
        currentHandler = handler;
    }

    void processSignal(int value) {
        if (currentHandler) {
            currentHandler(value);
        } else {
            qDebug() << "No handler set.";
        }
    }
};

// 使用
DynamicSwitcher switcher;
switcher.setHandler([](int value) { qDebug() << "Initial handler with value:" << value; });

QObject::connect(sender, &SenderClass::signalName, &switcher, &DynamicSwitcher::processSignal);

// 动态切换逻辑
switcher.setHandler([](int value) { qDebug() << "Switched handler with value:" << value; });

121. 信号的智能对象管理

为信号和槽添加生命周期管理,自动清理无效对象。

class SmartSignalManager : public QObject {
    Q_OBJECT

    QMap<QObject*, QList<QMetaObject::Connection>> connections;

public:
    void addConnection(QObject* sender, const char* signal, QObject* receiver, const char* slot) {
        auto conn = QObject::connect(sender, signal, receiver, slot);
        connections[sender].append(conn);

        connect(sender, &QObject::destroyed, this, [this, sender]() {
            connections.remove(sender);
        });
    }

    void disconnectAll(QObject* sender) {
        if (connections.contains(sender)) {
            for (const auto& conn : connections[sender]) {
                QObject::disconnect(conn);
            }
            connections.remove(sender);
        }
    }
};

// 使用
SmartSignalManager manager;
manager.addConnection(sender, SIGNAL(signalName()), receiver, SLOT(slotName()));

122. 信号的参数注入

动态注入额外参数到信号中。

class ParameterInjector : public QObject {
    Q_OBJECT

signals:
    void injectedSignal(int value, QString extra);

public slots:
    void injectParameters(int value) {
        emit injectedSignal(value, "Extra Data");
    }
};

// 使用
ParameterInjector injector;

QObject::connect(sender, &SenderClass::signalName, &injector, &ParameterInjector::injectParameters);
QObject::connect(&injector, &ParameterInjector::injectedSignal, [](int value, QString extra) {
    qDebug() << "Received value:" << value << "with extra:" << extra;
});

123. 信号的模块化桥接

通过桥接器在模块之间传递信号,降低耦合性。

class SignalBridge : public QObject {
    Q_OBJECT

signals:
    void bridgedSignal(int value);

public slots:
    void bridgeSignal(int value) {
        emit bridgedSignal(value);
    }
};

// 使用
SignalBridge bridge;

QObject::connect(moduleA, &ModuleA::outputSignal, &bridge, &SignalBridge::bridgeSignal);
QObject::connect(&bridge, &SignalBridge::bridgedSignal, moduleB, &ModuleB::inputSlot);

124. 信号的嵌套调用

支持信号之间的嵌套触发,避免直接递归。

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    qDebug() << "Outer signal received:" << value;
    emit sender->nestedSignal(value * 2);
});

QObject::connect(sender, &SenderClass::nestedSignal, [&](int nestedValue) {
    qDebug() << "Nested signal processed:" << nestedValue;
});

125. 信号与动态脚本绑定

通过 QJSEngine 动态绑定信号到 JavaScript 函数。

QJSEngine engine;

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    QJSValue func = engine.evaluate("(function(value) { return value * 2; })");
    QJSValue result = func.call(QJSValueList() << value);
    qDebug() << "Script result:" << result.toInt();
});

126. 信号与扩展事件系统结合

将信号转为 Qt 事件,使其兼容标准事件处理流程。

class SignalToEventAdapter : public QObject {
    Q_OBJECT

signals:
    void eventGenerated(QEvent* event);

public:
    void emitAsEvent() {
        QEvent* event = new QEvent(QEvent::User);
        emit eventGenerated(event);
    }
};

// 使用
SignalToEventAdapter adapter;

QObject::connect(&adapter, &SignalToEventAdapter::eventGenerated, [&](QEvent* event) {
    qDebug() << "Event received with type:" << event->type();
    delete event;  // 清理事件
});

adapter.emitAsEvent();

127. 信号的事务控制

为信号添加事务支持,确保一组信号全部成功或回滚。

class TransactionalSignalHandler : public QObject {
    Q_OBJECT

    bool transactionActive = false;

public:
    void beginTransaction() { transactionActive = true; }
    void commitTransaction() { transactionActive = false; }
    void rollbackTransaction() {
        if (transactionActive) {
            qDebug() << "Transaction rolled back.";
            transactionActive = false;
        }
    }

signals:
    void transactionalSignal(int value);

public slots:
    void processSignal(int value) {
        if (transactionActive) {
            emit transactionalSignal(value);
        }
    }
};

128. 信号的分布式调度

通过 QTimer 将信号分布在不同时间片处理。

class DistributedScheduler : public QObject {
    Q_OBJECT

    QQueue<int> taskQueue;

public:
    void scheduleTask(int value) {
        taskQueue.enqueue(value);
        QTimer::singleShot(100, this, &DistributedScheduler::processNext);
    }

private slots:
    void processNext() {
        if (!taskQueue.isEmpty()) {
            int value = taskQueue.dequeue();
            qDebug() << "Processing value:" << value;
        }
    }
};

// 使用
DistributedScheduler scheduler;

scheduler.scheduleTask(1);
scheduler.scheduleTask(2);
scheduler.scheduleTask(3);

129. 信号的实时调试工具

开发调试工具捕获和可视化信号的触发和传播。

class SignalDebugger : public QObject {
    Q_OBJECT

public slots:
    void logSignal(const QString& signalName, const QVariant& data) {
        qDebug() << "Signal triggered:" << signalName << "Data:" << data;
    }
};

// 使用
SignalDebugger debugger;

QObject::connect(sender, &SenderClass::signalName, [&debugger](int value) {
    debugger.logSignal("signalName", value);
});

130. 信号的分步执行

将信号的槽函数拆分为多个步骤执行。

class StepwiseProcessor : public QObject {
    Q_OBJECT

    QQueue<std::function<void()>> steps;

public:
    void addStep(std::function<void()> step) {
        steps.enqueue(step);
    }

    void executeNext() {
        if (!steps.isEmpty()) {
            steps.dequeue()();  // 执行下一步
        }
    }
};

// 使用
StepwiseProcessor processor;
processor.addStep([] { qDebug() << "Step 1 executed"; });
processor.addStep([] { qDebug() << "Step 2 executed"; });

QObject::connect(sender, &SenderClass::signalName, &processor, &StepwiseProcessor::executeNext);

131. 信号的多线程复用

通过线程池动态分配信号给空闲线程处理。

QThreadPool::globalInstance()->setMaxThreadCount(4);

QObject::connect(sender, &SenderClass::signalName, [](int value) {
    QtConcurrent::run([value]() {
        qDebug() << "Processing value in thread:" << QThread::currentThread() << "Value:" << value;
    });
});

132. 信号的压缩与合并

在高频信号场景中,将多个信号数据合并后统一处理,减少槽调用次数。

class SignalCompressor : public QObject {
    Q_OBJECT

    QList<int> buffer;

public:
    void addData(int value) {
        buffer.append(value);
        if (buffer.size() >= 5) {  // 累积到一定数量后触发处理
            processBuffer();
            buffer.clear();
        }
    }

private:
    void processBuffer() {
        qDebug() << "Processing compressed data:" << buffer;
    }
};

// 使用
SignalCompressor compressor;

QObject::connect(sender, &SenderClass::signalName, &compressor, [&](int value) {
    compressor.addData(value);
});

133. 信号的状态驱动

根据系统状态决定信号的处理方式。

class StateDrivenHandler : public QObject {
    Q_OBJECT

    QString currentState;

public:
    void setState(const QString& state) {
        currentState = state;
    }

public slots:
    void handleSignal(int value) {
        if (currentState == "Active") {
            qDebug() << "Active state handling value:" << value;
        } else if (currentState == "Paused") {
            qDebug() << "Paused state, ignoring value:" << value;
        }
    }
};

// 使用
StateDrivenHandler handler;
handler.setState("Active");

QObject::connect(sender, &SenderClass::signalName, &handler, &StateDrivenHandler::handleSignal);

// 动态改变状态
handler.setState("Paused");

134. 信号的广播增强

为信号广播添加订阅和取消订阅功能。

class EnhancedBroadcaster : public QObject {
    Q_OBJECT

    QList<QObject*> subscribers;

public:
    void subscribe(QObject* subscriber) {
        subscribers.append(subscriber);
    }

    void unsubscribe(QObject* subscriber) {
        subscribers.removeAll(subscriber);
    }

    void broadcast(int value) {
        for (auto* subscriber : subscribers) {
            QMetaObject::invokeMethod(subscriber, "handleBroadcast", Q_ARG(int, value));
        }
    }
};

// 使用
EnhancedBroadcaster broadcaster;
broadcaster.subscribe(receiver1);
broadcaster.subscribe(receiver2);

broadcaster.broadcast(42);

135. 信号的实时数据流整合

通过信号与数据流框架(如 RxCpp 或自定义流)结合,实现实时流式处理。

class DataStreamHandler : public QObject {
    Q_OBJECT

signals:
    void processedData(int value);

public slots:
    void processSignal(int value) {
        int processedValue = value * 2;  // 模拟数据处理
        emit processedData(processedValue);
    }
};

// 使用
DataStreamHandler streamHandler;

QObject::connect(sender, &SenderClass::signalName, &streamHandler, &DataStreamHandler::processSignal);
QObject::connect(&streamHandler, &DataStreamHandler::processedData, [](int value) {
    qDebug() << "Streamed data:" << value;
});

136. 信号的动态统计分析

统计信号触发次数及参数分布。

class SignalStatistics : public QObject {
    Q_OBJECT

    int triggerCount = 0;
    QMap<int, int> valueDistribution;

public slots:
    void analyzeSignal(int value) {
        triggerCount++;
        valueDistribution[value]++;
    }

    void printStatistics() {
        qDebug() << "Signal triggered" << triggerCount << "times.";
        for (auto it = valueDistribution.constBegin(); it != valueDistribution.constEnd(); ++it) {
            qDebug() << "Value:" << it.key() << "Count:" << it.value();
        }
    }
};

// 使用
SignalStatistics stats;

QObject::connect(sender, &SenderClass::signalName, &stats, &SignalStatistics::analyzeSignal);

137. 信号的动态重试

在信号处理失败时实现自动重试机制。

class RetryHandler : public QObject {
    Q_OBJECT

    int retryLimit;
    int retryCount = 0;

public:
    explicit RetryHandler(int limit, QObject* parent = nullptr) : QObject(parent), retryLimit(limit) {}

public slots:
    void processSignal(int value) {
        if (value % 2 == 0) {
            qDebug() << "Signal processed successfully with value:" << value;
            retryCount = 0;  // 重置重试计数
        } else if (retryCount < retryLimit) {
            retryCount++;
            qDebug() << "Retrying... Attempt:" << retryCount;
            QTimer::singleShot(100, [this, value]() { processSignal(value); });
        } else {
            qDebug() << "Processing failed after" << retryLimit << "retries.";
        }
    }
};

// 使用
RetryHandler handler(3);

QObject::connect(sender, &SenderClass::signalName, &handler, &RetryHandler::processSignal);

138. 信号的层次分发

根据信号来源的层级分发给不同的处理器。

class HierarchicalDistributor : public QObject {
    Q_OBJECT

    QMap<int, std::function<void(int)>> levelHandlers;

public:
    void addHandler(int level, std::function<void(int)> handler) {
        levelHandlers[level] = handler;
    }

    void distributeSignal(int level, int value) {
        if (levelHandlers.contains(level)) {
            levelHandlers[level](value);
        } else {
            qDebug() << "No handler for level:" << level;
        }
    }
};

// 使用
HierarchicalDistributor distributor;

distributor.addHandler(1, [](int value) { qDebug() << "Level 1 handler processing" << value; });
distributor.addHandler(2, [](int value) { qDebug() << "Level 2 handler processing" << value; });

QObject::connect(sender, &SenderClass::signalName, &distributor, [&](int level, int value) {
    distributor.distributeSignal(level, value);
});

139. 信号的自动清理机制

当槽或信号源销毁时,自动清理信号连接。

QObject::connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName,
                 Qt::UniqueConnection | Qt::ConnectionType::AutoConnection);

140. 信号与日志系统的全面集成

开发日志工具记录信号与槽的每一次调用细节,包括时间戳和参数。

class SignalLogger : public QObject {
    Q_OBJECT

public slots:
    void logSignal(const QString& signalName, const QVariant& data) {
        qDebug() << QDateTime::currentDateTime().toString() << "Signal:" << signalName << "Data:" << data;
    }
};

// 使用
SignalLogger logger;

QObject::connect(sender, &SenderClass::signalName, [&](int value) {
    logger.logSignal("signalName", value);
});

141. 信号的动态绑定和解除

实现运行时动态添加或移除槽函数。

class DynamicSignalBinder : public QObject {
    Q_OBJECT

    QMap<int, QMetaObject::Connection> connections;

public:
    void bindSignal(QObject* sender, const char* signal, QObject* receiver, const char* slot, int id) {
        auto conn = QObject::connect(sender, signal, receiver, slot);
        connections[id] = conn;
    }

    void unbindSignal(int id) {
        if (connections.contains(id)) {
            QObject::disconnect(connections[id]);
            connections.remove(id);
        }
    }
};

// 使用
DynamicSignalBinder binder;

binder.bindSignal(sender, SIGNAL(signalName()), receiver, SLOT(slotName()), 1);
binder.unbindSignal(1);

142. 信号的性能监控与优化

通过分析信号触发的频率和执行时间,找出性能瓶颈。

class SignalPerformanceMonitor : public QObject {
    Q_OBJECT

    QElapsedTimer timer;

public slots:
    void startMonitoring() {
        timer.start();
    }

    void stopMonitoring() {
        qDebug() << "Signal execution time:" << timer.elapsed() << "ms";
    }
};

// 使用
SignalPerformanceMonitor monitor;

QObject::connect(sender, &SenderClass::signalName, &monitor, &SignalPerformanceMonitor::startMonitoring);
QObject::connect(sender, &SenderClass::signalName, &monitor, &SignalPerformanceMonitor::stopMonitoring);

143. 信号的多条件触发

当满足多个条件时,触发槽函数。

class MultiConditionTrigger : public QObject {
    Q_OBJECT

    QMap<QString, bool> conditions;

public:
    void setCondition(const QString& name, bool met) {
        conditions[name] = met;
        checkConditions();
    }

signals:
    void allConditionsMet();

private:
    void checkConditions() {
        if (std::all_of(conditions.begin(), conditions.end(), [](bool met) { return met; })) {
            emit allConditionsMet();
        }
    }
};

// 使用
MultiConditionTrigger trigger;
trigger.setCondition("ConditionA", false);
trigger.setCondition("ConditionB", false);

QObject::connect(&trigger, &MultiConditionTrigger::allConditionsMet, []() {
    qDebug() << "All conditions met!";
});

trigger.setCondition("ConditionA", true);
trigger.setCondition("ConditionB", true);

144. 信号与有限状态机(FSM)集成

使用信号控制状态机的状态转换。

QStateMachine machine;
QState* state1 = new QState();
QState* state2 = new QState();

state1->addTransition(sender, &SenderClass::signalName, state2);

machine.addState(state1);
machine.addState(state2);
machine.setInitialState(state1);

QObject::connect(state2, &QState::entered, []() {
    qDebug() << "State 2 entered!";
});

machine.start();

145. 信号的多层代理

通过代理层逐步处理和分发信号。

class SignalProxy : public QObject {
    Q_OBJECT

signals:
    void proxiedSignal(int value);

public slots:
    void interceptSignal(int value) {
        int modifiedValue = value * 2;  // 修改信号值
        emit proxiedSignal(modifiedValue);
    }
};

// 使用
SignalProxy proxy;

QObject::connect(sender, &SenderClass::signalName, &proxy, &SignalProxy::interceptSignal);
QObject::connect(&proxy, &SignalProxy::proxiedSignal, receiver, &ReceiverClass::slot);

146. 信号的周期性触发

定期触发信号,模拟周期性任务。

class PeriodicSignal : public QObject {
    Q_OBJECT

    QTimer timer;

signals:
    void periodicSignal(int count);

public:
    void start(int interval) {
        int count = 0;
        timer.setInterval(interval);
        connect(&timer, &QTimer::timeout, this, [&]() {
            emit periodicSignal(++count);
        });
        timer.start();
    }

    void stop() {
        timer.stop();
    }
};

// 使用
PeriodicSignal periodic;

QObject::connect(&periodic, &PeriodicSignal::periodicSignal, [](int count) {
    qDebug() << "Periodic signal triggered, count:" << count;
});

periodic.start(1000);  // 每秒触发

147. 信号的事务回滚

当信号处理失败时,回滚之前的操作。

class TransactionalSignal : public QObject {
    Q_OBJECT

    QStack<int> history;

signals:
    void transactionCommitted();

public slots:
    void processSignal(int value) {
        history.push(value);
        if (value % 2 == 0) {
            emit transactionCommitted();
        } else {
            rollback();
        }
    }

private:
    void rollback() {
        if (!history.isEmpty()) {
            int lastValue = history.pop();
            qDebug() << "Rolling back value:" << lastValue;
        }
    }
};

148. 信号的自定义序列化

将信号数据序列化后存储或传输。

class SignalSerializer : public QObject {
    Q_OBJECT

signals:
    void serializedSignal(QByteArray data);

public slots:
    void serializeSignal(int value) {
        QByteArray data;
        QDataStream stream(&data, QIODevice::WriteOnly);
        stream << value;
        emit serializedSignal(data);
    }
};

// 使用
SignalSerializer serializer;

QObject::connect(sender, &SenderClass::signalName, &serializer, &SignalSerializer::serializeSignal);
QObject::connect(&serializer, &SignalSerializer::serializedSignal, [](QByteArray data) {
    QDataStream stream(&data, QIODevice::ReadOnly);
    int value;
    stream >> value;
    qDebug() << "Deserialized value:" << value;
});

149. 信号的粒度控制

根据接收者的能力动态调整信号的触发频率或数据粒度。

class SignalGranularityController : public QObject {
    Q_OBJECT

    int granularity;

signals:
    void granularSignal(int value);

public:
    void setGranularity(int level) {
        granularity = level;
    }

public slots:
    void processSignal(int value) {
        if (value % granularity == 0) {
            emit granularSignal(value);
        } else {
            qDebug() << "Signal ignored due to granularity settings.";
        }
    }
};

150. 信号的动态时间窗口

在特定时间窗口内处理信号,超出时间则忽略。

class TimeWindowHandler : public QObject {
    Q_OBJECT

    QElapsedTimer timer;
    int timeWindow;

public:
    explicit TimeWindowHandler(int window, QObject* parent = nullptr)
        : QObject(parent), timeWindow(window) {
        timer.start();
    }

public slots:
    void handleSignal(int value) {
        if (timer.elapsed() <= timeWindow) {
            qDebug() << "Signal within time window, value:" << value;
        } else {
            qDebug() << "Signal outside time window, ignored.";
        }
    }
};

// 使用
TimeWindowHandler handler(5000);  // 5 秒时间窗口

QObject::connect(sender, &SenderClass::signalName, &handler, &TimeWindowHandler::handleSignal);

151. 信号的链式回调

多个信号形成一条链式反应流,支持动态扩展。

class ChainableSignal : public QObject {
    Q_OBJECT

signals:
    void nextSignal(int value);

public:
    void triggerChain(int value) {
        emit nextSignal(value);
    }
};

// 使用
ChainableSignal signal1, signal2, signal3;

QObject::connect(&signal1, &ChainableSignal::nextSignal, &signal2, [&](int value) {
    qDebug() << "Signal 2 processing value:" << value;
    emit signal2.nextSignal(value * 2);
});

QObject::connect(&signal2, &ChainableSignal::nextSignal, &signal3, [&](int value) {
    qDebug() << "Signal 3 processing value:" << value;
});

signal1.triggerChain(10);

152. 信号的负载分析

实时分析信号的触发频率和处理负载。

class LoadAnalyzer : public QObject {
    Q_OBJECT

    QElapsedTimer timer;
    int triggerCount = 0;

public slots:
    void analyzeSignal() {
        triggerCount++;
        if (timer.isValid()) {
            qDebug() << "Signal triggered" << triggerCount << "times in" << timer.elapsed() << "ms";
        } else {
            timer.start();
        }
    }
};

// 使用
LoadAnalyzer analyzer;

QObject::connect(sender, &SenderClass::signalName, &analyzer, &LoadAnalyzer::analyzeSignal);

153. 信号的动态模块绑定

根据模块的加载状态动态连接或断开信号。

class ModuleManager : public QObject {
    Q_OBJECT

    QMap<QString, QObject*> modules;

public:
    void loadModule(const QString& name, QObject* module) {
        modules[name] = module;
        // 动态连接信号
        QObject::connect(sender, &SenderClass::signalName, module, &ModuleClass::moduleSlot);
    }

    void unloadModule(const QString& name) {
        if (modules.contains(name)) {
            // 断开信号
            QObject::disconnect(sender, &SenderClass::signalName, modules[name], &ModuleClass::moduleSlot);
            modules.remove(name);
        }
    }
};

// 使用
ModuleManager manager;

manager.loadModule("ModuleA", moduleA);
manager.unloadModule("ModuleA");

154. 信号的跨进程通信

通过 QSharedMemoryQLocalSocket 实现信号跨进程传递。

使用 QLocalSocket
class InterProcessSignal : public QObject {
    Q_OBJECT

    QLocalSocket socket;

signals:
    void receivedSignal(QByteArray data);

public:
    void connectToServer(const QString& serverName) {
        socket.connectToServer(serverName);
    }

public slots:
    void sendSignal(QByteArray data) {
        socket.write(data);
    }
};

// 使用
InterProcessSignal ipcSignal;

ipcSignal.connectToServer("LocalServer");

QObject::connect(sender, &SenderClass::signalName, [&ipcSignal](int value) {
    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly);
    stream << value;
    ipcSignal.sendSignal(data);
});

155. 信号的区域化控制

信号的触发受地理位置或时间区域限制。

class RegionalSignalController : public QObject {
    Q_OBJECT

    QString currentRegion;

public:
    void setRegion(const QString& region) {
        currentRegion = region;
    }

signals:
    void regionalSignal(int value);

public slots:
    void handleSignal(int value) {
        if (currentRegion == "AllowedRegion") {
            emit regionalSignal(value);
        } else {
            qDebug() << "Signal ignored due to region restrictions.";
        }
    }
};

156. 信号的图形化调试

通过可视化工具显示信号的触发和传播路径。

class SignalVisualizer : public QObject {
    Q_OBJECT

public slots:
    void visualizeSignal(const QString& signalName) {
        qDebug() << "Visualizing signal:" << signalName;
        // 使用 Qt 的 QGraphicsView 显示信号路径
    }
};

// 使用
SignalVisualizer visualizer;

QObject::connect(sender, &SenderClass::signalName, [&visualizer]() {
    visualizer.visualizeSignal("signalName");
});

157. 信号的时序依赖与自动触发

多个信号按时间顺序触发。

class SequentialSignalManager : public QObject {
    Q_OBJECT

    QList<std::function<void()>> sequence;
    int currentStep = 0;

public:
    void addStep(std::function<void()> step) {
        sequence.append(step);
    }

    void triggerNext() {
        if (currentStep < sequence.size()) {
            sequence[currentStep]();
            currentStep++;
        }
    }
};

// 使用
SequentialSignalManager manager;

manager.addStep([] { qDebug() << "Step 1 triggered."; });
manager.addStep([] { qDebug() << "Step 2 triggered."; });
manager.addStep([] { qDebug() << "Step 3 triggered."; });

QObject::connect(sender, &SenderClass::signalName, &manager, &SequentialSignalManager::triggerNext);

158. 信号的动态优先级任务队列

基于优先级调度信号触发。

class PriorityTaskQueue : public QObject {
    Q_OBJECT

    QMap<int, QList<std::function<void()>>> tasks;

public:
    void addTask(int priority, std::function<void()> task) {
        tasks[priority].append(task);
    }

    void execute() {
        for (auto it = tasks.begin(); it != tasks.end(); ++it) {
            for (const auto& task : it.value()) {
                task();
            }
        }
        tasks.clear();
    }
};

// 使用
PriorityTaskQueue queue;

queue.addTask(1, [] { qDebug() << "Low priority task."; });
queue.addTask(0, [] { qDebug() << "High priority task."; });

QObject::connect(sender, &SenderClass::signalName, [&queue]() { queue.execute(); });

159. 信号的机器学习应用

结合 AI 模型使用信号实时预测。

class AIModel : public QObject {
    Q_OBJECT

signals:
    void predictionReady(float result);

public slots:
    void predict(QVector<float> input) {
        float result = std::accumulate(input.begin(), input.end(), 0.0f) / input.size();  // 模拟预测
        emit predictionReady(result);
    }
};

// 使用
AIModel model;

QObject::connect(sender, &SenderClass::signalName, [&model](QVector<float> input) {
    model.predict(input);
});

QObject::connect(&model, &AIModel::predictionReady, [](float result) {
    qDebug() << "Prediction result:" << result;
});

160. 信号的网络传输与同步

将信号数据通过网络同步到多个客户端。

class NetworkSignal : public QObject {
    Q_OBJECT

    QTcpSocket socket;

public:
    void connectToServer(const QHostAddress& address, quint16 port) {
        socket.connectToHost(address, port);
    }

    void sendSignalData(QByteArray data) {
        socket.write(data);
    }
};

// 使用
NetworkSignal networkSignal;

networkSignal.connectToServer(QHostAddress::LocalHost, 1234);

QObject::connect(sender, &SenderClass::signalName, [&networkSignal](int value) {
    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly);
    stream << value;
    networkSignal.sendSignalData(data);
});

总结

这些方法进一步拓展了 Qt 信号与槽的边界,涵盖了链式处理、负载分析、跨模块动态绑定、跨进程和网络通信、机器学习集成等高级场景。这些方法展示了信号与槽几乎无穷的潜力,适用于各种复杂项目。


文章来源:https://blog.csdn.net/qq_43689451/article/details/144159467
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云