Russian Qt Forum
Октябрь 05, 2024, 10:31 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: qobject_cast, findChildren() и самописный класс - проблема  (Прочитано 8237 раз)
Whiplash
Гость
« : Июль 28, 2011, 10:30 »

Есть проблема. Есть класс, который используется в самописном плагине. Класс - наследник QFrame. В начале объявления класса прописан макрос Q_OBJECT. Всё отлично работает за исключением того, что qobject_cast не проходит.
Т.е. есть у меня указатель типа QWidget* на объект этого класса. Мне необходимо его привести к родному указателю:
Код:
LibsElementSelector *libs=qobject_cast<LibsElementSelector*>(widget);
Возвращается null.
Непосредственное преобразование нормально проходит:
Код:
LibsElementSelector *libs=(LibsElementSelector*)widget;
Ну и
Код:
widget->metaObject()->className();
Возвращает имя класса LibsElementSelector.
Вроде бы и фиг с ним, но есть одна загвоздка. Думаю, именно из-за того, что не работает qobject_cast, невозможен и стандартный поиск всех потомков:
Код:
QList <LibsElementSelector*> list=superWidget->findChildren <LibsElementSelector*>();
Вышеприведённый код возвращает пустой список. Приходится пользоваться такой лазейкой:
Код:
QList<QWidget*> list=superWidget->findChildren<QWidget*>();
    LibsElementSelector *l;
    for(int i=0;i<list.count();i++){
        if(QString::compare(list.at(i)->metaObject()->className(),"LibsElementSelector")==0){
            l=(LibsElementSelector*)list.at(i);
           //...
        }
    }

Поскажите, где копнуть?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Июль 28, 2011, 10:43 »

LibsElementSelector *libs=dynamic_cast<LibsElementSelector*>(widget);
работает?
Записан
Whiplash
Гость
« Ответ #2 : Июль 28, 2011, 10:57 »

Да, дайнэмик каст работает. Вот такой код:
Код:
if(QString::compare(list.at(i)->metaObject()->className(),"LibsElementSelector")==0){
            l=dynamic_cast<LibsElementSelector*>(list.at(i));
            qDebug() << "dynamic_cast" << l;
            l=qobject_cast<LibsElementSelector*>(list.at(i));
            qDebug() << "qobject_cast" << l;
            l=(LibsElementSelector*)list.at(i);
            qDebug() << "(LibsElementSelector*)" << l;
            //...
        }
Даёт вот такой вывод:
Код:
dynamic_cast LibsElementSelector(0xa7588d0, name = "libClient") 
qobject_cast QObject(0x0) 
(LibsElementSelector*) LibsElementSelector(0xa7588d0, name = "libClient")
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Июль 28, 2011, 11:48 »

А плагин у вас как подключается?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #4 : Июль 28, 2011, 11:53 »

Покажи определение LibsElementSelector.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Whiplash
Гость
« Ответ #5 : Июль 28, 2011, 12:52 »

Плагин подключается к uiloader, который находит его по пути, который есть в pluginPaths. Может правда, в нём дело, в плагине?
Вот объявление класса, всё тривиально:
Код:
class LibsElementSelector : public QFrame
{
    Q_OBJECT
    Q_PROPERTY(int lib_head_id READ getHeadId WRITE setHeadId)

public:
    LibsElementSelector(QWidget *parent = 0);
    ~LibsElementSelector();

    void setModel(libModel* model);
    void setModel(libPool *pool, int head);
    libModel* model(){
        return lModel;
    }
    void setPool(libPool *pool){
        setModel(pool,headId);
    }

    QModelIndex currentIndex();
    QVariant currentData(int role=libModel::idRole);

    void setCurrentData(const QVariant &data, int role=libModel::idRole);
    int getHeadId(){return headId;}
    void setHeadId(int i){
        headId=i;
        if(modelsPool)setModel(modelsPool, headId);
    }

private:
    QLineEdit *line;
    QPushButton *button;
    QTreeView *view;

    QByteArray viewGeometry;
    QModelIndex index;
    libModel *lModel;

    int savedX;
    int savedY;

    int headId;
    libPool *modelsPool;

public slots:
    void setCurrentIndex(const QModelIndex &idx);

private slots:
    void showView();
    void hideView();

signals:
    void currentIndexChanged(const QModelIndex &idx);
};
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #6 : Июль 28, 2011, 13:25 »

Вот это не ваш случай?

Цитировать
Think of it like this: the plugin can only link to libraries.

That means any classes that you want to use in the plugin must be in a
library. This includes the base class you're creating your plugin
infrastructure from.

Conclusion: you need at least one (shared) library.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #7 : Июль 28, 2011, 16:18 »

можно использовать Q_INTERFACES (там кьюобжект каст будет работать), но придется забыть о сигналах/слотах в "интерфейсе"
И таки да, чтобы кьюобжект каст работал надо линковаться к либе, где живет базовый класс.
Записан
Whiplash
Гость
« Ответ #8 : Июль 29, 2011, 09:47 »

Понятно. Спасибо, коллеги.
Записан
Maquefel
Гость
« Ответ #9 : Июль 29, 2011, 15:30 »

можно использовать Q_INTERFACES (там кьюобжект каст будет работать), но придется забыть о сигналах/слотах в "интерфейсе"
И таки да, чтобы кьюобжект каст работал надо линковаться к либе, где живет базовый класс.

Не придется, сигналы могут быть определены в интерфейсе.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #10 : Июль 30, 2011, 20:57 »

Да, но пользователь должен работать с _интерсфейсом_ и не может полагаться на то, что эти сигналы иплементированы (то есть он о них _ничего_ не знает). Вам не кажется это неправильным?
Записан
Maquefel
Гость
« Ответ #11 : Август 04, 2011, 10:11 »

Да, но пользователь должен работать с _интерсфейсом_ и не может полагаться на то, что эти сигналы иплементированы (то есть он о них _ничего_ не знает). Вам не кажется это неправильным?

Не до конца понял мысль. То есть они определены в интерфейсе, но не реализованы?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #12 : Август 04, 2011, 22:02 »

их просто нельзя определить в интерфейсе
Записан
Maquefel
Гость
« Ответ #13 : Август 05, 2011, 09:09 »

их просто нельзя определить в интерфейсе

Можно.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #14 : Август 05, 2011, 14:57 »

Код:
class IFace {
public slots:
virtual slot() {}
};
удачи
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.313 секунд. Запросов: 23.