Qt QSignalMapper 正在为地图中的每个项目发出信号
Qt QSignalMapper is emitting a signal for every item in the map
我有一个函数可以接收我创建的 class 的 QList。我们称这个假设为 class "Stuff"。所以,这个函数接收到一个 QList of Stuff
我遍历 QList,根据 "Stuff" 对象的属性,我将生成以下内容之一:
1) QLineEdit
2) QCheckBox
3) QComboBox
这不是实际的代码,但我实际上是这样做的:
void MyProgram::update(QList<Stuff> myStuffs)
{
this->mSignalMapper = new QSignalMapper();
foreach (Stuff stuff, myStuffs)
{
if (stuff.isInt())
{
QLineEdit* input = new QLineEdit();
//There is code here to setup the QLineEdit and fill an initial value
verticalLayout->addWidget(input); //verticalLayout is QVBoxLayout
QObject::connect(input, SIGNAL(editingFinished()), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
/*
* NOTE: the stuff.getMappingId() function returns an int that is unique
* to that stuff object. I'm 100% sure each stuff object is getting
* a unique mapping ID */
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
else if (stuff.isBool())
{
QCheckBox* input = new QCheckBox();
//There is code here to setup the QCheckBox and set an initial value
verticalLayout->addWidget(input);
QObject::connect(input, SIGNAL(stateChanged(int)), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
else if (stuff.isStringList())
{
QComboBox* input = new QComboBox();
//There is code here to setup the QComboBox and fill in values for the combo box
verticalLayout->addWidget(input);
QObject::connect(input, SIGNAL(activated(int)), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
}
}
问题是,如果我通过编辑 QLineEdit、选中复选框或更改组合框值来触发 Widget 的信号之一,onStuffChanged(int) 函数将被调用 N 次,其中 N = mSignalMapper 映射的数量。
这是怎么回事?如果我遍历并创建 10 个小部件,则仅单击 10 个小部件中的 1 个会调用该函数 10 次,而这 10 次中的每一次都会传递与我交互的 1 个对象关联的唯一 int。因此,如果 10 个小部件中的第一个是唯一 int ID 为 27 的复选框,则 onStuffChanged(int) 函数将被调用 10 次,每次调用参数为 27。
问题出在这一行:
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
您正在建立相同的连接 N 次(N = 您的 "stuff" 计数),因此每一个 mapped()
信号也会触发 onStuffChanged(int)
插槽 N 次。
解法:
将此行移到循环外,只调用一次。
我有一个函数可以接收我创建的 class 的 QList。我们称这个假设为 class "Stuff"。所以,这个函数接收到一个 QList of Stuff
我遍历 QList,根据 "Stuff" 对象的属性,我将生成以下内容之一:
1) QLineEdit
2) QCheckBox
3) QComboBox
这不是实际的代码,但我实际上是这样做的:
void MyProgram::update(QList<Stuff> myStuffs)
{
this->mSignalMapper = new QSignalMapper();
foreach (Stuff stuff, myStuffs)
{
if (stuff.isInt())
{
QLineEdit* input = new QLineEdit();
//There is code here to setup the QLineEdit and fill an initial value
verticalLayout->addWidget(input); //verticalLayout is QVBoxLayout
QObject::connect(input, SIGNAL(editingFinished()), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
/*
* NOTE: the stuff.getMappingId() function returns an int that is unique
* to that stuff object. I'm 100% sure each stuff object is getting
* a unique mapping ID */
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
else if (stuff.isBool())
{
QCheckBox* input = new QCheckBox();
//There is code here to setup the QCheckBox and set an initial value
verticalLayout->addWidget(input);
QObject::connect(input, SIGNAL(stateChanged(int)), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
else if (stuff.isStringList())
{
QComboBox* input = new QComboBox();
//There is code here to setup the QComboBox and fill in values for the combo box
verticalLayout->addWidget(input);
QObject::connect(input, SIGNAL(activated(int)), this->mSignalMapper, SLOT(map()));
this->mSignalMapper->setMapping(input, stuff.getMappingId());
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
}
}
}
问题是,如果我通过编辑 QLineEdit、选中复选框或更改组合框值来触发 Widget 的信号之一,onStuffChanged(int) 函数将被调用 N 次,其中 N = mSignalMapper 映射的数量。
这是怎么回事?如果我遍历并创建 10 个小部件,则仅单击 10 个小部件中的 1 个会调用该函数 10 次,而这 10 次中的每一次都会传递与我交互的 1 个对象关联的唯一 int。因此,如果 10 个小部件中的第一个是唯一 int ID 为 27 的复选框,则 onStuffChanged(int) 函数将被调用 10 次,每次调用参数为 27。
问题出在这一行:
QObject::connect(this->mSignalMapper, SIGNAL(mapped(int)), this, SLOT(onStuffChanged(int)));
您正在建立相同的连接 N 次(N = 您的 "stuff" 计数),因此每一个 mapped()
信号也会触发 onStuffChanged(int)
插槽 N 次。
解法: 将此行移到循环外,只调用一次。