Signal/Slot Connections

Investiagte issues regarding signal/slot connection handling.

This examples shows GammaRay's capabilities in analyzing signal/slot connection problems.

Problem

The application shows two buttons and a LCD widget. The LCD widget is connected to the clicked() signal of the first button and increments every time the clicked() signal is emitted. The second button recreates the connection.

Clicking the reconnect button multiple times however breaks things, so that clicking the emit button will result in more than on increment of the LCD widget.

auto layout = new QVBoxLayout(this);
m_emitButton = new QPushButton("Emit Signal", this);
layout->addWidget(m_emitButton);
connect(m_emitButton, &QPushButton::clicked, this, &Widget::signalEmitted);

auto reconnectButton = new QPushButton("Reconnect Signal", this);
layout->addWidget(reconnectButton);
connect(reconnectButton, &QPushButton::clicked, this, &Widget::reconnectSignal);

m_counter = new QLCDNumber(this);
layout->addWidget(m_counter);

Investigation

There are several aspects of this problem that can be analyzed with GammaRay.

Watch a signal emission

Select the emit button in the Object Browser or the Widget Inspector tool, and open the Methods tab on the right. Find the clicked() signal in the method list, and chose Connect to in the context menu. Clicking on the emit button will now show each emitted clicked() signal in the method log at the bottom half on the right side. This allows you to verify that the signal is emitted correctly, and here in particular is only emitted once per click.

Alternatively, you can also observe this in the Signal Plotter view.

Check existing signal/slot connections

Select the emit button in the Object Browser or the Widget Inspector tool, and open the Connections tab on the right. The list of outbound connections at the bottom half will show all existing connections to the LCD widget incrementing code. You will notice that multiple connections to the same slot exist, and that GammaRay shows a warning icon for this.

Looking at the reconnection slot we then see that the code mixes string based and function pointer based connect()/disconnect() calls, which is not supported by QObject:

disconnect(m_emitButton, &QPushButton::clicked, this, &Widget::signalEmitted);
connect(m_emitButton, &QAbstractButton::clicked, this, &Widget::signalEmitted);

This code therefore adds another connection each time its called, resulting in multiple increments in the LCD widget per emit button click.

Files: