11

在我在这里发帖后:将信号和插槽关联到一个 qcheckbox 动态创建我需要关联:

clicked()当我点击qCheckBox我的功能时的信号cliqueCheckBox(QTableWidget *monTab, int ligne, QCheckBox *pCheckBox)

为此,我必须使用QSignalMapper,经过两个小时的尝试了解它是如何工作的,我不能得到一个好的结果,这是我制作的代码,这显然是错误的:

 QSignalMapper *m_sigmapper = new QSignalMapper(this);
 QObject::connect(pCheckBox, SIGNAL(mapped(QTableWidget*,int, QCheckBox*)), pCheckBox, SIGNAL(clicked()));
 QObject::connect(this, SIGNAL(clicked()), this, SLOT(cliqueCheckBox(QTableWidget *monTab, int ligne, QCheckBox *pCheckBox)));

 m_sigmapper->setMapping(pCheckBox, (monTab,ligne, pCheckBox));
 QObject::connect(m_sigmapper, SIGNAL(clicked()),this, SLOT(cliqueCheckBox(QTableWidget *monTab, int ligne, QCheckBox *pCheckBox)));

你能向我解释一下,它是如何QSignalMapper工作的吗?我真的不明白与什么相关联:(

4

2 回答 2

14

QSignalMapper类收集一组无参数信号,并使用与发送信号的对象相对应的整数、字符串或小部件参数重新发出它们。所以你可以有一个像:

QSignalMapper * mapper = new QSignalMapper(this);
QObject::connect(mapper,SIGNAL(mapped(QWidget *)),this,SLOT(mySlot(QWidget *)));

对于每个按钮,您可以将clicked()信号连接到map()插槽QSignalMapper并使用 setMapping 添加映射,以便在clicked()从按钮发出信号时mapped(QWidget *)发出信号:

QPushButton * but = new QPushButton(this);

QObject::connect(but, SIGNAL(clicked()),mapper,SLOT(map()));
mapper->setMapping(but, but);

这样,每当您单击按钮时,mapped(QWidget *)都会发出映射器的信号,其中包含小部件作为参数。

于 2014-06-17T10:16:47.963 回答
13

首先,我将向您解释如何QSignalMapper工作。然后我会解释你为什么不需要它。

工作原理QSignalMapper

创建 s QSignalMapper。假设您要为每个复选框分配一个整数值,因此每次单击任何复选框时,您都会收到一个分配有整数值的信号。

将映射器信号连接到您将实现的 SLOT:

connect(mapper, SIGNAL(mapped(int)), this, SLOT(yourSlot(int)));

现在您可以编写插槽,它将采用整数参数。对于您拥有的每个复选框,参数都会有所不同。

创建复选框时,对于每个复选框,您需要执行以下操作:

mapper->setMapping(checkBox, integerValueForThisCheckbox);
connect(checkBox, SIGNAL(clicked()), mapper, SLOT(map()));

从现在开始,每次单击复选框时,它都会clicked()向 发出信号QSignalMapper,然后将其映射到分配的整数值并发出mapped()信号。您连接到该mapped()信号,因此yourSlot(int)将使用正确的整数值调用。

QString您可以分配,QWidget*QObject*(参见 Qt 文档) ,而不是整数。

这就是QSignalMapper工作方式。

你不需要它:

  • QTableWidget *monTab单个对象,它不会改变。将其保留为类成员字段并从您的插槽函数中使用它。
  • -QCheckBox *pCheckBox你可以通过强制转换sender()来获得它QCheckBox*

像这样:

void supervision::yourSlot()
{
    QCheckBox* pCheckBox = qobject_cast<QCheckBox*>(sender());
    if (!pCheckBox) // this is just a safety check
        return;
}

sender()函数是 from QObject,您确实继承自它,因此您可以访问它。

  • int linge它是行号,对吗?) - 当您创建复选框时,您可以在类字段中存储指向该复选框的指针,QList并从您的插槽函数中使用它找出它是哪一行,如下所示:

在类声明中:

private:
    QList<QCheckBox*> checkboxes;

创建复选框时:

QCheckBox* cb = new QCheckBox();
checkboxes << cb;

在您的插槽功能中:

void supervision::yourSlot()
{
    QCheckBox* pCheckBox = qobject_cast<QCheckBox*>(sender());
    if (!pCheckBox) // this is just a safety check
        return;

    int linge = checkboxes.indexOf(pCheckBox);
}

如果需要,您可以跳过它QListQSignalMapper使用映射器使用并将行分配给复选框。这只是你喜欢什么的问题。

于 2014-06-17T10:07:54.603 回答