- 1. Приклад
- 1. віджет.h
- 2. widget.cpp
- 3. Висновок
Всі ми знаємо, що в Qt існує два синтаксиси сигналів та слотів:
- Старий синтаксис на макросах SIGNAL SLOT
- Новий синтаксис на покажчиках
Але також, як не варто заважати пиво з горілкою, з таким самим успіхом не варто змішувати два синтаксиси в рамках одного проекту.
Звичайно, існують проекти, в яких написано досить багато коду і зробити повний рефакторинг по зміні всього синтаксису є досить накладною роботою, але якщо ви поступово доповнюючи проект переходьте на новий синтаксис, постарайтеся в рамках одного сигналу слотового з'єднання оновити всі місця коду з даними з'єднанням новий синтаксис.
Справа в тому, що для обох випадків ( SINGAL SLOT макроси та синтаксис на покажчиках ) формується інший вміст moc файлів , що призводить до того, що змішане використання методів connect та disconnect не працює так, як очікувалося б. А якщо бути точним, то метод disconnect не працюватиме в тому випадку, якщо connect був викликаний з використанням макросів, а disconnect був викликаний з використанням покажчиків.
Приклад
Створимо пробний проект, у якому буде вікно та одна кнопка. Додамо у вікні слот. І в конструкторі класу вікна перевіримо чотири комбінації підключення сигналу кнопки до слота вікна:
- підключити SIGNAL SLOT - відключити SIGNAL SLOT
- connect SIGNAL SLOT - disconnect синтаксис на вказівниках
- connect на покажчиках - disconnect на покажчиках
- connect на покажчиках – disconnect SIGNAL SLOT
віджет.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 - обязательно делать, во всех случаях?
Если удаляете объект, то все коннекты отключаются автоматически, здесь следить не требуется.