Russian Qt Forum

Qt => Общие вопросы => Тема начата: Whiplash от Июль 28, 2011, 10:30



Название: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: 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);
           //...
        }
    }

Поскажите, где копнуть?


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: LisandreL от Июль 28, 2011, 10:43
LibsElementSelector *libs=dynamic_cast<LibsElementSelector*>(widget);
работает?


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Whiplash от Июль 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")


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: LisandreL от Июль 28, 2011, 11:48
А плагин у вас как подключается?


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Пантер от Июль 28, 2011, 11:53
Покажи определение LibsElementSelector.


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Whiplash от Июль 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);
};


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: LisandreL от Июль 28, 2011, 13:25
Вот это (http://lists.trolltech.com/qt-interest/2008-07/msg00360.html) не ваш случай?

Цитировать
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.


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Авварон от Июль 28, 2011, 16:18
можно использовать Q_INTERFACES (там кьюобжект каст будет работать), но придется забыть о сигналах/слотах в "интерфейсе"
И таки да, чтобы кьюобжект каст работал надо линковаться к либе, где живет базовый класс.


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Whiplash от Июль 29, 2011, 09:47
Понятно. Спасибо, коллеги.


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Maquefel от Июль 29, 2011, 15:30
можно использовать Q_INTERFACES (там кьюобжект каст будет работать), но придется забыть о сигналах/слотах в "интерфейсе"
И таки да, чтобы кьюобжект каст работал надо линковаться к либе, где живет базовый класс.

Не придется, сигналы могут быть определены в интерфейсе.


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Авварон от Июль 30, 2011, 20:57
Да, но пользователь должен работать с _интерсфейсом_ и не может полагаться на то, что эти сигналы иплементированы (то есть он о них _ничего_ не знает). Вам не кажется это неправильным?


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

Не до конца понял мысль. То есть они определены в интерфейсе, но не реализованы?


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Авварон от Август 04, 2011, 22:02
их просто нельзя определить в интерфейсе


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Maquefel от Август 05, 2011, 09:09
их просто нельзя определить в интерфейсе

Можно.


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Авварон от Август 05, 2011, 14:57
Код:
class IFace {
public slots:
virtual slot() {}
};
удачи


Название: Re: qobject_cast, findChildren() и самописный класс - проблема
Отправлено: Maquefel от Август 08, 2011, 09:39
Код:
class IFace {
public slots:
virtual slot() {}
};
удачи

Код:
class SerialScaleInterface
{
public:
    virtual ~SerialScaleInterface() {}

    virtual bool isValid() const = 0;
    virtual bool isStable() const = 0;

    virtual double getWeight() const = 0;       
    virtual bool write(const QByteArray &array) = 0;

    virtual QString version() const = 0;
    virtual QString name() const = 0;

    virtual int mode() const = 0;
    virtual void setMode(int iMode) = 0;

    virtual QMap<int, QString> getModes() const = 0;

    virtual QObject* getObject() = 0;
signals:
    virtual void readyWeight(double weight) = 0;
};

Q_DECLARE_INTERFACE(SerialScaleInterface,
                     "com.trolltech.Plugin.SerialScaleInterface/1.0");

Спасибо, но у меня и так все работает.