Как отправить экземпляр пользовательской структуры с помощью QSignalMapper?

У меня есть пользовательская структура, экземпляры которой связаны с QAction экземпляров. Я хотел бы, чтобы слот выполнялся с соответствующим экземпляром моей структуры при выполнении действия.

Мне удалось заставить это работать, используя QSignalMapper по подклассам QObject инкапсулировать экземпляр моей структуры. Однако все значения моей структуры неверны, когда они поступают в слот — они кажутся неинициализированными.

Если я отправлю примитивный тип, такой как ИНТ вместо структуры, или даже что-то вроде QAction, все работает ок.

Можно ли сделать то, что я пытаюсь сделать? Если так, что я пропускаю?

Спасибо,
Алан

Изменить: Добавлен пример кода

Вот как я подключаю QSignalMapper. Примечание: STRUCT_WRAPPER является производным от QObject.

/* Connect signal mapper to selected slot */
connect(signalMapper, SIGNAL(mapped(QObject *)), this,
SLOT(on_selected(QObject *)));

/* For all structures */
for(x = 0; x < structureCount; x++)
{
/* Create action */
QAction * action = ui.menu->addAction("Name");

/* Get current structure */
MY_STRUCT myStruct = structList[x];

/* Create wrapper */
STRUCT_WRAPPER * structWrapper = new STRUCT_WRAPPER(this, myStruct);

/* Map struct to action */
signalMapper->setMapping(action, structWrapper);
}

И вот слот, где я получаю неинициализированные значения:

void on_selected(QObject * object)
{
/* Get structure wrapper */
STRUCT_WRAPPER * structWrapper = (STRUCT_WRAPPER *)object;

/* Get structure */
MY_STRUCT myStruct = structWrapper->GetStruct();

/* ID is always uninitialised */
int id = myStruct.ID;
}

0

Решение

Вместо использования QSignalMapper, который вынуждает вас создавать собственный STRUCT_WRAPPER, попробуйте использовать QAction :: УстановитьДанные метод, который принимает любой QVariant

Также не забудьте зарегистрировать вашу структуру в системе метатипов Qt, используя Q_DECLARE_METATYPE

Затем просто подключите все ваши QAction к одному и тому же слоту и используйте http://qt-project.org/doc/qt-4.8/qobject.html#sender чтобы получить QAction, который испустил сигнал:

void MyWindow::on_selected() {
QAction *action = qobject_cast<QAction *>(sender());
Q_ASSERT(action);

MY_STRUCT myStruct = action->data().value<MY_STRUCT>();
}

Кроме того, избегайте использования бросков в стиле C. Если вы не используете QObjects, используйте вместо этого qobject_cast (он опирается на информацию MetaObject и не нуждается в дополнительной функции RTTI):

STRUCT_WRAPPER * structWrapper = qobject_cast<STRUCT_WRAPPER *>(object;)
1

Другие решения

почему вы не просто используете пользовательский класс для работы? производя его от qobject и с некоторыми слотами / сигналами, он будет делать то, что вы хотите.

я понятия не имею, почему ваша структура получает недопустимые значения, поэтому было бы хорошо, чтобы получить код в качестве примера 🙂

су долго зайборг

0

void on_selected(QObject * structWrapper)
{
/* Get structure */
MY_STRUCT myStruct = structWrapper->GetStruct();

/* ID is always uninitialised */
int id = myStruct.ID;
}

я думаю, что проблема в том, что QObject * не знает, что должен делать GetStruct () … он должен выдавать ошибку при компиляции oO

может быть попробовать

MY_STRUCT myStruct = <dynamic_cast>(STRUCT_WRAPPER*)->GetStruct();
0

Спасибо за все полезные ссылки.

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

Я не хотел использовать Q_DECLARE_METATYPE в этом случае, потому что я бы предпочел не иметь зависимости QT от моей библиотеки API. В противном случае предложение восьмерика тоже сработало бы.

0
По вопросам рекламы [email protected]