Как спокойный реализует сигналы и слоты?

Кто-то может объяснить мне основную идею о QT signals&slots РЕАЛИЗАЦИЯ механизма? Я хочу знать то, что все они макросы Q_OBJECT делают "в плоскости C++". Этот вопрос не о signals&slots использовании.

добавленный: Я знаю, что QT использует компилятор MOC для преобразования Спокойного C++ в плоскость C++. Но что делает MOC? Я пытался считать "moc_filename.cpp" файлы, но я понятия не имею, что что-то вроде этого может означать

void *Widget::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_Widget))
    return static_cast<void*>(const_cast< Widget*>(this));
return QDialog::qt_metacast(_clname);
}
15
задан River 18 October 2017 в 03:33
поделиться

3 ответа

[

]Что касается сигналов и слотов, в макросе []Q_OBJECT[] добавлена виртуальная функция []qt_metacall()[] в декларацию класса, которая будет определена позднее с помощью []moc[]. (Он также добавляет некоторые декларации для преобразования, но это не слишком важно)[

] [

]moc[]moc[] затем считывает заголовочный файл, и когда он видит макрос, он генерирует другой файл [].cpp[] с именем []moc_headerfilename. cpp[] с определениями для виртуальных функций и - возможно, вы спросили себя, почему вам может сойти с рук упоминание сигналов []:[] в заголовочном файле без правильного определения - сигналов.[

] [

]Итак, при вызове сигнала выполняется определение из moc-файла и вызывается []QMetaObject::activate()[] с именем сигнала и его аргументами. Затем функция []activate()[] выясняет, какие соединения были установлены и получает имена для соответствующих слотов.[

] [

]Затем она вызывает []qt_metacall[] с именами слотов и аргументами, переданными сигналу, и мета-функция делегирует это с помощью большого []-[]-[]case[] оператора case[] в реальные слоты. [

] [

]Так как в языке С++ отсутствует реальная информация о реальном времени исполнения, касающаяся реальных имен сигналов и слотов, как уже было замечено, они будут закодированы макросами []SIGNAL[] и []SLOT[] в простые []const char*[]s (с добавлением либо "1", либо "2" к имени, чтобы отличить сигналы от слотов). [

] [

]Как определено в []qobjectdefs.h[]:[

] [
#define SLOT(a)     "1"#a
#define SIGNAL(a)   "2"#a
] [

]-[

] [

]Другое, что делает макрос []Q_OBJECT[], это определяет функции []tr()[] внутри вашего объекта, которые могут быть использованы для перевода вашего приложения.[

] [

][]Edit[]]. Как вы спросили, что делает []qt_metacast[]. Он проверяет, принадлежит ли объект определенному классу и возвращает ли он указатель на него. Если нет, то возвращается 0.[

] [
Widget* w = new Widget();
Q_ASSERT(w->qt_metacast("Widget") != 0);
Q_ASSERT(w->qt_metacast("QWidget") != 0);
Q_ASSERT(w->qt_metacast("QObject") != 0);
Q_ASSERT(w->qt_metacast("UnrelatedClass") == 0);
] [

]Это необходимо для того, чтобы обеспечить некоторое отражение во время выполнения, что в противном случае невозможно. Например, функция вызывается в [][]QObject::inherits(const char *)[][] и просто проверяет наследование.[

].
17
ответ дан 1 December 2019 в 03:52
поделиться

Эти макросы ничего не делают "в обычном C++", - они расширяются до пустых строк (я думаю).

QT использует мета-объектный компилятор, который генерирует код C++ для классов с поддержкой Q_OBJECT (реализовывает сигналы/слоты, которые вы определяете, среди прочего).

Подробнее об этом можно прочитать в официальной документации.

.
3
ответ дан 1 December 2019 в 03:52
поделиться

Основная идея заключается в том, что Вы можете подключать свои объекты, позволяя им выполнять метод (слот), когда сигнал выполнен.

connect(pistol,SIGNAL(sigShoot()),runner,SLOT(slotRun()))

Выполняя соединение выше, когда пистолет излучает сигнал, бегунок выполнит свой слот.

Для этого необходимо объявить свои сигналы и слоты в соответствующих классах.

Это основная идея.

Удачи!

-1
ответ дан 1 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: