#ifndef CONNECTIONMANAGER_H
#define CONNECTIONMANAGER_H
#include <QObject>
#include <vector>
#include <functional> // 必须包含,支持 std::function
#include <QMetaObject> // 包含 QMetaObject::Connection
class ConnectionManager : public QObject
{
Q_OBJECT
private:
using ConnectFunction = std::function<QMetaObject::Connection()>;
// 存储:创建连接的函数 + 当前连接对象
std::vector<std::pair<ConnectFunction, QMetaObject::Connection>> m_connections;
public:
// 定义:创建连接的函数(无参,返回新的连接对象)
explicit ConnectionManager(QObject *parent = nullptr);
// 添加需要管理的连接(传入“创建连接”的逻辑)
void addConnection(ConnectFunction connectFunc);
// 断开所有管理的连接
void disconnectAll();
// 重新连接所有管理的连接(先断旧连接,再创建新连接)
void reconnectAll();
// 清空连接(断开 + 清除列表)
void clear();
};
// 自动守卫类(RAII:函数进入时断开,退出时重连)
class ConnectionGuard
{
public:
explicit ConnectionGuard(ConnectionManager& manager);
~ConnectionGuard();
// 禁止拷贝(避免重复管理连接)
ConnectionGuard(const ConnectionGuard&) = delete;
ConnectionGuard& operator=(const ConnectionGuard&) = delete;
private:
ConnectionManager& m_manager;
};
#endif // CONNECTIONMANAGER_H
#include "connectionmanager.h"
ConnectionManager::ConnectionManager(QObject *parent)
: QObject(parent)
{
}
void ConnectionManager::addConnection(ConnectFunction connectFunc)
{
if (connectFunc) { // 检查函数对象有效
// 立即创建连接,并存储“创建函数 + 连接对象”
m_connections.emplace_back(connectFunc, connectFunc());
}
}
void ConnectionManager::disconnectAll()
{
// 遍历所有连接,断开(VS2015 不支持结构化绑定,改用 pair 访问)
for (auto& pair : m_connections) {
ConnectFunction& createFunc = pair.first; // 创建连接的函数
QMetaObject::Connection& conn = createFunc(); // 测试中pair.second在传递中会被其他未知行为改变地址
QObject::disconnect(conn); // Qt 支持重复断开,安全无副作用
}
}
void ConnectionManager::reconnectAll()
{
for (auto& pair : m_connections) {
ConnectFunction& createFunc = pair.first; // 创建连接的函数
QMetaObject::Connection& conn = pair.second; // 当前连接对象
// 先断开旧连接(若存在)
QObject::disconnect(conn);
// 重新执行创建逻辑,生成新连接
if (createFunc) {
conn = createFunc();
}
}
}
void ConnectionManager::clear()
{
disconnectAll();
m_connections.clear();
}
ConnectionGuard::ConnectionGuard(ConnectionManager& manager)
: m_manager(manager)
{
m_manager.disconnectAll(); // 构造时自动断开连接
}
ConnectionGuard::~ConnectionGuard()
{
m_manager.reconnectAll(); // 析构时自动重连连接
}
定义:
connManager->addConnection([this]() {
return QObject::connect(m_tblCentPad1, &QTableWidget::itemChanged, this, [=](QTableWidgetItem *item) {
if (item) {
JudgeTableLimit(1, item);
}
});
});
使用:
ConnectionGuard guard(*connManager);
功能 :在一个函数执行中先断开lambda表达式的connect链接 在函数执行完之后在链接上
问题:无法断开lambda链接还是会触发信号