PDA

View Full Version : Emit signal from const function



waynew
22nd August 2010, 02:30
Seems like this has been beat to death in past posts, but I can't seem to figure out how to apply a solution to my problem.

I have a table view in a form built with designer. 2 columns have item delegates to provide combo boxes to limit the choices of entry values. The problem I have is in trying to limit the choices of the second column based on what is chosen from the combo box in the first column. The solution seemed to be to emit a signal from column 1 when the value was edited. Then receive the value in a slot in the column 2 delegate and use the received value to limit the combo box choices in column 2.

Problem is that the setModelData function in column 1 won't work unless it is declared const. Then you can't emit a signal from it. In one post Wysota said, declare the slot const too. Tried that but it still gets the same compile error about discards qualifiers.

Here is the relevant part of the code - column 1 delegate with signal:


void ModeDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const
{
QComboBox* comboBox = static_cast<QComboBox*>(editor);
QString value = comboBox->currentText();

qDebug() << "mode delegate data is " << value;
emit modeChanged(value); // CAUSES THE COMPILE ERROR
model->setData(index, value, Qt::EditRole);
}


Here is the slot in column 2 delegate:


void FilterDelegate::getMode(QString value) const
{
qDebug() << "mode value received is " << value;
}


Is there a way around this, or another way I can get the column 1 selected value to column 2?

norobro
22nd August 2010, 05:28
You could get the value from column 1 of your model in your column 2 delegate. Something like this:

void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const //column 2 delegate
{
QString column_one_value = index.model()->data(index.model()->index(index.row(), index.column()-1));
// then adjust your combobox model here

HTH

Lykurg
22nd August 2010, 08:10
Or in a little bit simpler syntax
QString columnOneValue = index.sibling(index.row, 1).value().toString();

stampede
22nd August 2010, 11:01
Is there a way around this (...)
In general, you may try something like :

const_cast< MyClass* >(this)->emit mySignal();

Lykurg
22nd August 2010, 12:11
In general, you may try something like :

const_cast< MyClass* >(this)->emit mySignal();
No we wont, since emit or Q_EMIT is a keyword/marco and not a member of a class.

Lykurg
22nd August 2010, 12:21
Just for record, even if you don't need it in your case you can make the signal const. This works for me:
#include <QtGui>

class test : public QObject
{
Q_OBJECT

public:
void emitSignal() const
{
Q_EMIT sig("This is a test!");
}

Q_SIGNALS:
void sig(const QString&) const;

public Q_SLOTS:
void slot(const QString& str) const
{
qWarning() << Q_FUNC_INFO << str;
}
};


int main(int argc, char *argv[])
{
QApplication app(argc, argv);

test t;
QObject::connect(&t, SIGNAL(sig(const QString&)), &t, SLOT(slot(const QString&)));
t.emitSignal();

return 0;
// return app.exec();
}

#include "main.moc"

yakin
22nd August 2010, 12:30
No we wont, since emit or Q_EMIT is a keyword/marco and not a member of a class.

but you can call
const_cast< MyClass* >(this)->mySignal();

emit is not necessary cause the SIGNALS are just method declarations.

But if there is a better way, avoid to manipulate the constness with const_cast.

Lykurg
22nd August 2010, 12:44
but you can call
const_cast< MyClass* >(this)->mySignal();
Yes, sorry, you are right! I was confused about the notation with the keyword.

waynew
22nd August 2010, 13:09
Thanks for your help folks. Got it working by reading the previous column with your suggestions.
As usual, trying to make something too complicated!

stampede
22nd August 2010, 13:10
emit is not necessary (...)
Sure, I've just putted it there to show that this is still related to original signal question.


But if there is a better way, avoid to manipulate the constness with const_cast.
Of course, i agree 100%, I think a need for const_cast could be just a bad class desing. But C++ allows that. Personally, I will never persuade anyone to use it, but this is one of possible solutions for the problem.