Connect is used to connect qt signals and slots and is integral to qt programming. It actually has a fifth parameter, but it generally uses the default value, which may need to be set manually for special needs.
Qt::AutoConnection: Default value, using which the connection type is determined when the signal is sent. If the receiver and sender are in the same thread, the Qt::DirectConnection type is automatically used. If the receiver and sender are not in the same thread, the Qt::QueuedConnection type is automatically used.
Qt::DirectConnection: Slot functions are called directly when a signal is sent. Slot functions run on the thread on which the signal is sent. The effect looks like calling the slot function directly at the signal location. This is dangerous in multi-threaded environments and can cause crashes.
Qt::QueuedConnection: The slot function is called to control the event loop back to the receiver’s thread. The slot function runs on the signal receiver’s thread. The slot function is not called immediately after the signal is sent, but only after the receiver’s current function has finished executing and entered the event loop. This is what you use in multithreaded environments.
Qt: : BlockingQueuedConnection: slot function call time and Qt: : QueuedConnection is consistent, but send out signals of backwardness anything where the thread will be blocked, until the function is finished running. The receiver and sender must never be on the same thread, or the program will deadlock. This may be needed in situations where synchronization between multiple threads is required.
Qt: : UniqueConnection: this flag can be through the bitwise or (|) used together with the above four. When this flag is set, repeated connections will fail when a signal is already connected to a slot. So you don’t have to rejoin.
QObject:: Connect () is itself thread-safe. Slot functions are generally unsafe.
Class Test: public QMainWindow {Q_OBJECT Test() signals: void sigFirst(); private slots: void slotFirst(); }
Test::Test(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); for (int i = 0; i < 5; // Connect (this, SIGNAL(sigFirst()), this, SLOT(slotFirst()))); }
emit sigFirst();
}
void Test::slotFirst() { numCoon++; QStringLiteral()<< QStringLiteral(” signal “)<
“Signal 1st connection”, “signal 2nd connection”, “signal 3rd connection”, “signal 4th connection”, “signal 5th connection”, if the code is changed to:
connect(this, SIGNAL(sigFirst()), this, SLOT(slotFirst()), Qt::UniqueConnection); // Run the fifth parameter again to see the output:
“Signal first” connection “this time only sent a signal, but we connected 5 times, so use Qt::UniqueConnection connection, no matter how many times to connect, only send a signal, will only perform a slot function
2. Signal and slot functions in different threads
#pragma once
#include <QThread>
class QtTestThread : public QThread {
Q_OBJECT
public:
QtTestThread(QObject *parent);
~QtTestThread();
protected:
void run();
signals:
void sigSecond();
};
#include “QtTestThread.h”
#include <QDebug>
QtTestThread::QtTestThread(QObject *parent)
: QThread(parent) {
}
QtTestThread::~QtTestThread() {
}
void QtTestThread::run() { emit sigSecond(); QDebug () << QStringLiteral(” Signal sent!” ); } Call thread class:
class QtTestThread;
class Test: public QMainWindow
{
Q_OBJECT
Test()
signals:
void sigFirst();
private slots:
void slotThread();
private:
QtTestThread* testThread;
}
#include “QtTestThread.h”
Test::Test(QWidget *parent)
: QMainWindow(parent) {
ui.setupUi(this);
testThread = new QtTestThread(this); connect(testThread, SIGNAL(sigSecond()), this, SLOT(slotThread())); // There is no fifth argument, which is to use the default connection mode
testThread->start();
}
Void Test::slotThread() {qDebug() << QStringLiteral(” Thread sent signal – slot function executed!” ); QThread::sleep(3); } Run it and output:
“Signal sent!” “Signal sent by thread – slot function executed!” As you can see, after sending the signal, the following code is run directly, and the sent signal is put into the main thread’s signal queue for execution.
Let’s signal slot connection mode change, add signal slot connection Qt: : BlockingQueuedConnection:
connect(testThread, SIGNAL(sigSecond()), this, SLOT(slotThread()), Qt::BlockingQueuedConnection); Run it again:
“Signal sent by thread – slot function executed!” “Signal sent!” / / time after waiting for 3 seconds to output this sentence USES Qt: : BlockingQueuedConnection connection mode is to realize the simultaneous execution of signals and slots function.
—
The complete source code is as follows:
The header file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
namespace Ui {
class MainWindow;
}
class QtTestThread : public QThread {
Q_OBJECT
public:
QtTestThread(QObject *parent);
~QtTestThread();
protected:
void run();
signals:
void sigSecond();
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
signals:
void sigFirst();
private slots:
void slotFirst();
void slotThread();
private:
QtTestThread* testThread;
int numCoon;
};
#endif // MAINWINDOW_H
Copy the code
The source file:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> QtTestThread::QtTestThread(QObject *parent) : QThread(parent) { } QtTestThread::~QtTestThread() { } void QtTestThread::run() { emit sigSecond(); QDebug () << QStringLiteral(" Signal sent!" ); } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); for (int i = 0; i < 5; // Connect (this, SIGNAL(sigFirst()), this, SLOT(slotFirst()))); Connect (this, SIGNAL(sigFirst()), this, SLOT(slotFirst()), Qt::UniqueConnection); } numCoon = 0; //emit sigFirst(); testThread = new QtTestThread(this); //connect(testThread, SIGNAL(sigSecond()), this, SLOT(slotThread())); // Connect (testThread, SIGNAL(sigSecond()), this, SLOT(slotThread())), Qt::QueuedConnection); / / the effect same as the connect (testThread, SIGNAL (sigSecond ()), and this, SLOT (slotThread ()), Qt: : BlockingQueuedConnection); TestThread ->start(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::slotFirst() { numCoon++; QStringLiteral()<< QStringLiteral(" signal ")<<numCoon<<QStringLiteral(" string "); } void MainWindow::slotThread() {qDebug() << QStringLiteral(" Thread sent signal - slot function executed!" ); QThread::sleep(3); }Copy the code