Qt: значение возвращаемого значения слота? - PullRequest
24 голосов
/ 22 сентября 2008

Согласно документации возвращаемое значение из слота ничего не значит.
Тем не менее в сгенерированном коде moc я вижу, что если слот возвращает значение, это значение используется для чего-то. Есть идеи, что он делает?


Вот пример того, о чем я говорю. это взято из кода, сгенерированного moc. 'message' - это слот, который ничего не возвращает, а 'selectPart' объявлен как возвращающий int.

case 7: message((*reinterpret_cast< const QString(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2]))); break;
case 8: { int _r = selectPart((*reinterpret_cast< AppObject*(*)>(_a[1])),(*reinterpret_cast< int(*)>(_a[2])));
    if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; }  break;

Ответы [ 4 ]

12 голосов
/ 30 сентября 2008

Возвращаемое значение полезно только в том случае, если вы хотите вызвать слот как обычную функцию-член: class MyClass : public QObject { Q_OBJECT public: MyClass(QObject* parent); void Something(); public Q_SLOTS: int Other(); };</p> <p>void MyClass::Something() { int res = this->Other(); ... } Редактировать: Кажется, что это не единственный способ использования возвращаемого значения, метод QMetaObject :: invokeMethod можно использовать для вызова слота и получения возвращаемого значения. Хотя кажется, что это немного сложнее.

12 голосов
/ 22 сентября 2008

При просмотре источника Qt кажется, что когда слот вызывается из QMetaObject :: invokeMethod, можно указать тип возвращаемого значения и получить возвращаемое значение. (Посмотрите на invokeMethod в справке Qt)

Я не смог найти много примеров того, как это на самом деле используется в источнике Qt. Один, который я нашел, был

bool QAbstractItemDelegate::helpEvent 

, который является слотом с типом возврата и вызывается из

QAbstractItemView::viewportEvent

с использованием invokeMethod.

Я думаю, что возвращаемое значение для слота доступно только тогда, когда функция вызывается напрямую (когда это обычная функция C ++) или когда используется invokeMethod. Я думаю, что это действительно предназначено для внутренних функций Qt, а не для обычного использования в программах, использующих Qt.

Edit: Для примера:

case 8: { int _r = selectPart((*reinterpret_cast< AppObject*(*)>(_a[1])), *reinterpret_cast< int(*)>(_a[2])));
if (_a[0]) *reinterpret_cast< int*>(_a[0]) = _r; }  break;

вектор _a - это список аргументов, который передается в qt_metacall. Это передается QMetaObject :: invokeMethod. Таким образом, возвращаемое значение в сгенерированном moc-коде сохраняется и передается вызывающей стороне. Таким образом, для нормальных взаимодействий сигнал-слот возвращаемое значение вообще ни для чего не используется. Тем не менее, механизм существует, так что возвращаемые значения из слотов могут быть доступны, если слот вызывается через invokeMethod.

6 голосов
/ 01 февраля 2010

Это очень полезно, когда вы имеете дело с динамическим языком, таким как qtscript, JavaScript, QtPython и так далее. С этим языком / привязками вы можете динамически использовать C ++ QObject, используя интерфейс, предоставленный MetaObject. Как вы, наверное, знаете, только сигналы и слоты анализируются moc и генерируют описание MetaObject. Так что если вы используете C ++ QObject из привязки javascript, вы сможете вызывать только слоты и вам понадобится возвращаемое значение. Зачастую привязки Qt для динамических языков предоставляют некоторые возможности для доступа к обычному методу, но процесс определенно более сложен.

4 голосов
/ 07 января 2011

Все слоты доступны в QMetaObject, где к объекту можно получить доступ через отражающий интерфейс.

Например, QMetaObject :: invokeMethod () принимает параметр QGenericReturnArgument. Поэтому я верю, что это не для явного использования слотов, а скорее для динамического вызова методов в целом. (Существуют другие способы предоставления методов в QMetaObject, кроме превращения их в слоты.)

Функция invokeMethod, например, используется различными динамическими языками, такими как QML и Javascript, для вызова методов QObject:s. (Существует также мост Python-Qt под названием PythonQt , который использует это. Не путать с PyQt , который является полной оберткой.)

Возвращаемое значение используется при выполнении синхронных вызовов между потоками внутри приложения Qt (поддерживается через invokeMethod и устанавливается тип соединения равным Qt::BlockingQueuedConnection, который имеет следующую документацию:

То же, что и QueuedConnection, за исключением блоков текущего потока, пока слот возвращается. Этот тип соединения должен использоваться только там, где излучатель и приемник находятся в разные темы. Примечание. Нарушение этого правила может привести к вашему заявлению в тупик.

...