- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在构造器内部,有一个连接:
connect(&amskspace::on_board_computer_model::self(),
SIGNAL(camera_status_changed(const amskspace::camera_status_t&)),
this,
SLOT(set_camera_status(const amskspace::camera_status_t&)));
方法:
void camera_model::
set_camera_status(const amskspace::camera_status_t& status) {
disconnect(&amskspace::on_board_computer_model::self(),
SIGNAL(camera_status_changed(const amskspace::camera_status_t&)),
this,
SLOT(set_camera_status(const amskspace::camera_status_t&)));
// do the job
}
我想在第一次通话后断开这个插槽。
问题是:有没有办法只调用一次插槽?没有明确的断开连接?像单发方法?可能吗?
最佳答案
核心思想是创建一个包装器,一个自动断开信号的特殊“连接”。如果您使用很多“给我打电话一次”连接,这将很有用;否则我建议在插槽的开头使用 Qobject::disconnect。
此实现通过创建 2 个连接来工作:一个“正常”连接,一个会断开连接并立即清理所有连接。
一个实现(使用 C++11/Qt 5,):
template <typename Func1, typename Func2>
static inline QMetaObject::Connection weakConnect(
typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot)
{
QMetaObject::Connection conn_normal = QObject::connect(sender, signal, receiver, slot);
QMetaObject::Connection* conn_delete = new QMetaObject::Connection();
*conn_delete = QObject::connect(sender, signal, [conn_normal, conn_delete](){
QObject::disconnect(conn_normal);
QObject::disconnect(*conn_delete);
delete conn_delete;
});
return conn_normal;
}
注意事项/需要改进的地方:
QObject::disconnect
,但这会导致小的内存泄漏)测试使用:
class A : public QObject
{
Q_OBJECT
signals:
void sig(int a);
};
class B : public QObject
{
Q_OBJECT
public:
B(int b) : QObject(), b_(b) {}
int b() const { return b_; }
public slots:
void slo(int a) { qDebug() << "\tB :" << b_ << "a:" << a; }
private:
int b_;
};
和
A a1;
A a2;
B b10(10);
B b20(20);
weakConnect(&a1, &A::sig, &b10, &B::slo);
weakConnect(&a1, &A::sig, &b20, &B::slo);
weakConnect(&a2, &A::sig, &b20, &B::slo);
qDebug() << "a1 :"; emit a1.sig(1);// Should trigger b10 and b20 slo
qDebug() << "a2 :"; emit a2.sig(2);// Should trigger b20 slo
qDebug() << "a1 :"; emit a1.sig(3);// Should do nothing
qDebug() << "a2 :"; emit a2.sig(4);// Should do nothing
测试代码输出:
a1 :
B : 10 a: 1
B : 20 a: 1
a2 :
B : 20 a: 2
a1 :
a2 :
摆脱 C++11/Qt5(我没有 Qt 4.8/GCC4.4.7,所以没有用它们进行测试)根据文档,Qt 4.8 没有连接功能,所以我使用包装器:
class ConnectJanitor : public QObject
{
Q_OBJECT
public slots:
void cleanup()
{
QObject::disconnect(conn_normal_);
QObject::disconnect(*conn_delete_);
delete conn_delete_;
delete this;
}
public:
static ConnectJanitor* make(QMetaObject::Connection conn_normal,
QMetaObject::Connection* conn_delete)
{
return new ConnectJanitor(conn_normal, conn_delete);
}
private:
ConnectJanitor(QMetaObject::Connection conn_normal,
QMetaObject::Connection* conn_delete) :
QObject(0) , conn_normal_(conn_normal), conn_delete_(conn_delete) {}
ConnectJanitor(const ConnectJanitor&); // not implemented
ConnectJanitor& operator=(ConnectJanitor const&);
QMetaObject::Connection conn_normal_;
QMetaObject::Connection* conn_delete_;
};
(我将 ConnectJanitor
的构造函数设为私有(private),因为该实例会自毁(删除此
))
对于weakConnect
:
static inline QMetaObject::Connection weakConnect(const QObject * sender, const char * signal, const QObject * receiver, const char * slot)
{
QMetaObject::Connection conn_normal = QObject::connect(sender, signal, receiver, slot);
QMetaObject::Connection* conn_delete = new QMetaObject::Connection();
*conn_delete = QObject::connect(sender, signal, ConnectJanitor::make(conn_normal, conn_delete), SLOT(cleanup()));
return conn_normal;
}
如果您需要手动断开连接,我建议让 weakConnect() 返回 ConnectJanitor 的指针。
关于c++ - 第一次通话后断开插槽的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27019290/
插槽到底是个啥?5分钟搞定 Vue 插槽 插槽的基本使用 组件使用slot标签,显示组件标签的内容 Title aaa Vu
Closed. This question is not reproducible or was caused by typos。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-to
我有一个对象,它用一个对象发出信号: MyObj *obj = this->generateObj(); emit newObjSignal(obj); delete obj; 我有一个或多个人与此有
距离ETS的发布也有一段时间,也有不少小伙伴通过ETS制作出很多精美的页面,但在我查阅ETS的组件和API中发现,现有版本的ETS并没有插槽的功能。经过一段时间的探索终于找到曲线救国方式实现插槽
我无法找到有关使用资源管理器模板以编程方式向 WebApp 添加插槽的信息/指南。我的基本配置运行良好,创建了 WebApp 本身、SQL 服务器、SQL DB 等,但我也渴望完成插槽,以便我可以将它
我们的项目位于 sitecore 中,并使用 Azure - 应用服务进行部署。我们已经创建了暂存槽,除了应用程序设置和连接字符串之外,还希望使一些配置文件槽特定(交换时坚持槽)。 有没有办法让整个配
我使用 Azure 插槽功能来部署我的机器人: 部署到“暂存”槽 Azure 启动此实例 启动后,我会交换“生产”和“登台”时段 我想在进行插槽之前测试暂存实例,最好使用 Azure 门户中的 Web
我使用 Azure 插槽功能来部署我的机器人: 部署到“暂存”槽 Azure 启动此实例 启动后,我会交换“生产”和“登台”时段 我想在进行插槽之前测试暂存实例,最好使用 Azure 门户中的 Web
我的应用程序只能通过右键单击托盘图标并按“退出”来退出: class DialogUIAg(QDialog): ... self.quitAction = QAction("&Quit
我不太确定如何将其总结为一个谷歌问题,但也许详细解释它会给我更好的帮助。 我正在尝试找到与在 PHP 中的 python 中设置槽的等价物 python : class Node: slots
我浪费了几个小时试图找出这个错误,但我仍然不知道为什么会发生...所以我求助于你! 我将一个对象移动到一个线程中,该线程执行一些工作,完成后会发出一个信号以供 QMainWindow 捕获。就这么简单
我有一个自旋控件 block ,它可以更改数组的各个元素我不想使用单独的接收器槽函数,而是只想指定哪个控件在信号中发送消息 您可以使用 QSignalMapper 来做到这一点——但是是否可以像下面那
我想知道如何将一个单独的变量传递到一个插槽中。我似乎无法让它工作。有什么办法解决这个问题吗? 这是我的代码: QTimer * timer = new QTimer(); connect(timer,
我有一个基类,它定义了一个 Qt 插槽 class Base { public: Base() { connect(otherobject, SIGNAL(mySign
这是基类中声明的样子: protected: void indexAll(); void cleanAll(); 在派生类中,以下不编译: indexAll(); // OK con
比如我有一个函数 void A::fun() { do_1(); emit signal_1(); do_2(); emit signal_2(); do_3(
我希望能够将视频从连接到我的计算机的摄像头直接流式传输到我通过 PCIE 连接到我的计算机的 FPGA。 我不介意使用 javascript 或 C# 等高级语言来执行此操作(因为这些是我知道的具有视
Qt世界中,事件和信号/槽的区别是什么? 一个会取代另一个吗?事件是信号/槽的抽象吗? 最佳答案 Qt documentation可能解释得最好: In Qt, events are objects,
1. 监听属性值的变化 - watch 语法要求:watch里面的函数名必须跟date里面属性名一致 {{num}} 添加 var
在 Class Buttons 中,我有一个 btnRightClicked 信号和一个 mousePressEvent 插槽: void Buttons::mousePressEvent(QMous
我是一名优秀的程序员,十分优秀!