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;
5 ответов
Возвращаемое значение полезно только в том случае, если вы хотите вызвать слот как обычную функцию-член: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 может использоваться для вызова слота и получения возвращаемого значения. Хотя кажется, что это немного сложнее сделать.
Просматривая источник Qt, кажется, что когда слот вызывается из QMetaObject::invokeMethod, можно указать возвращаемый тип и получить возвращаемое значение. (Посмотрите на invokeMethod в справке Qt)
Я не смог найти много примеров того, как это на самом деле используется в источнике Qt. Я нашел один
bool QAbstractItemDelegate::helpEvent
который является слотом с типом возврата и вызывается из
QAbstractItemView::viewportEvent
используя invokeMethod.
Я думаю, что возвращаемое значение для слота доступно только тогда, когда функция вызывается напрямую (когда это обычная функция C++) или когда используется 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.
Это очень полезно, когда вы имеете дело с динамическим языком, таким как qtscript, JavaScript, QtPython и так далее. С этим языком / привязками вы можете динамически использовать C++ QObject, используя интерфейс, предоставленный MetaObject. Как вы, вероятно, знаете, только сигналы и слоты анализируются moc и генерируют описание MetaObject. Поэтому, если вы используете C++ QObject из привязки javascript, вы сможете вызывать только слоты и вам понадобится возвращаемое значение. Часто привязки Qt для динамических языков предоставляют некоторую возможность доступа к обычному методу, но этот процесс определенно более сложен.
Все слоты доступны в QMetaObject, где к объекту можно получить доступ через отражающий интерфейс.
Например, QMetaObject:: invokeMethod () принимает QGenericReturnArgument
параметр. Поэтому я верю, что это не для явного использования слотов, а скорее для динамического вызова методов в целом. (Существуют другие способы предоставления методов в QMetaObject, кроме превращения их в слоты.)
invokeMethod
Функция, например, используется различными динамическими языками, такими как QML и Javascript, для вызова методов QObject:s
, (Существует также мост Python-Qt, называемый PythonQt, который использует это. Не путать с PyQt, который является полной оберткой.)
Возвращаемое значение используется при выполнении синхронных вызовов между потоками внутри приложения Qt (поддерживается через invokeMethod и установка типа соединения в Qt::BlockingQueuedConnection
, который имеет следующую документацию:
То же, что QueuedConnection, за исключением блоков текущего потока, пока слот не вернется. Этот тип соединения должен использоваться только тогда, когда излучатель и приемник находятся в разных потоках. Примечание. Нарушение этого правила может привести к блокировке приложения.
Ну, этот вопрос впервые был задан 14 лет назад. Теперь QML позволяет Slots возвращать значение, и это точно.
Вам необходимо объявить тип возвращаемого значения, используяresult
параметр (обратите внимание, что это возврат, а не результат).
В Python, присваивая слоту два числа и принимая значение, синтаксис будет таким:
@pyqtSlot(int, int, result=int)
def add(x,y):
return x + y
Вы можете назвать это как
ret_val = add(1, 2)