1

I have a widget-based class. It has two private QString members. I would like to be able to use signals to notify when the values are changed. So for both variables I have a setter and a getter. I also have a signal.

  • Question: Can they both use the same signal? Or do I have to define two independent signals?

Then - I would like to bind that signal to a slot in the same class (I know I could just call the slot instead of emiting signal - but I'd like to use signal).

  • How do I connect them? I tried:

    connect( &invoiceFilterDirectionPart, SIGNAL(valueChanged(QString)), this, SLOT(invoiceFilterDirectionPart_valueChanged(QString)) );
    

But it doesn't compile - as invoiceFilterDirectionPart is a QString, whereas connect expects first argument to be QObject*

I could use this in the connect statement - but as far as single signal is concerned - i guess that both slots would trigger? Is only option two independent signals and then using this in the connect statement - or am I missing something?

  • Last question: do I need a Q_PROPERTY to make all this work? When i first used it i thoud it is some kind of a magic macro - that when I used it, like this:

    Q_PROPERTY(QString invoiceFilterContractorPart 
        READ getInvoiceFilterContractorPart
        WRITE setInvoiceFilterContractorPart
        NOTIFY valueChanged
    )
    

I thought it will auto-magically generate the variable, setter, getter and the notifier signal. Sadly - that didn't happen ;). It just screamed that none of mentioned items exists. Is that all it does? Can't really find a good use case for it...

svlasov
  • 9,923
  • 2
  • 38
  • 39
murison
  • 3,640
  • 2
  • 23
  • 36

1 Answers1

2

As far as I can see, you do not necessarily need to set Q_PROPERTY but since invoiceFilterContractorPart seems to be a property of your object, it is correctly used. Leave it.

Having a valueChanged signal indicates a wrong way of thinking of the property. Assume invoiceFilterContractorPart is a property of some class Foo:

class Foo : public QObject
{
    // ...

    Q_PROPERTY(QString invoiceFilterContractorPart 
        READ getInvoiceFilterContractorPart
        WRITE setInvoiceFilterContractorPart
        NOTIFY valueChanged
    )
}

Then what an external object gets notified about is:

Object foo1 of type Foo says: 'valueChanged'

and not

invoiceFilterContractorPart says: 'valueChanged'

Thus you need to change your signal, such that it is clear which property has changed, e.g. rename it to invoiceFilterContractorPartChanged():

class Foo : public QObject
{
    // ...

    Q_PROPERTY(QString invoiceFilterContractorPart 
        READ getInvoiceFilterContractorPart
        WRITE setInvoiceFilterContractorPart
        NOTIFY invoiceFilterContractorPartChanged
    )
}

Now what an external object gets notified about is:

Object foo1 of type Foo says: 'invoiceFilterContractorPartChanged'

which enabled you to ask for the new value like foo1.getInvoiceFilterContractorPart().

Thus, you do not connect the property but the object owning that property:

connect(this, SIGNAL(invoiceFilterDirectionPartChanged(QString)),
        someotherobject, SLOT(onFooDidInvoiceFilterDirectionPartChanged(QString)));

or inside of some other class Bar:

connect(&foo1, SIGNAL(invoiceFilterDirectionPartChanged(QString)),
        this, SLOT(onFooDidInvoiceFilterDirectionPartChanged(QString)));
Simon Warta
  • 10,850
  • 5
  • 40
  • 78