我想用一堆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()));
所以我想把一个参数传递给插槽onStepIncreased
(你可以想象它们是1,5,10,25,50)。你知道我怎么做吗?
答案 0 :(得分:111)
使用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))) ;
答案 1 :(得分:103)
使用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); });
connect
的第三个参数名义上是可选的。它用于设置仿函数将在其中执行的线程上下文。仿函数使用QObject
实例时总是需要的。如果仿函数使用多个QObject
个实例,那么它们应该有一些共同的父级来管理它们的生命周期,而仿函数应该引用那个父级,或者应该确保这些对象能够比仿函数更长。
在Windows上,这适用于MSVC2012&新。
答案 2 :(得分:11)
QObject::sender()
函数返回指向已发信号通知到插槽的对象的指针。您可以使用它来找出触发了哪个动作
答案 3 :(得分:1)
也许您可以使用m_increase成员变量对QAction进行子类化
将triggered()信号连接到新QAction子类的插槽,并使用正确的参数发出新信号(例如,trigger(int number))。
例如
class MyAction:public QAction
{
public:
MyAction(int increase, ...)
:QAction(...), m_increase(increase)
{
connect(this, SIGNAL(triggered()), this, SLOT(onTriggered()));
}
protected Q_SLOTS:
void onTriggered()
{
emit triggered(m_increase);
}
Q_SIGNALS:
void triggered(int increase);
private:
int m_increase;
};
答案 4 :(得分:0)
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)));
}
答案 5 :(得分:0)
您可以使用 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)
;每次工作人员发出错误信号时都会调用。
userErrorslot
每次连接到客户端的套接字遇到错误时都会执行。它有签名:
void ChatServer::userError(ServerWorker *sender)
{
//some code
}