如何根据QSignalMapper获取QList的索引

4

我有一个QListQPushButton和一个QSignalMapper来识别哪个按钮被按下了。 所以我做了类似以下的事情(我的项目非常大,所以我只剪切了需要的行数来提问)

QList<QPushButton*> Buttons;
QList <QLabel*> LabelList1;
QList <QLabel*> LabelList2;
QList <QLabel*> LabelList3;
QList <QLabel*> LabelList4;
QSignalMapper *ButtonsMapper;
ButtonsMapper= new QSignalMapper(this);
connect(ButtonsMapper, SIGNAL(mapped(int)),this,SIGNAL(ButtonsClicked(int)));
connect(this, SIGNAL(ButtonsClicked(int)),this,SLOT(deleteButton(int)));

Buttons.append(new QPushButton(tr("0")));//first button 
LabelList1.append(new QLabel(tr("0")));
LabelList2.append(new QLabel(tr("0")));
LabelList3.append(new QLabel(tr("0")));
LabelList4.append(new QLabel(tr("0")));
QPushButton * pb1 = Buttons.last();//pointer to the last button
connect(pb1, SIGNAL(clicked()), ButtonsMapper, SLOT(map()));
ButtonsMapper->setMapping(pb1,0);

Buttons.append(new QPushButton(tr("1")));//second button
LabelList1.append(new QLabel(tr("1")));
LabelList2.append(new QLabel(tr("1")));
LabelList3.append(new QLabel(tr("1")));
LabelList4.append(new QLabel(tr("1"))); 
QPushButton * pb2 = Buttons.last();//pointer to the last button
connect(pb2, SIGNAL(clicked()), ButtonsMapper, SLOT(map()));
ButtonsMapper->setMapping(pb2,1);

当按下deleteButton函数时,预期删除按钮。如果我执行以下操作:

void myclass::deleteButton(int i){ 
   delete (Buttons.takeAt(i));
   delete ( LabelList1.takeAt(i));
   delete ( LabelList2.takeAt(i));
   delete( LabelList3.takeAt(i));
   delete( LabelList4.takeAt(i));
    }

如果我删除第一个按钮,然后按下第二个按钮,那么该函数可能会导致索引超出范围错误,因为函数Buttons.takeAt(i)指向不存在的按钮。

3个回答

1
理论上,您可以保留对信号映射器的指针,并在删除后重新映射索引。
void myclass::deleteButton(int i){
    delete (Buttons.takeAt(i));
    for(int i = 0; i < Buttons.size(); ++i) {
        ButtonsMapper->setMapping(Buttons[i], i);
    }
}

如果我只有一个QList,那就太好了,但是我至少有8个QList需要每次删除... - avi software

0

我建议您对代码进行一些修改:

QMap<QPushButton*,int> Buttons;
QSignalMapper *ButtonsMapper;
ButtonsMapper= new QSignalMapper(this);
connect(ButtonsMapper, SIGNAL(mapped(int)),this,SIGNAL(ButtonsClicked(int)));
connect(this, SIGNAL(ButtonsClicked(int)),this,SLOT(deleteButton(int)));

Buttons.insert (new QPushButton(tr("0")),0);//first button 
QPushButton * pb1 = Buttons.last();//pointer to the last button
connect(pb1, SIGNAL(clicked()), ButtonsMapper, SLOT(map()));
ButtonsMapper->setMapping(pb1,0);

Buttons.insert (new QPushButton(tr("1")),1);//second button 
QPushButton * pb2 = Buttons.last();//pointer to the last button
connect(pb2, SIGNAL(clicked()), ButtonsMapper, SLOT(map()));
ButtonsMapper->setMapping(pb2,1);

void myclass::deleteButton(int i){
    if (Buttons.contains(i))
    delete (Buttons[i]);  
}

QMap 不适合我的项目,我需要数组有组织地排列,不跳过任何元素。 - avi software
类似这样的代码,int index = Buttons.indexOf(ButtonsMapper->mapping(i)); 是无法正常工作的。 - avi software
你为什么需要列表?如果你只需要在点击后删除它,那么你可以使用带有 QObject * 的映射。 - Kamil Klimek
我需要一个列表,有几个原因,比如删除、插入和一些循环通过一些索引。实际上我认为我已经解决了这个问题,但是我不能在这里回答,因为我是新用户... void myclass::deleteButton(int i){ int index = Buttons.indexOf((QPushButton*)ButtonsMapper->mapping(i)); delete (Buttons.takeAt(index)); - avi software
如果QList中没有PushBoton实例,那么这个解决方案将无法正确工作。 - Ruslan F.

0

你可以将QPushButton的映射从索引(int)改为QWidget *

- ButtonsMapper->setMapping(pb1,0);
+ ButtonsMapper->setMapping(pb1, pb1);

然后插槽也会改变

void myclass::deleteButton(QWidget * widget){
    Buttons.removeOne(widget);
    delete widget;  
}

这很好,但不适用于我的项目,因为我有8个QList,并且我想每次按下QPushButton时从每个QList中删除一个单元格...我正在编辑我的问题,以便您可以理解...谢谢。 - avi software

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接