Menu

Getting QWidget winId

Help
Neosettler
2013-05-29
2013-06-06
  • Neosettler

    Neosettler - 2013-05-29

    Greetings everyone,

    I'm trying to convert a piece of code form PySide to PythonQt and I'm having a hard time so far figuring this one out, here is the working PySide version:

    def setHandle(self, in_widget):
        import ctypes
        ctypes.pythonapi.PyCObject_AsVoidPtr.restype = ctypes.c_void_p
        ctypes.pythonapi.PyCObject_AsVoidPtr.argtypes = [ctypes.py_object]
        self._winid = ctypes.pythonapi.PyCObject_AsVoidPtr(in_widget.winId())
    

    When translated to PythonQt in_widget.winId() becomes in_widget.winId but I'm getting this error:

    TypeError: PyCObject_AsVoidPtr with non-C-object

    Anyone could help me clear this up?

    Thx

     
  • Neosettler

    Neosettler - 2013-05-30

    So basically, QWidget.winId is not a C-object and not an integer... I'm totally mystified.

     
  • Neosettler

    Neosettler - 2013-06-04

    If I had one last question to ask on this forum it would be this one:

    Could anyone share how to pass a widget winId from PyhtonQt to c++?

     
  • Neosettler

    Neosettler - 2013-06-04

    To specified: when winId is cast as a long:

    self._winid = long(in_widget.winId)

    it returns:
    TypeError: long() argument must be a string or a number, not 'builtin_qt_slot'

    I also tried to keep the same nomenclature as Qt C++ and retrieve QWidget.data.winid but data is not recognized.

    I'm guessing that WId is a special case and I'd be very interested in knowing how to deal with this via PythonQt.

    Thx.

     
  • Neosettler

    Neosettler - 2013-06-04

    Also, when using

    self._winid = long(in_widget.winId())

    I get:

    ValueError: Called WId winId(), return type 'WId' is ignored because it is unknown to PythonQt. Probably you should register it using qRegisterMetaType() or add a default constructor decorator to the class.

    Maybe someone could point me in the right direction how to accomplish just that?

     
  • Chris Bevan

    Chris Bevan - 2013-06-05

    Hi,

    I don't know much about WId objects I'm afraid - but it looks like that's a QWidget method, so if you're trying to get that into C++, it'd seem easiest to pass the QWidget to C++ and call pWidget->winId() to get the value you're after.

    Cheers,
    - Chris

     
  • Neosettler

    Neosettler - 2013-06-05

    Hi Chris, thank you for your input,

    I guess WId is not very popular in general but still covered by the PySide or PyQt community and I cant find any information on this within PythonQt. I'll think about your suggestion but I basically need to retrieve the WId to send it to C++ via Cython and Qt is unknown to the library I'm sending it to. I think the key is to convert the WId to either a pylong or a c++ void pointer otherwise I'll have to make a major change in my API design.

     
  • Chris Bevan

    Chris Bevan - 2013-06-05

    Ah, right; I see what you mean. I think Qt probably doesn't cover it too much because it's platform-specific. The docs only seem to say this:

    typedef WId
    Platform dependent window identifier.

    It looks like it's a HWND, so yeah, that does sound like it could be handy elsewhere on Windows.

    kernel/qwindowdefs_win.h
    118:typedef HWND WId;

    You could try calling qRegisterMetaType<WId>() in your C++ code that initialises PythonQt, and see if that works. Some other variant such as qRegisterMetaType<QWidget::WId>("WId") might also help. Otherwise I can't think of much that might be of use, though, sorry.

    • Chris
     

    Last edit: Chris Bevan 2013-06-06
  • Florian Link

    Florian Link - 2013-06-05

    PythonQt does not yet support this out-of-the-box.

    You can one of the below options:

    a) register WId as a basic type in PythonQtMethodInfo.cpp,
    but the type will be different on 32bit/64bit and might be different between platforms:

    int PythonQtMethodInfo::nameToType(const char* name)
    ...
    // TODO: check for 32/64bit and use a different type
    _parameterTypeDict.insert("WId", QMetaType::LongLong);

    // alternative, that may work as well:
    //_parameterTypeDict.insert("WId", QMetaType::VoidStar);
    

    b) You can patch the generated wrapper slot for QWidget::winId().
    Search for winId() in the generated_cpp dir and patch the method to cast/return a void* or a long long or even a pylong created using the Python API.

    c) You can also add your own decorator methods to QWidget, see the decorator docs/examples.

    No sure if any of those interoperates well with Cython, I never used that.

     
  • Neosettler

    Neosettler - 2013-06-06

    Alright, thank you gentlemen, I'm going to chew on this for a while.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.