- 1. Пример
- 1. widget.h
- 2. widget.cpp
- 3. Вывод
Все мы знаем, что в Qt существует два синтаксиса сигналов и слотов:
- Старый синтаксис на макросах SIGNAL SLOT
- Новый синтаксис на указателях
Но также, как не стоит мешать пиво с водкой, с таким же успехом не стоит смешивать два синтаксиса в рамках одного проекта.
Конечно, существуют проекты, в которых написано достаточно много кода и сделать полный рефакторинг по смене всего синтаксиса является довольно накладной работой, но если вы, постепенно дополняя проект, переходите на новый синтаксис, постарайтесь в рамках одного сигнала слотового соединения обновить все места кода с данным соединением на новый синтаксис.
Дело в том, что для обоих случаев ( SINGAL SLOT макросы и синтаксис на указателях ) формируется иное содержание moc файлов , что приводит к тому, что смешанное использование методов connect и disconnect не работает так, как ожидалось бы. А если быть точным, то метод disconnect не будет работать в том случае, если connect был вызван с использованием макросов, а disconnect был вызван с использованием указателей.
Пример
Создадим пробный проект, в котором будет окно и одна кнопка. Добавим в окне слот. И в конструкторе класса окна проверим четыре комбинации подключения сигнала кнопки к слоту окна:
- connect SIGNAL SLOT - disconnect SIGNAL SLOT
- connect SIGNAL SLOT - disconnect синтаксис на указателях
- connect на указателях - disconnect на указателях
- connect на указателях - disconnect SIGNAL SLOT
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); public slots: void checkSlot() {} // Slot for checking private: Ui::Widget *ui; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); qDebug() << "First test"; qDebug() << connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(checkSlot())); qDebug() << disconnect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(checkSlot())); qDebug() << "Second test"; qDebug() << connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(checkSlot())); qDebug() << disconnect(ui->pushButton, &QPushButton::clicked, this, &Widget::checkSlot); qDebug() << "Third test"; qDebug() << connect(ui->pushButton,&QPushButton::clicked, this, &Widget::checkSlot); qDebug() << disconnect(ui->pushButton, &QPushButton::clicked, this, &Widget::checkSlot); qDebug() << "Fourth test"; qDebug() << connect(ui->pushButton,&QPushButton::clicked, this, &Widget::checkSlot); qDebug() << disconnect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(checkSlot())); } Widget::~Widget() { delete ui; }
Вывод
First test true true Second test true false Third test true true Fourth test true true
Таким образом получается, что пара connect SINGAL SLOT - disconnect на указателях даёт не тот результат, который ожидался. И по факту слот остаётся подключённым.
Поэтому новичкам рекомендую внимательно относится к этому нюансу работы с сигналами и слотами в Qt.
Who hasn’t mixed beer with vodka! 🤢🤮
vodka + beer = strong coctail, but it is bad ))
disconnect - обязательно делать, во всех случаях?
Если удаляете объект, то все коннекты отключаются автоматически, здесь следить не требуется.