Qt 将参数传递给插槽
我想用一堆Qaction和QMenus覆盖mouseReleaseEventQt 将参数传递给插槽,qt,qsignalmapper,qt-slot,Qt,Qsignalmapper,Qt Slot,我想用一堆Qaction和QMenus覆盖mouseReleaseEvent connect(action1, SIGNAL(triggered()), this, SLOT(onStepIncreased())); connect(action5, SIGNAL(triggered()), this, SLOT(onStepIncreased())); connect(action10, SIGNAL(triggered()), this, SLOT(onStepIncreased()))
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()));
因此,我想将一个参数传递到slotonsteppereduced
(可以想象它们是1,5,10,25,50)。你知道我怎么做吗?该函数返回一个指向已向插槽发出信号的对象的指针。您可以使用它来找出触发了哪个操作。像这样:
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))) ;
也许您可以使用m_increase成员变量将QAction子类化。
将triggered()信号连接到新QAction子类上的插槽,并使用正确的参数发出新信号(例如triggered(int number))。
e、 g
使用Qt5和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); });
connect
的第三个参数名义上是可选的。它用于设置执行函子的线程上下文。当函子使用QObject
实例时,它总是必需的。如果functor使用多个QObject
实例,则它们应该有一些管理其生存期的公共父对象,并且functor应该引用该父对象,或者应该确保对象比functor更长寿
在Windows上,这适用于MSVC2012及更新版本。QVector W(100);
QVector<QAction*> W(100);
W[1]= action1;
W[5]= action5;
W[10]= action10;
W[25]= action25;
W[50]= action50;
for (int i=0; i<100; ++i)
{
QSignalMapper* signalmapper = new QSignalMapper();
connect (W[i], SIGNAL(triggered()), signalmapper, SLOT(map())) ;
signalmapper ->setMapping (W[i], i);
connect (signalmapper , SIGNAL(mapped(int)), this, SLOT(onStepIncreased(int)));
}
W[1]=动作1;
W[5]=动作5;
W[10]=行动10;
W[25]=行动25;
W[50]=行动50;
对于(int i=0;isetMapping(W[i],i);
连接(信号映射器,信号映射器(int)),此,插槽(onsteppereduced(int));
}
您可以使用std::bind
这是一个功能对象适配器,允许将功能对象适配到给定数量的参数
例如,您创建自己的聊天服务器。它包含两个类:ChatServer和ServerWorker
ChatServer是QTcpServer类,ServerWorker是QTcpSocket(管理服务器端的套接字)
ServerWorker标头中的信号:
void error();
在ChatServer标头中定义以下专用插槽:
void userError(ServerWorker *sender);
在cpp文件中创建这些对象,并在套接字连接后运行的incomingConnection
方法中,使用std::bind
连接插槽和信号:
void ChatServer::incomingConnection(qintptr socketDescriptor)
{
//some code
connect(worker, &ServerWorker::error, this, std::bind(&ChatServer::userError, this, worker));
}
std::bind
创建一个带有固定参数的函子。例如connect(worker,&ServerWorker::error,this,std::bind(&ChatServer::userError,this,worker));
将导致this->userError(worker)
;在每次worker发出错误信号时调用
userErrorslot
每次连接到客户端的套接字遇到错误时都会执行。它具有以下签名:
void ChatServer::userError(ServerWorker *sender)
{
//some code
}
请原谅?该插槽是QObject子类的成员,因此它还有一个QObject::sender()成员。只需调用sender(),您将获得一个指向您的操作的QObject*。之后,您可以使用objectName()或property()收集更多信息的已获取操作。如果确实需要,您也可以将其转换为操作对象,但我不建议这样做。我仍然记得,Qt没有QSignalMapper,唯一的解决方案是在连接到同一插槽的对象上设置属性,并使用sender()->property(…)@Kamil Klimek您不必这样做;您可以编写自己的映射程序:)如果我的
上下文参数将一个对象指向一个无法访问操作的类,那么如何使用它?因此,context
signalmapper将无法访问操作,或者如果我将signalmapper放入同一个类,则连接槽的上下文将是错误的。值得注意的是(2018年,Qt5,C++11),QSignalMapper已被弃用。从这个链接中可以看出:“这个类是过时的。它是为了保持旧的源代码工作。我们强烈建议不要在新代码中使用它。”下面的“KuBA”的答案现在是更好的。代替传递参数,考虑分析SENDE()。在信号内部。C++11 lambdas和Qt 5将函子连接到信号的能力的结合是非常有用的,但被低估了。我根据我的情况调整了这个解决方案。但是,如果我使用信号(triggered(bool))
而不是&QAction::triggered
,它会抛出一个错误。谁能给我解释一下为什么?它不会“抛出”错误。编译器会抱怨,错误消息应该告诉您原因:没有QObject::connect
重载将const char*
作为第二个参数,将函子作为第三个或第四个参数。Qt4样式connect
语法与新语法不兼容。如果您希望使用旧语法,那么您将失去连接到函子的便利性(即使如果您使用的是C++11编译器,但使用的是Qt4,也可能是近似的)。
void ChatServer::userError(ServerWorker *sender)
{
//some code
}