1

I have a C++ class defined with a method which has a sol (pointer to member method) as argument:

MyClass : public QDialog, private Ui::MyClassBase
{
  Q_OBJECT
  public:
    MyClass( QWidget *parent = nullptr );

    void connectValueChanged( const QList<QWidget *> &widgets, void ( MyClass::*slot )() );
}

and

 void MyClass::connectValueChanged( const QList<QWidget *> &widgets, void ( MyClass::*slot )() )
 {
   Q_FOREACH ( QWidget *widget, widgets )
   {
     connect( w, &QWidget::signal, this, slot );
   }
 }

The connectValueChanged cannot be used as defined in the SIP file, I get a syntax error.


I also tried to use const char *slot without success: In the SIP file

void MyClass::connectValueChanged( const QList<QWidget *> &widgets, const char *slot);

I get an error (no matching function for call to ‘MyClass::connectValueChanged) as I suppose I need some MethodCode to achieve this.


Maybe some hints:


What shall I do to define a method with a slot as argument in SIP ?

I think this requires some MethodCode I am not capable to write at the moment. I would like to use Qt5 new signal/slot connection (avoid using const char *slot in the cpp method, put possibly in the python method with some MethodCode)

Denis Rouzaud
  • 2,412
  • 2
  • 26
  • 45

1 Answers1

0

I've removed the pointer-to-member since I'm not sure whether this is supported at the moment. If you use the const char* signal/slot method, you also need to implement the methods like that otherwise you'll of course get a mismatch error.

class MyQObj : public QObject {
    Q_OBJECT

    public:
        MyQObj(QObject * parent = nullptr);

        void connectValueChanged(const QList<QObject*> &objects, const char * slot);

    public slots:
        void mySlot();
};

...

MyQObj::MyQObj(QObject * parent) : QObject(parent) {}

void MyQObj::connectValueChanged(const QList<QObject*> &objects, const char * slot) {
    for (auto p : objects)
        QObject::connect(p, SIGNAL(objectNameChanged(QString)), this, slot);
}

void MyQObj::mySlot() {
    std::cout << "Called slot\n";
}

...

int main(int argc, char ** argv) {
    QCoreApplication app(argc, argv);

    MyQObj obj(&app);
    QObject xxx(&app);

    QList<QObject*> list;
    list.push_back(&xxx);
    obj.connectValueChanged(list, SLOT(mySlot()));

    QTimer::singleShot(1000, [&xxx](){
            xxx.setObjectName("newname");
    });

    return app.exec();
}

The SIP file could be something like:

%Module A

%Import QtCore/QtCoremod.sip

class MyQObj : public QObject
{
    public:
        MyQObj(QObject * parent /TransferThis/ = nullptr);

        void connectValueChanged(const QList<QObject*> &objects, const char* slot);

    public slots:
        void mySlot();
};
Svalorzen
  • 5,353
  • 3
  • 30
  • 54
  • Thanks for your reply. I could not correctly build this. If I keep the `using` line in the sip code I get an error (`sip: using is undefined`) and if I remove the line I get `unknown VoidSlot`. Am I missing something, could you drat the sip file too? Cheers. – Denis Rouzaud Apr 07 '17 at 06:43
  • I assumed you had access to c++11, I've changed the example with a `typedef` rather than a `using`. – Svalorzen Apr 07 '17 at 12:29
  • Thanks again for your reply. I do have access to c++11. My intention is to use the new signal slot connection in Qt5, hence the pointer to member argument, which I would like to keep. – Denis Rouzaud Apr 10 '17 at 05:02
  • I am just wondering if it would not be possible to use some method code to transform the `const char *slot` to a pointer to method member. Cheers. – Denis Rouzaud Apr 10 '17 at 05:03
  • @DenisRouzaud I suppose that simply `sip` does not support pointers to members. Ideally, you could export the `const char*` version and use it to call the pointer to member method. You can convert from `const char*` to pointer member with something like a `static const QHash` appropriately initialized. – Svalorzen Apr 10 '17 at 10:05