Подтвердить что ты не робот

Qt: значение возвращаемого значения слота?

Согласно документации, возвращаемое значение из слота ничего не значит.
Однако в сгенерированном коде 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;
4b9b3361

Ответ 1

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

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

bool QAbstractItemDelegate::helpEvent 

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

QAbstractItemView::viewportEvent

с помощью invokeMethod.

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

Изменить: Для примера:

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.

Ответ 2

Возвращаемое значение полезно только в том случае, если вы хотите вызвать слот как обычную функцию-член:

class MyClass : public QObject {
    Q_OBJECT
public:
    MyClass(QObject* parent);
    void Something();
public Q_SLOTS:
    int Other();
};

void MyClass::Something() { int res = this- > Other(); ... } Изменить: Похоже, что не единственный способ использования возвращаемого значения, метод QMetaObject:: invokeMethod может использоваться для вызова слота и получения возвращаемого значения. Хотя кажется, что это немного сложнее сделать.

Ответ 3

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

Ответ 4

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

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

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

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

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