将参数传递给插槽

Fat*_*lan 71 qt qsignalmapper qt-slot

我想用一堆QActions和QMenus覆盖mouseReleaseEvent ...

connect(action1, SIGNAL(triggered()), this, SLOT(onStepIncreased()));

connect(action5, SIGNAL(triggered()), this, SLOT(onStepIncreased()));

connect(action10, SIGNAL(triggered()), this, SLOT(onStepIncreased()));

connect(action25, SIGNAL(triggered()), this, SLOT(onStepIncreased()));

connect(action50, SIGNAL(triggered()), this, SLOT(onStepIncreased()));
Run Code Online (Sandbox Code Playgroud)

所以我想把一个参数传递给插槽onStepIncreased(你可以想象它们是1,5,10,25,50).你知道我怎么做吗?

Ton*_*nyK 113

使用QSignalMapper.像这样:

QSignalMapper* signalMapper = new QSignalMapper (this) ;
connect (action1, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action5, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action10, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action25, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action50, SIGNAL(triggered()), signalMapper, SLOT(map())) ;

signalMapper -> setMapping (action1, 1) ;
signalMapper -> setMapping (action5, 5) ;
signalMapper -> setMapping (action10, 10) ;
signalMapper -> setMapping (action25, 25) ;
signalMapper -> setMapping (action50, 50) ;

connect (signalMapper, SIGNAL(mapped(int)), this, SLOT(onStepIncreased(int))) ;
Run Code Online (Sandbox Code Playgroud)


Rei*_*ica 112

使用Qt 5和C++ 11编译器,执行此类操作的惯用方法是使用以下函数connect:

connect(action1,  &QAction::triggered, this, [this]{ onStepIncreased(1); });
connect(action5,  &QAction::triggered, this, [this]{ onStepIncreased(5); });
connect(action10, &QAction::triggered, this, [this]{ onStepIncreased(10); });
connect(action25, &QAction::triggered, this, [this]{ onStepIncreased(25); });
connect(action50, &QAction::triggered, this, [this]{ onStepIncreased(50); });
Run Code Online (Sandbox Code Playgroud)

第三个参数connect名义上是可选的.它用于设置仿函数将在其中执行的线程上下文.当函子使用QObject实例时总是需要的.如果函子使用多个QObject实例,那么它们应该有一些共同的父级来管理它们的生命周期,而仿函数应该引用那个父级,或者应该确保这些对象比这个对象更长.

在Windows上,这适用于MSVC2012及更高版本.

  • 这种C++ 11 lambdas和Qt 5将仿函数连接到信号的能力的组合是一种非常有用但却被低估的特性. (7认同)

kin*_*nak 12

QObject::sender()函数返回指向已通知槽的对象的指针.您可以使用它来找出触发了哪个操作

  • 请再说一遍?该插槽是QObject子类的成员,因此它也具有QObject :: sender()成员。只需调用sender(),您将获得一个指向您的操作的QObject *。之后,您可以使用获取的操作的objectName()或property()来收集更多信息。如果确实需要,也可以将其转换为动作对象,但我不建议这样做。 (2认同)