PDA

View Full Version : QSignalMapper problems



ChiBriTri
16th September 2014, 02:00
Hi,

I am having problems with slots getting called multiple times. Each time I add another mapping, the slot gets called n+1 times - where n is the previous number of times called. Made a very simple demo program - can someone tell me what I'm doing wrong here?

Project is a qtreewidget that starts with one button to add a top level item. Each top level item adds a button to add a child. Adding a top level always just adds one (not part of the mapping), but adding a child has exponential growth. Assuming I'm somehow inserting it into the mapping in a looping manner, but just can't seem to figure out where.

testwidget.h


#pragma once
#include "qwidget.h"
#include "qsignalmapper.h"

class QTreeWidget;
class QTreeWidgetItem;
class FilterGroup;
class FilterGroupWidget;

class TestWidget: public QWidget
{
Q_OBJECT

public:
TestWidget(QWidget* pParent);

private Q_SLOTS:
void addNewFilter();
void addChildFilter(QWidget *pItem);

private:
void updateRow(QTreeWidgetItem *pRow);

QTreeWidget *m_pTree;
QSignalMapper m_Mapper;
};


testwidget.cpp


#include "stdafx.h"
#include "TestWidget.h"
#include "QtWidgets\qboxlayout.h"
#include "FilterColumns.h"
#include "qtreewidget.h"
#include "qheaderview.h"
#include "FilterTypeWidgets.h"
#include "FilterWidget.h"

TestWidget::TestWidget(QWidget* pParent):QWidget(pParent)
{
auto pMainLayout=new QVBoxLayout();
m_pTree=new QTreeWidget();
m_pTree->setColumnCount(1);

auto pRow=new QTreeWidgetItem();
m_pTree->insertTopLevelItem(0, pRow);

auto pAdd=new QPushButton();
pAdd->setText("Add top level");
m_pTree->setItemWidget(pRow, 0, pAdd);

connect(pAdd, &QPushButton::clicked, this, &TestWidget::addNewFilter);

setLayout(pMainLayout);
pMainLayout->setMargin(0);
pMainLayout->addWidget(m_pTree);
}


void TestWidget::addNewFilter()
{
auto pRow=new QTreeWidgetItem();
m_pTree->insertTopLevelItem(m_pTree->topLevelItemCount() - 1, pRow);

updateRow(pRow);
}

void TestWidget::addChildFilter(QWidget *pItem)
{
auto pParent=(QTreeWidgetItem *)pItem;
auto pRow=new QTreeWidgetItem();

pParent->addChild(pRow);
pParent->setExpanded(true);

updateRow(pRow);
}

void TestWidget::updateRow(QTreeWidgetItem *pRow)
{
auto pWidget=new QPushButton("add child");
auto test=connect(pWidget, SIGNAL(clicked()), &m_Mapper, SLOT(map()));
m_Mapper.setMapping(pWidget, (QWidget *)pRow);

connect(&m_Mapper, SIGNAL(mapped(QWidget *)), this, SLOT(addChildFilter(QWidget *)));

m_pTree->setItemWidget(pRow, 0, pWidget);
}

anda_skoa
16th September 2014, 07:12
In line 56 you call connect from the mapper to a slot.
Every time updateRow() is called.
So obviously you get as many connections as updateRow() calls.

You probably want to connect only once, e.g. in the constructor.

Cheers,
_