PDA

View Full Version : Signal Slot Question



graciano
16th August 2009, 12:03
Hi,
This must be a basic question but here it goes.

#include "txtedit.h"
#include "ui_txtedit.h"

txtEdit::txtEdit(QWidget *parent) :
QGroupBox(parent),
m_ui(new Ui::txtEdit)
{
m_ui->setupUi(this);

listStringList = new QStringList;
listModel = new QStringListModel(this);
listModel->setStringList(*listStringList);
m_ui->listView->setModel(listModel);
...
connect(m_ui->sortAscendingButton, SIGNAL(clicked(bool)), this, SLOT(sortStringList(bool)));
connect(m_ui->sortDescendingButton, SIGNAL(clicked(bool)), this, SLOT(sortStringList(bool)));
}

...


void txtEdit::sortStringList(bool order)
{
if(order)
listModel->sort(0, Qt::AscendingOrder);
else
listModel->sort(0, Qt::DescendingOrder);
}


I want the buttons in lines 15 e 16 to send a true or false value to the sortStringList slot.
How do i manage this?
Thansks

Boron
16th August 2009, 17:23
Read "Advanced Signals and Slots Usage": http://doc.trolltech.com/4.5/signalsandslots.html#advanced-signals-and-slots-usage

Lykurg
16th August 2009, 21:15
In your special case a QButtonGroup with setExclusive(true) would do also a great job.

graciano
17th August 2009, 15:32
I wasn't able to do it with the QButtonGroup so i did this:

sortListSignalMapper = new QSignalMapper(this);
sortListSignalMapper->setMapping(m_ui->sortAscendingButton, QString("Ascending"));
sortListSignalMapper->setMapping(m_ui->sortDescendingButton, QString("Descending"));
connect(m_ui->sortAscendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(m_ui->sortDescendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(sortListSignalMapper, SIGNAL(mapped(QString)), this, SLOT(sortStringList(QString)));

Looks like i can not use bool in this situation.
Thanks

Lykurg
17th August 2009, 21:54
Ok,

with the mapper you can use the "int option". 1 = true and 0 = false.



//not tested but should work
sortListSignalMapper = new QSignalMapper(this);
sortListSignalMapper->setMapping(m_ui->sortAscendingButton, 1);
sortListSignalMapper->setMapping(m_ui->sortDescendingButton, 0);
connect(m_ui->sortAscendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(m_ui->sortDescendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(sortListSignalMapper, SIGNAL(mapped(int)), this, SLOT(sortStringList(bool)));

And with the button group you could simply use:

// use the buttonClicked(QAbstractButton *button) signal to connect to your slot
void txtEdit::sortStringList(QAbstractButton *button)
{
if(button == m_ui->sortAscendingButton)
listModel->sort(0, Qt::AscendingOrder);
else
listModel->sort(0, Qt::DescendingOrder);
}
// or if you need a bool function beside
void txtEdit::sortStringList(QAbstractButton *button)
{
return sortStringList(button == m_ui->sortAscendingButton);
}

graciano
18th August 2009, 09:20
Hi,
I remember trying your first option.
I geted a ...

QObject::connect: Incompatible sender/receiver arguments
QSignalMapper::mapped(int) --> txtEdit::sortStringList(bool)
But now you gave me an idea...


sortListSignalMapper = new QSignalMapper(this);
sortListSignalMapper->setMapping(m_ui->sortAscendingButton, 1);
sortListSignalMapper->setMapping(m_ui->sortDescendingButton, 0);
connect(m_ui->sortAscendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(m_ui->sortDescendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(sortListSignalMapper, SIGNAL(mapped(int)), this, SLOT(sortStringList(int)));

...and it worked fine.
This way order is an integer and it's value is evaluated as an "bool" in the condition.
Thanks

Lykurg
18th August 2009, 11:52
if you want that your code is readable (and understandable) later, you could also use Qt::AscendingOrder and Qt::DescendingOrder:


sortListSignalMapper = new QSignalMapper(this);
sortListSignalMapper->setMapping(m_ui->sortAscendingButton, Qt::AscendingOrder);
sortListSignalMapper->setMapping(m_ui->sortDescendingButton, Qt::DescendingOrder);
connect(m_ui->sortAscendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(m_ui->sortDescendingButton, SIGNAL(clicked()), sortListSignalMapper, SLOT(map()));
connect(sortListSignalMapper, SIGNAL(mapped(int)), this, SLOT(sortStringList(int)));
//...
void xxx::sortStringList(int order)
{
switch(order)
{
case Qt::DescendingOrder:
//...
break;
case Qt::AscendingOrder:
default:
//...
break;
}
}


EDIT:
QObject::connect: Incompatible sender/receiver arguments
QSignalMapper::mapped(int) --> txtEdit::sortStringList(bool)
Ok, thought Qt would cast internally.:rolleyes:

axeljaeger
18th August 2009, 22:25
You can also connect both to a slot and evaluate sender() in that slot to see which button was clicked and therefore which method to execute.

graciano
19th August 2009, 10:35
Looks like there is a warning about this subject( http://doc.trolltech.com/4.5/qobject.html#sender )

Warning: This function violates the object-oriented principle of modularity. However, getting access to the sender might be useful when many signals are connected to a single slot.
I will try ti stick to the "principle of modularity" in order not to get lost ;)
Thanks for the tip.