2

Trying to construct a QImage with byte data along with a cleanupFunction, am I doing something wrong here?
Segfault code:

>>> from PySide6 import QtGui as qtg
>>> qtg.QImage(b'', 10, 10, qtg.QImage.Format.Format_ARGB32, lambda: print(x))
[1]    119240 segmentation fault  python3

but without the function it works:

>>> qtg.QImage(b'', 10, 10, qtg.QImage.Format.Format_ARGB32)
<PySide6.QtGui.QImage(QSize(10, 10),format=QImage::Format_ARGB32,depth=32,devicePixelRatio=1,bytesPerLine=40,sizeInBytes=400) at 0x7fc7af514fc0>

In accordance to the PySide documentation for the constructor, I changed the first argument to a string, but that didn't work:

>>> qtg.QImage('', 10, 10, qtg.QImage.Format.Format_ARGB32, lambda: print(1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'PySide6.QtGui.QImage.__init__' called with wrong argument types:
  PySide6.QtGui.QImage.__init__(str, int, int, Format, function)
Supported signatures:
  PySide6.QtGui.QImage.__init__()
  PySide6.QtGui.QImage.__init__(str, int, int, PySide6.QtGui.QImage.Format)
  PySide6.QtGui.QImage.__init__(str, int, int, int, PySide6.QtGui.QImage.Format)
  PySide6.QtGui.QImage.__init__(Union[PySide6.QtGui.QImage, str])
  PySide6.QtGui.QImage.__init__(bytes, int, int, int, PySide6.QtGui.QImage.Format, Optional[Callable] = None, Optional[int] = None)
  PySide6.QtGui.QImage.__init__(bytes, int, int, PySide6.QtGui.QImage.Format, Optional[Callable] = None, Optional[int] = None)
  PySide6.QtGui.QImage.__init__(Union[str, bytes, os.PathLike], Optional[bytes] = None)
  PySide6.QtGui.QImage.__init__(PySide6.QtCore.QSize, PySide6.QtGui.QImage.Format)
  PySide6.QtGui.QImage.__init__(int, int, PySide6.QtGui.QImage.Format)
  PySide6.QtGui.QImage.__init__(Iterable)

further more, the list of function signatures shows that it's supposed to be a bytes object.
(Also, is it just me or is PySide's documentation really bad?)

Neat
  • 61
  • 1
  • 5
  • The [cleanup function](https://doc.qt.io/qt-6/qimage.html#QImageCleanupFunction-typedef) signature requires an argument, change to `lambda x: print(x)`. About the documentation, I wouldn't suggest to use the python documentation (PySide/PyQt) at all, unless for the very few cases where you need to check for *specific* differences in signatures (which you can always check in the python consolle through `help()`). Use the standard reference C++ documentation: it might require a bit to get used to, but it's always better, more comprehensive, and less confusing. – musicamante Sep 11 '22 at 17:00
  • @musicamante Nope, still get a segfault with `qtg.QImage(b'', 10, 10, qtg.QImage.Format.Format_ARGB32, lambda x: print(1))`, same with `*args` as well. – Neat Sep 11 '22 at 17:06
  • @musicamante "about the documentation..." < yeah, I do the same thing, thought I'd check the PySide documentation for this since it wasn't working but the signature was just straight up wrong there. – Neat Sep 11 '22 at 17:07
  • On PyQt it works fine. Try keeping a reference to the created image: `test = QImage(...)`. Also try with keeping a reference to the lambda: `test = lambda x: print(x)` `QImage(..., test)`. The signature is correct, as only the overload that accepts bytes also accepts the callable argument. – musicamante Sep 11 '22 at 17:19
  • @musicamante unfortunately, it still results in a segfault. I've come to notice that PyQt seems to be the better implementation of Qt than PySide. Wrong as it is defining `data` as a `str` when it should be a `bytes` or even `QByteArray`. – Neat Sep 11 '22 at 17:25
  • Oh, you were referring to the first two. That's probably an issue with shiboken (probably a missing/wrong configuration for the automation). I'd suggest you to search and eventually submit a report on Qt's [bug tracker](//bugreports.qt.io). – musicamante Sep 11 '22 at 17:41
  • It makes no sense to pass *cleanupfunc* without also passing *cleanupinfo*. Doing so won't fix the buggy pyside implementation, but I'm curious to know what you intend to do with this API. Do you have an actual use-case, or this just curiosity? (By use-case, I mean something you cannot already do in python by other means). – ekhumoro Sep 11 '22 at 17:50
  • @ekhumoro what I'm working on is possibly another question, but basically I noticed that the memory taken by a `QImage` instance is not cleared even when the instance is out of scope/deleted by Python. I looked around a bit and came across https://bugreports.qt.io/browse/PYSIDE-140?focusedCommentId=355441#comment-355441 . So right now I'm trying to implement a similar code in a different way, with the `cleanupFunction` performing the `data.clear()`. Also, it looks like it's (QImage memory leak) not a problem with PyQt, according to some comment I read somewhere, forgot where. – Neat Sep 12 '22 at 03:45
  • @ekhumoro never mind, https://www.qtcentre.org/threads/17011-QImage-destruction-is-not-releasing-memory?p=85436#post85436 , tried it on Windows and yeah the memory consumption isn't the same as on Linux. Would you happen to know of a way to fix this? – Neat Sep 12 '22 at 08:03
  • Fix what, exactly? Without a [mre], I can't test anything (and I can only test on linux, anyway). How are you measuring the memory leak? – ekhumoro Sep 12 '22 at 20:22

0 Answers0