Class inheriting QQbject

Help
Nicu Tofan
2012-03-28
2013-04-06
  • Nicu Tofan
    Nicu Tofan
    2012-03-28

    Hello!

    I need a class in python that can be created on some circumstances:

    inst = example.Foo()
    inst.someMethod()
    

    and, on other circumstances, I want it to be created for the user prior to first line of the custom script:

    # inst2 is already part of this module
    inst2.someMethod()
    

    The way I understand the examples, this means that:
    - for first use case I need a wrapper:

    class _w_Foo : public QObject{
    Q_OBJECT
    public slots:
      void someMethod(Foo * o) { o->someMethod(); }
    }
    

    - for second use case I need my class to inherit QObject:

    class Foo : public QObject{
    Q_OBJECT
    public slots:
      void someMethod() { /* do somthing */; }
    }
    

    Is there any other way?

    PS there may be syntactic errors in code up there, I didn't checked it. Just extract the idea. :)

     
  • Chris Bevan
    Chris Bevan
    2012-03-28

    Hi Nick,

    The way I do this is using PythonQt's decorators.  Here's a rough example from some code:

    class Test : public QObject
    {
        Q_OBJECT
    public slots:
        void run();
    };
    class TestDecorator : public QObject
    {
        Q_OBJECT
    public slots:
        Test* new_Test();
    };

    Provided that you register the decorators and then the class before you use either of them, this should let you do any of the following:

    test1 = my_module.getSomeTest()
    test1.run()
    test2 = my_module.Test()    # you'll need to copy this from PythonQt.private
    test2.run()

    Hope that helps.

    - Chris

     
  • Nicu Tofan
    Nicu Tofan
    2012-03-28

    Thank you for your help, Chris! There is something that I'm missing here. A little example may help.

    This is how I define the classes that you have used (minimal changes):

    class Test : public QObject {
        Q_OBJECT
    public slots:
        QString run()
        { return "run slot called!"; }
    };
    class TestDecorator : public QObject {
        Q_OBJECT
    public slots:
        Test* new_Test()
        { return new Test(); }
    };
    

    Now here is the code that makes use of these classes. There are comments indicating the output and the missing routine:

    void    test__newmodule                 ( void )
    {
        PythonQt * sgl = PythonQt::self();
        PythonQtObjectPtr module = sgl->createUniqueModule();
        sgl->addDecorators( new TestDecorator() );
        sgl->registerCPPClass( "Test", "", "example" );
        module.evalScript( "print( dir() )\n");
        //OUTPUT: ['__builtins__', '__doc__', '__file__', '__name__', '__package__']
        module.evalScript( "from PythonQt import example\n");
        module.evalScript( "print( dir() )\n");
        //OUTPUT: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'example']
        module.evalScript( "print( dir( example ) )\n");
        //OUTPUT: ['Test', '__doc__', '__name__', '__package__']
        module.evalScript( "print( dir( example.Test ) )\n");
        //OUTPUT: ['__dict__', '__doc__', '__module__', '__weakref__', 'className', 'delete', 'help', 'inherits']
        /* I would have expected to see run here */
        module.evalScript( "tinst = example.Test()\n");
        module.evalScript( "print( dir() )\n");
        //OUTPUT: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'example', 'tinst']
        module.evalScript( "print( dir( tinst ) )\n");
        //OUTPUT: ['__dict__', '__doc__', '__init__', '__module__', '__weakref__', 'className', 'delete', 'help', 'inherits']
        /* I would have expected to see run here */
        PythonQtObjectPtr module2 = sgl->createUniqueModule();
        module2.addObject( "predef_inst", new Test() );
        module2.evalScript( "print( dir() )\n");
        //OUTPUT: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'predef_inst']
        module2.evalScript( "print( dir( predef_inst ) )\n");
        //OUTPUT: ['__dict__', '__doc__', '__init__', '__module__', '__weakref__', 'className', 'delete', 'help', 'inherits']
        /* I would have expected to see run here */
    
    }
    
     
  • Chris Bevan
    Chris Bevan
    2012-03-28

    Hmmm…  You're doing things pretty similarly to my code there, and I would have expected those dir commands to show "run" as you say.  The only significant difference I've spotted is that you're calling PythonQt::registerCPPClass(), whereas I'm calling PythonQt::registerClass().  That might make a difference, given that PythonQt wraps QObject classes and general C++ classes in different ways.  Does changing that help at all?

    - Chris

     
  • Nicu Tofan
    Nicu Tofan
    2012-03-28

    that's right, that was the problem. Thank you, Chris!

    For future reference, the line

    sgl->registerCPPClass( "Test", "", "example" );
    

    should be replaced with this one:

    sgl->registerClass( &Test::staticMetaObject, "example" );
    

    Nick