crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Вызвать слот по имени без QScriptEngine
fantom
  опции профиля:
сообщение 4.2.2009, 16:55
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 29.1.2009
Пользователь №: 515

Спасибо сказали: 1 раз(а)




Репутация:   1  


Возможно ли вызвать слот зная его имя в QString? Интересует решение без использования скриптового движка.

Или отправить сигнал таким же способом?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 4.2.2009, 16:57
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


можно, см. QMetaObject::invokeMethod
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
fantom
  опции профиля:
сообщение 4.2.2009, 17:05
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 29.1.2009
Пользователь №: 515

Спасибо сказали: 1 раз(а)




Репутация:   1  


Спасибо. Буду пробывать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
fantom
  опции профиля:
сообщение 5.2.2009, 17:24
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 29.1.2009
Пользователь №: 515

Спасибо сказали: 1 раз(а)




Репутация:   1  


Возникла проблема.
Так работает..
  TestLogic* logic = new TestLogic();
     QMetaObject::invokeMethod(logic, "test", Qt::QueuedConnection);

А так нет..
  QObject *object = new QObject();
     TestLogic *logic = qobject_cast<TestLogic *>(object);
     QMetaObject::invokeMethod(logic, "test", Qt::QueuedConnection);

Класс TestLogic унаследован от QObject.
Как заставить это заработать?


Может надо еще вызвать qRegisterMetaType()? Только я не совсем понял как его вызывать. Если просто qRegisterMetaType<TestLogic>("TestLogic"); то пишет ошибку
/usr/include/QtCore/qobject.h:303: error: 'QObject::QObject(const QObject&)' is private


И еще.. Как я понимаю qobject_cast работает вызывая dynamic_cast? Кто нибудь может на пальцах пояснить концепцию превышающего приведения типов. Что происходит с памятью? Она копируется куда то? Ведь базовый класс занимает меньше места чем производный класс? Насколько это быстрая операция?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 5.2.2009, 17:40
Сообщение #5


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


fantom,
на сколько я понимаю ты пытаешься вызвать метод которого нет в QObject но он есть в TestLogic???
если так то понятен результат.
ведь ты пишешь
QObject *object = new QObject();

а если
QObject *object = new TestLogic();
то стоит проверить. думаю так заработает.

я так думаю что dynamic_cast не досоздает(извините за корявое слово) необходимые члены и методы
класса

и кстати если пользуешь dynamic_cast то проверяй на ноль указатели в ответственных местах.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 5.2.2009, 17:46
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(fantom @ 5.2.2009, 20:24) *
А так нет..
и не должен!

Какой смысл приводить базовый класс к наследнику? Это в принципе не правильно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
fantom
  опции профиля:
сообщение 5.2.2009, 17:49
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 29.1.2009
Пользователь №: 515

Спасибо сказали: 1 раз(а)




Репутация:   1  


kwisp ты прав. Так работает.Спасибо.

Ну все равно интересен вопрос про работу dynamic_cast.
И про ошибку при вызове qRegisterMetaType<TestLogic>.

Цитата(Litkevich Yuriy @ 5.2.2009, 17:46) *
Какой смысл приводить базовый класс к наследнику? Это в принципе не правильно.

Ну вот так то работает..

QObject *object = new QObject();
TestLogic *logic = qobject_cast<TestLogic *>(object);
logic->test();


Как ни странно..
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 5.2.2009, 17:51
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(fantom @ 5.2.2009, 20:49) *
Ну вот так то работает..
да работать-то может и работает, не зряж троли переписывали приводилку типов. Только логики в этом нет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
fantom
  опции профиля:
сообщение 5.2.2009, 17:55
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 47
Регистрация: 29.1.2009
Пользователь №: 515

Спасибо сказали: 1 раз(а)




Репутация:   1  


Цитата(Litkevich Yuriy @ 5.2.2009, 17:51) *
да работать-то может и работает, не зряж троли переписывали приводилку типов. Только логики в этом нет.

Ну стандартный dynamic_cast тоже работает по такому принципу. А есть логика или нет это уже вопрос проектирования структуры приложения.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 5.2.2009, 18:01
Сообщение #10


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


fantom,
а что интересно про dynamic_cast

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

указатель на производный = dynamic_cast<указатель на базовый>
то сработает.

а вообще лучше почитать
что пишут?
Цитата
Оператор dynamic_cast применяется при идентификации типа во время выполнения (run-time type identification)


а вообще целая глава этому посвящена.
Раскрывающийся текст

RTTI позволяет программам, которые манипулируют объектами через указатели или ссылки на базовые классы, получить истинный производный тип адресуемого объекта. Для поддержки RTTI в языке C++ есть два оператора:
" оператор dynamic_cast поддерживает преобразования типов во время выполнения, обеспечивая безопасную навигацию по иерархии классов. Он позволяет трансформировать указатель на базовый класс в указатель на производный от него, а также преобразовать l-значение, ссылающееся на базовый класс, в ссылку на производный, но только в том случае, если это завершится успешно;
" оператор typeid позволяет получить фактический производный тип объекта, адресованного указателем или ссылкой.
Однако для получения информации о типе производного класса операнд любого из операторов dynamic_cast или typeid должен иметь тип класса, в котором есть хотя бы одна виртуальная функция. Таким образом, операторы RTTI - это события времени выполнения для классов с виртуальными функциями и события времени компиляции для всех остальных типов. В данном разделе мы более подробно познакомимся с их возможностями.
Использование RTTI оказывается необходимым при реализации таких приложений, как отладчики или объектные базы данных, когда тип объектов, которыми манипулирует программа, становится известен только во время выполнения путем исследования RTTI-информации, хранящейся вместе с типами объектов. Однако лучше пользоваться статической системой типов C++, поскольку она безопаснее и эффективнее.

19.1.1. Оператор dynamic_cast
Оператор dynamic_cast можно применять для преобразования указателя, ссылающегося на объект типа класса в указатель на тип класса из той же иерархии. Его также используют для трансформации l-значения объекта типа класса в ссылку на тип класса из той же иерархии. Приведение типов с помощью оператора dynamic_cast, в отличие от других имеющихся в C++ способов, осуществляется во время выполнения программы. Если указатель или l-значение не могут быть преобразованы в целевой тип, то dynamic_cast завершается неудачно. В случае приведения типа указателя признаком неудачи служит возврат нулевого значения. Если же l-значение нельзя трансформировать в ссылочный тип, возбуждается исключение.




Цитата(fantom @ 5.2.2009, 17:49) *
QObject *object = new QObject();
TestLogic *logic = qobject_cast<TestLogic *>(object);
logic->test();


Litkevich Yuriy прав целиком и полностью логики в этом нет и делать так не надо. плохо это , плохо..... а то что сработало это еще не факт что сработает завтра послезавтра и несколько раз подряд а плывущие неявные баги исправлять сложнее всего.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 17.10.2021, 21:15