PDA

View Full Version : Tracing signals.



johnny_sparx
12th April 2006, 20:44
Hello,

I am having trouble tracing signals and slots in my application. I have a function that is being called once a tree view has changed. It seems to be called three times however. I want to identify who is emitting the replicated signal so I can block them appropriately.

How do I do this?

I suppose this is a more general question about debugging signals/slots in Qt.

John.

jacek
12th April 2006, 21:05
QObject::sender()

http://qt4.digitalfanatics.org/articles/signalspy.html
http://doc.trolltech.com/4.1/qsignalspy.html

johnny_sparx
12th April 2006, 21:25
I can use the signal spy you suggested, but can't help but to think that this should be solved by inspection.

I suppose I am not fully aware of which signals are emitted when in my tree view. For example, I did not know that a signal is emitted when the color of a tree leaf is changed.

J.

johnny_sparx
12th April 2006, 21:54
Are there a special way to configure Qt so that it can use the spy?

#include <QSignalSpy>

can't be found, and neither can <QTest>.

how can I configure Qt to use the spy?:confused:

jacek
12th April 2006, 22:04
CONFIG += qtestlib

johnny_sparx
12th April 2006, 22:37
This worked, thank you.

Now I have A QSignalSpy pointer in my class. I instantiated it:

Signal_Spy = new SignalSpy(Acquisition_Browser->DICOM_Header_Tree,SIGNAL(itemChanged(QTreeWidgetIt em*,int)) );

I simply do not know how to identify the signal's origin at this point....


Signal_Spy->sender()->objectName();

was my first instinct in order to extract the name of the object whose signal was the trigger. "sender()" however, is protected. So how do I identify the signal's source?

(This is very new to me!).


J

jacek
12th April 2006, 22:50
Now I have A QSignalSpy pointer in my class.
I think that this signal spy ( http://qt4.digitalfanatics.org/articles/signalspy.html) will be more helpful.


Signal_Spy->sender()->objectName();
You don't need a singnal spy for this --- just use sender() within your slot.

johnny_sparx
12th April 2006, 23:05
jacek, thanks alot - you seem to help me out alot on this forum...

I am still questionning though. I was able to use sender directly as you proposed, and it identifies the object that emitted the signals. But I need to know which actions were performed in order to emit the signal to my slot.

I am looking at itemChanged from QTreeView. Is it a setTextColor? is it a setData? I already know the object, but need more details. :crying:

jacek
12th April 2006, 23:20
Set a breakpoint in the slot and see the stack trace.

wysota
12th April 2006, 23:40
I am looking at itemChanged from QTreeView. Is it a setTextColor? is it a setData? I already know the object, but need more details. :crying:

setData(). setTextColor is just a setData wrapper defined as:


inline void setTextColor(int column, const QColor &color)
{ setData(column, Qt::TextColorRole, color); }

Which is easy to guess by the way, as it has to be QTreeView method which emits the signal and only one that does allow an item to be changed (and emits a signal) is QAbstractItemModel::setData().

johnny_sparx
13th April 2006, 23:42
Okay.... now I have narrowed things down.... it IS the setColor that is emitting the signal. Weirdly, I have blocked the signals before I change the signals (see top and bottom of the function:


#define BLOCK_SIGNALS blockSignals(TRUE)
#define ALLOW_SIGNALS blockSignals(FALSE)



void AcquisitionBrowserWidget::Read_Only_Checked(bool value)
{
BLOCK_SIGNALS;
// Change the state of the 'Update Header' button appropriately.
Acquisition_Browser->Update_Header_Button->setEnabled(!value);
// If 'Read only' checkbox is not checked (edit possible), then the
// editable fields should be dark green otherwise, it should be black.
if(!value)
{
// Change the color of the editable fields to green.
DICOM_Information__Patient_Information__Name->setTextColor(1,QColor(Qt::darkGreen));
DICOM_Information__Patient_Information__ID->setTextColor(1,Qt::darkGreen);
DICOM_Information__Study__Description->setTextColor(1,Qt::darkGreen);
DICOM_Information__Study__UID->setTextColor(1,Qt::darkGreen);
DICOM_Information__Series__Description->setTextColor(1,Qt::darkGreen);
DICOM_Information__Series__UID->setTextColor(1,Qt::darkGreen);

// Set the fields so that they are not editable.
DICOM_Information__Patient_Information__Name->setFlags(Qt::ItemIsEditable);
DICOM_Information__Patient_Information__ID->setFlags(Qt::ItemIsEditable);
//DICOM_Information__Study__Description->setFlags(Qt::ItemIsEditable);
DICOM_Information__Study__UID->setFlags(Qt::ItemIsEditable);
//DICOM_Information__Series__Description->setFlags(Qt::ItemIsEditable);
DICOM_Information__Series__UID->setFlags(Qt::ItemIsEditable);

Acquisition_Browser->Update_Header_Button->setIcon(QIcon("greenball.png"));
DICOM_Tree_Data_Changed = false;
DICOM_Tree_Data_Updated = false;
}
else
{
// Change the color of the editable fields to black.
DICOM_Information__Patient_Information__Name->setTextColor(1,QColor(Qt::black));
DICOM_Information__Patient_Information__ID->setTextColor(1,Qt::black);
DICOM_Information__Study__Description->setTextColor(1,Qt::black);
DICOM_Information__Study__UID->setTextColor(1,Qt::black);
DICOM_Information__Series__Description->setTextColor(1,Qt::black);
DICOM_Information__Series__UID->setTextColor(1,Qt::black);

// Set the fields so that they are not editable.
DICOM_Information__Patient_Information__Name->setFlags(!Qt::ItemIsEditable);
DICOM_Information__Patient_Information__ID->setFlags(!Qt::ItemIsEditable);
DICOM_Information__Study__UID->setFlags(!Qt::ItemIsEditable);
DICOM_Information__Series__UID->setFlags(!Qt::ItemIsEditable);

// If the data changed, then notify the user.
if(DICOM_Tree_Data_Updated && DICOM_Tree_Data_Changed)
{
QMessageBox::information(this,"DICOM Inspector Warning","The DICOM information has changed but was not updated.");
}
// Update the colored indicator on the button.
ALLOW_SIGNALS;
}


Have I done this incorrectly? It seems like the color change is the trigger for my problems.:eek:

jacek
14th April 2006, 00:18
You have blocked signals only for AcquisitionBrowserWidget.