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 -
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 -
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()).
-
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 -
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);@