Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. PyQt loading libraries, what is wrong there?
Forum Updated to NodeBB v4.3 + New Features

PyQt loading libraries, what is wrong there?

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 4.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    ilian
    wrote on last edited by
    #1

    Hello, I am still trying to figure out how to load a library in that PyQt thing. So in short, I have a widget, that is a library:

    Here is the header:

    #ifndef INTERFACE_H
    #define INTERFACE_H
    #define MY_EXPORT
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    struct QWidget;
    QWidget *getWidget(void);
    
    #ifdef __cplusplus
    };
    #endif
    

    and the implementation:

    #include "interface.h"
    #include "testwidget.h"
    #include <iostream>
    #include <QtWidgets/qwidget.h>
    #include <QObject>
    
    
    extern "C" MY_EXPORT QWidget *getWidget(void)
    {
    
        QWidget* w = new QWidget;
        w->setMinimumSize(200, 200);
        w->setMaximumSize(200, 200);
        return  w;
    }
    

    Now from the C++ perespective the following main.cpp is legit and working:

    #include <QApplication>
    #include <QtCore>
    #include <iostream>
    #include <QtWidgets/QWidget>
    
    typedef QWidget* (*fncall)(void);
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QLibrary lib("/home/ilian/git-projects/build-testpyqtlib-Desktop_Qt_5_7_1_GCC_64bit-Debug/libtestpyqtlib.so");
        bool res = lib.load();
        if (res) {
            std::cout << "LOAD OK" << std::endl;
            fncall f = (fncall)lib.resolve("getWidget");
            if (f) {
                std::cout << "Calling f\n";
                QWidget* w = f();
                w->show();
            } else {
                //exit(1);
            }
        } else {
            std::cout << "LOAD FAILED" << std::endl;
            std::cout << lib.errorString().toStdString() << std::endl;
        }
        app.exec();
    }
    

    The bad things get in the PyQt loading the libraries. Ok, I succeeded with loading the lib. But... How do I call the function getWidget() ? Here is in detail what is going on:

    import  sys
    from ctypes import *
    from PyQt5 import QtCore
    from PyQt5 import  QtGui
    from PyQt5 import QtWidgets
    from PyQt5.QtCore import QLibrary
    from sip import voidptr
    
    
    libc = CDLL('/home/ilian/git-projects/build-testpyqtlib-Desktop_Qt_5_7_1_GCC_64bit-Debug/libtestpyqtlib.so')
    
    def foo():
        pass
    
    def main(*args, **kwargs):
        app = QtWidgets.QApplication(sys.argv)
        w = libc.getWidget()
        print(w)
        app.exec()
    
    if __name__ == "__main__":
        main(sys.argv)
    

    Consider the above python code: the function getWidget is called, but the return type is always an int . I don't want it to be int. I saw a reference that tells: you can specify the return type however adding the line: (you can somehow specify the return type, assuming you have declaration of the type in your python app)

    ...
    libc.getWidget.restype = QtWidgets.QWidget
    w = libc.getWidget() # Crash!
    w.show()
    

    I got a program crash which I can't trace in python. The error on the call is:
    Traceback (most recent call last):

    File "/home/ilian/git-projects/pyqtlibtest/pyqtloadlibtest.py", line 24, in <module>
      main(sys.argv)
    File "/home/ilian/git-projects/pyqtlibtest/pyqtloadlibtest.py", line 18, in main
      w = libc.getWidget()
    TypeError: QWidget(parent: QWidget = None, flags: Union[Qt.WindowFlags, Qt.WindowType] = Qt.WindowFlags()): argument 1 has unexpected type 'int'
    

    Now I am kind of totally stuck with PyQt stuff and I can't seem how to load a QWidget as a library and to be able to connect that object to the program that loads the library.

    Any help here?

    #endif // INTERFACE_H

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Not a direct answer but wouldn't it be simpler to create bindings the same way PyQt does for your custom set of widgets ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      I 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Not a direct answer but wouldn't it be simpler to create bindings the same way PyQt does for your custom set of widgets ?

        I Offline
        I Offline
        ilian
        wrote on last edited by
        #3

        @SGaist I am really not a python/PyQt expert, so I have no idea about how to do that, but I will do some research, thanks.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Take a look here. PyQt uses sip to create the bindings. At the bottom of the page you can find an Qt example.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          I 1 Reply Last reply
          0
          • SGaistS SGaist

            Take a look here. PyQt uses sip to create the bindings. At the bottom of the page you can find an Qt example.

            I Offline
            I Offline
            ilian
            wrote on last edited by
            #5

            @SGaist I don't want to deal with that SIP thing, I want to keep as Qt as possible for the other team members. I was able to use QPluginLoader and get a QObject instance in the damned PyQt, however I am stuck with the lacking of qobject_cast<> which can cast to the interface, and I have no idea how to implement the classic C++ interface in the PyQt thing. Also the internet lacks any sophisticated info :(

            1 Reply Last reply
            0
            • I Offline
              I Offline
              ilian
              wrote on last edited by
              #6

              What I came into my mind, which can be considered an ugly hack, it to dump a QWidget to a char array, then cast it to QWidget again using C union

              union WidgetData
              {
                      QWidget w;
                      char data[sizeof(QWidget)];
              };
              

              but even then, I can't cast anything ... Really, I don't want to bother with that SIP thing, I want to keep it as simple as possible, and there must be some way, I'll try with Python.h to see if cant be done there, but this is really frustrating from PyQt side, not to have a simple example for the QLibrary and QPLuginLoader....

              jsulmJ 1 Reply Last reply
              0
              • I ilian

                What I came into my mind, which can be considered an ugly hack, it to dump a QWidget to a char array, then cast it to QWidget again using C union

                union WidgetData
                {
                        QWidget w;
                        char data[sizeof(QWidget)];
                };
                

                but even then, I can't cast anything ... Really, I don't want to bother with that SIP thing, I want to keep it as simple as possible, and there must be some way, I'll try with Python.h to see if cant be done there, but this is really frustrating from PyQt side, not to have a simple example for the QLibrary and QPLuginLoader....

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @ilian "I don't want to deal with that SIP thing" - do you think it is better to hack around with manual library loading and some dirty hacks like the union? PyQt already provides nice Qt integration in Python using SIP - it would be better to do it in the same way.

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                I 1 Reply Last reply
                0
                • jsulmJ jsulm

                  @ilian "I don't want to deal with that SIP thing" - do you think it is better to hack around with manual library loading and some dirty hacks like the union? PyQt already provides nice Qt integration in Python using SIP - it would be better to do it in the same way.

                  I Offline
                  I Offline
                  ilian
                  wrote on last edited by
                  #8

                  @jsulm It's a huge task I can't handle the whole task writing over 200 classes in that SIP modules. What I want is just to bridge existing slots in a C++ program to a PyQt based program, so the PyQto to be able to send signal/slots to the C++ program. That's why I want to be able to extract an Qt stuff from the library, which is C++. If I go into the SIP thing I will be totally lost.

                  1 Reply Last reply
                  0
                  • I Offline
                    I Offline
                    ilian
                    wrote on last edited by
                    #9

                    Also the examples are all for PyQt4 , and I am using PyQt5 that leads me to even further obfuscation.

                    1 Reply Last reply
                    0
                    • I Offline
                      I Offline
                      ilian
                      wrote on last edited by
                      #10

                      I am trying PyQt4 example in the SIP site, it fails me building a Qt module. Even with a copy/pasted code it gives me missing sbf files and cannot find QtGui\QtGuimod.sip . I don't know how people deal with this thing anymore.

                      1 Reply Last reply
                      0
                      • I Offline
                        I Offline
                        ilian
                        wrote on last edited by
                        #11

                        I was able to fight trough the SIP, if somebody needs an example: here it is:
                        https://github.com/heatblazer/pyqtlibtest/tree/master/sip

                        @SGaist thanks for the referal, it was a hard task but there is no way around.
                        @jsulm Seems like I could not avoid SIP :(

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved