[Qt] Three connection syntaxes of signal slots

[Qt] Three connection syntaxes of signal slots

To implement the observer mode, you can use function callbacks, but there are certain limitations in registering callback functions, and security is not guaranteed. So to a certain extent, it can be said that the Qt signal slot encapsulates the callback mechanism.

Qt's signal slot can be connected (connect) and compiled through, need to meet two conditions

  1. The number of parameters of the signal is greater than or equal to the slot function
  2. For the part with the same number of parameters of the signal slot, the parameter types must correspond one-to-one

There are three ways to create a signal slot connection

1. Use ui interface controls

The first one is to use the controls on the ui interface, right click -> go to the slot , and the code similar to the following function name will be generated in the cpp of the corresponding interface

void MainWindow::on_pushButton_clicked()
{
    
    
  
}

on_WidgetName_SignalName

on + control name + signal name

In this way, the slot function is generated without checking at compile time, and connected at runtime, and the two functions are connected through the reflection mechanism of Qt's own moc ( meta object compiler ) system.

Therefore, when the control name is modified, it will prompt that the connection fails at runtime.

Another disadvantage is that this connection method is also inconvenient to maintain, and the connection (connect) and disconnection (disconnect) are not within the controllable range.

2. Connection syntax of Qt4

The second way, the connection using Qt4 syntax, that is, using macro expansion, essentially uses the reflection mechanism of strings, for example:

connect(sender, SIGNAL(sigfunc()), receiver, SLOT((slotfunc()));

The four parameters of connect are: sender object pointer, SIGNAL (sender signal function), receiver object pointer, SLOT (receiver slot function)

If you look at SIGNALthe SLOTimplementation of these two macros, you can notice that these two macros convert the function name to a string

#ifndef QT_NO_META_MACROS
#ifndef QT_NO_DEBUG
#define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)
#ifndef QT_NO_KEYWORDS
#	define METHOD(0)  qFlagLocation("0"#a QLOCATION)
#endif
# define SLOT(a) qFlagLocation("1"#a QLOCATION)
# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
#else 
# ifndef QT_NO_KEYWORDS
#  define METHOD(a)  "0"#a
# endif
# define SLOT(a) "1"#a
# define SIGNAL(a) "2"#a
#endif

#The number is used to stringify the macro parameters behind it, that is to say, after the variable after it is replaced, a double reference is added to the left and right.

The slot slot function starts with "1", and the signal signal function starts with "2". QT_STRINGIFYThe definition of a macro is also the use of a single pound sign

#define QT_STRINGIFY2(x) #x
#define QT_STRINGIFY(x) QT_STRINGIFY2(x)

However, compared with the first method, this method performs a parameter consistency check in the form of a string during the compilation phase.

The disadvantage is that it is impossible to confirm whether this function is included in the class. You can put two functions whose parameters match but do not exist at all in the two macros. It can also pass the compilation check during compilation, but it prompts that the connection fails at runtime.

3. Connection syntax of Qt5

The third one, the connect syntax in the form of function pointer is provided in Qt5, example:

connect(sender, &Sender::signal, receiver, &Receiver::slot);

Adding the class name to the function to take the address ensures that the compiler checks whether the signal matches the slot function, which can reduce the connection failure at runtime.

There is also a variant of lambda expression, which also uses function pointers to connect

connect(sender, &Sender::signal, [](){
    
    
  //... implement of slot
});

However, if the signal or slot function is overloaded in the Qt5 syntax, or both are overloaded, connect will not be intelligently matched, and it will be used directly in the case of overloading, and the compilation will report an error. The error message is as follows:

no matching member function for call to 'connect'

No matching member function for call to connect

Can use Qt's QOverload to handle, if there are the following signal and slot functions

signals:
  void sigfunc(int);
  void sigfunc(QString);
//...
public slots:
  void slotfunc(int);
  void slotfunc(QString);

Can be used when connecting QOverload<T>::of, example:

connect(sender, QOverload<int>::of(&Sender::sigfunc), 
	receiver, QOverload<int>::of(&Receiver::slotfunc));

and

connect(sender, QOverload<QString>::of(&Sender::sigfunc), 
	receiver, QOverload<QString>::of(&Receiver::slotfunc));

Overloads to connect signals and slots (int, QString)

Guess you like

Origin blog.csdn.net/weixin_44488341/article/details/132235578