Connect diferent signals and slost each other



  • Hy Peaple,

    I have a project with 4.8 Qt framework. In the project connect I different signals and slots by reason of some architecture solution. A example:

    signals: void EmitHigh(int High);
    public slots: void Controll(double SomeOther);

    In standard C++ the int type casts to double implicit, but in my solution doesn't work it. If my knowledge is correct, Qt use string comparing to connect signal and slot.
    Can somebody tell me a solution how can I contact those each other? Some cast or other?

    Regards,
    Norbert



  • Just add a public slot (inline?) that accept int and calls the double one:
    @
    public slots:
    void Controll(double SomeOther);
    void Controll(int SomeOther){Controll( static_cast<double>(SomeOther));}
    @
    And connect the int slot with the int signal



  • Yes, I tried this solution, but it doesn't work for me :(
    Sorry, the problem is more complicated as my English knowledge. Only for test made I a test connection: I connected a valueChange signal of double spin box into a setInterval of Qtimer. The second accept int values which are handled by it as milliseconds. I wrote a converter class:
    @
    class Connector: public QObject {

    Q_OBJECT
    

    public slots: void Int2Double(int In){emit OutputDouble( static_cast<double>(In) );}
    public slots: void Double2Int(double In){emit OutputInt( static_cast<int>(In) );}

    signals: void OutputInt(int);
    signals: void OutputDouble(double);
    };
    @

    And the code of connections:

    @
    connect(ui->TSampleSpinBox, SIGNAL(valueChanged(double)), &D2I, SLOT(Double2Int(double)));
    connect(&D2I, SIGNAL(OutputInt(int)), &TimeControll, SLOT(setInterval(int)));
    @
    D2I is an instance of Connector class.
    If I debugging the application, the code reach the break point on the Double2Int slot, but the interval of timer doesn't change.

    Any idea?

    Regards,
    Norbert


  • Moderators

    Unfortunately, in Qt 4.8, signals and slots must use EXACTLY the same types. Like you said, signal-slot connections use string comparisons (so "double" != "int"). Even typedefs will fail: "size_t" != "unsigned int"

    Qt 5 is better; it can perform implicit conversion between signals and slots.

    In Qt 4.8, you'll need a converter function, but you don't need to emit a new signal. Just do this:

    @
    class Connector: public QObject {

    Q_OBJECT
    QTimer TimerControll;
    

    public slots:
    void Double2Int(double In){TimerControll.setInterval(In);}
    };

    ...

    connect(ui->TSampleSpinBox, SIGNAL(valueChanged(double)), &D2I, SLOT(Double2Int(double)));
    @

    (But, I would rename the functions, so that it's easier to understand what they do: void setTimerInterval() instead of void Double2Int()).



  • Hi,

    thanks for a rapid reply! If I use Qt 5.0.0 with the new pointer base connection technology, how can I decide between overloaded signals and / or slots? Such as QTimer have a setIntarval(int) and setInterval(QText...some)?

    Regards,
    Norbert



  • I think if your signal emits an int it will be connected to the setInterval(int) slot.

    BTW with Qt5 you can use lambdas and std::bind for even more flexibility.



  • Help Meee!!!

    I am trying the new Qt 5.0.0 with the function pointer like connection mechanism, but it doesn't compile to me :(
    I would like connect a QDoubleSpingBox and a own QTimer wrapper object:

    @
    connect(ui->TSampleSpinBox, &QDoubleSpinBox::valueChanged, &TimeControll, TimerWrapper::setInterval);
    @
    It is the own QTimer wrapper class:
    @
    class TimerWrapper: public QTimer
    {
    public: TimerWrapper() = default;
    public: virtual ~TimerWrapper() = default;

    public slots: void setInterval(double msec) {QTimer::setInterval(static_cast<s32>(msec));}
    };
    @

    If I try to compile a project get the following error:
    /home/moravas/work/sw/IrTechBeadando/mainwindow.cpp:16: error: no matching function for call to 'MainWindow::connect(QDoubleSpinBox*&, <unresolved overloaded function type>, TimerWrapper*, void (TimerWrapper::*)(double))'

    Can somebody help me to understand the right usage of signal-slot mechanism including the overloaded signals and/or slots?

    Regards,
    Norbert



  • You didn't use the & operator to get the address of TimeWrapper::SetInterval

    Also you don't seem to have the Q_OBJECT macro in the timer class. That is needed to use connect.

    Also, looking at your code it looks like you come from a language like C# or Java, where you have to specify public/private access per method, you don't have to do this in C++, just place all public stuff under the public label at top and all private stuff under the private label at the bottom. Much better readability, at least IMO.



  • Actually, that is not the problem, the problem is that you are using an overloaded signal and slot (QDoubleSpinBox has two overloads for the signal and you create an overload in your TimerWrapper, which is by the way completely unnecessary) which doesn't sit quite well with the new syntax:

    bq. As you might see in the example, connecting to QAbstractSocket::error is not really beautiful since error has an overload, and taking the address of an overloaded function requires explicit casting.
    The best thing is probably to recommend not to overload signals or slots …

    So, the solution is the rather ugly:

    @connect(ui->TSampleSpinBox,
    static_cast<void(QDoubleSpinBox::)(double)>(&QDoubleSpinBox::valueChanged),
    &TimeControl,
    static_cast<void(TimerWrapper::
    )(double)>(&TimerWrapper::setInterval));@

    which is the act of you specifying which overload you want based on the parameters.

    A much easier, but not compile time safe approach would be to just use the old syntax and declare a new slot for TimerWorker called setIntervalDouble(double msec) where you just call QTimer::setInterval(static_cast<int>msec)



  • Hi Utcenter,

    yes, I am forgot the Q_OBEJCT macro and the addressing operator too, it will be refine.
    I would like to present me as embedded programmer. I was learn to program with 8051 micro controller with ASM, my thesis was wrote in C with Cortex-M3.
    Yes, I can program with C# too, but don't java. I like to use this syntax than it is more comfortable and precise for me: it describes more metadatas of the member of the class.

    During the time found I the solution to resolve the overloaded signals and slots:
    We have two signals, something like this:
    @
    void valueChanged(double);
    void valueChanged(SomeOtherType);
    @

    Then we can declare it's type with static_cast operator, something like this:

    @
    connect(ui->TSampleSpinBox, static_cast<void(QDoubleSpinBox::*)(d)>(&QDoubleSpinBox::valueChanged), &ControllLoop.D, &QtSpecialisedDerivativeWrapper::SetSampleTime);
    @

    I think to it doesn't the more beautiful solution, but it works for me...

    Regards,
    Norbert



  • I edited my post with a solution that should work in your case, check it again.



  • Hi,

    I am looking your solution: we get same result for the problem independent from each other. Thank you very much for help.

    Regards,
    Norbert



  • Point is you don't really need the wrapper, the Qt5 connect syntax can implicitly cast the double to an int, so all you need is a standard QTimer and the connection:

    @connect(spin, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
    &timer, &QTimer::setInterval);@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.