A
A
Alexander2015-06-22 12:14:18
Qt
Alexander, 2015-06-22 12:14:18

What is the right way to write a macro to "extend" parent methods?

You need to create many descendants from different types, all of these types are descendants of QObject and QWidget. The task of the heir is to replace the standard methods, but leave the possibility of referring to them (only to himself). Here is one of the classes that should "extend" or override the parent() and setParent() methods:

class PQ_QWidget : public QWidget {
    Q_OBJECT
    PQW_OBJECT

public:
    explicit PQ_QWidget(QWidget* parent = 0) :
        QWidget(parent){
    }

    ~PQ_QWidget(){
        delete this;
    }
};

First I tried to write a macro like this:
#define PQW_OBJECT \
    Q_PROPERTY( long parent READ parent WRITE setParent ) \
public: \
    Q_INVOKABLE long parent() {\
        return m_parentQPId;\
    }\
public Q_SLOTS:\
    Q_INVOKABLE void setParent(long parentQPId) {\
        QWidget *qo = (QWidget*) ObjectFactory::getQObject(parentQPId);\
        if(qo != NULL) {\
            m_parentQPId = parentQPId;\
            setParent(qo);\
        }\
    }\
private:\
    long m_parentQPId;

which got an error: invalid conversion from 'QWidget*' to 'long int' > setParent(qo); . On the one hand, it is logical that the setParent(QObject *) method does not exist in this section of code, but on the other hand, it is not clear why the macro code tries to "run" at this stage, and not at the stage when it is already inserted into the real class. And why doesn't the method overload work? After all, QObject has a public method setParent(QObject *)...
Then I tried to replace setParent(qo) with parent::setParent(qo) , which again got an error that does not even need comments - parent is not declared.
As a result, instead of parent:: I just substituted QObject::setParent(qo);- collected, but does not work. The parent does not change.
The working macro is:
#define PQW_OBJECT \
    Q_PROPERTY( long parent READ parent WRITE setParent ) \
public: \
    Q_INVOKABLE long parent() {\
        return m_parentQPId;\
    }\
public Q_SLOTS:\
    Q_INVOKABLE void setParent(long parentQPId) {\
        QWidget *qo = (QWidget*) ObjectFactory::getQObject(parentQPId);\
        if(qo != NULL) {\
            m_parentQPId = parentQPId;\
            QWidget::setParent(qo);\
        }\
    }\
private:\
    long m_parentQPId;

But! It turns out that descendants created from QObject, and not from QWidget (there are none yet, but they are planned) will not change their parent and, most likely, will generally crash the application with a runtime error (not sure, honestly). So how do you do it right? Create two macros and substitute the right one, depending on which class I inherit? Or is it possible to somehow unify this action?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
AxisPod, 2015-06-22
@wxmaper

Make working sample classes first, and then cut them into macros, but on the other hand, C ++ has multiple inheritance, including non-virtual, why not use them. I just don’t know qt, but what your macros look like, they’re just asking for separate impurity classes, and some dependent parts can be thrown into a template parameter, you can use CRTP.

S
Stanislav Makarov, 2015-06-22
@Nipheris

1. Have you tried using your first option without a macro? What does the compiler say? Is the error coming from the moc file?
2. I would advise you a template parent, but since you have an MOC, it won't work.
3. Well, pass the parameter to the macro, if nothing at all. I would still figure out first why the option without specifying the genus. class does not work.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question