Error interpreting message in nativeEvent on Windows (might be a Qt bug?)
-
Minimal example:
from PySide6.QtWidgets import QWidget, QApplication class Window(QWidget): def nativeEvent(self, eventType, message): print(eventType, message, message.toBytes()) return super().nativeEvent(eventType, message) app = QApplication() window = Window() window.show() app.exec()
The output is always like
b'windows_generic_MSG' shiboken6.Shiboken.VoidPtr(Address 0x000000765B8DBD20, Size 0, isWritable False) b''
According to information on the Internet and the docs (Python doc, C++ doc), I am supposed to convert
message
to a WindowsMSG
.From the documentation of
shiboken6.Shiboken.VoidPtr
, the only way to access data from aShiboken.VoidPtr
is.toBytes()
. Butmessage.toBytes()
is always returningb''
. And the "Size" ofmessage
is always zero.My plan was to use struct module to convert the bytes (though I'm not sure if struct is the right way):
from PySide6.QtWidgets import QWidget, QApplication from shiboken6 import Shiboken import struct class Window(QWidget): def nativeEvent(self, eventType, message): if eventType == b'windows_generic_MSG': bytes = message.toBytes() # https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msg # https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types msg = struct.unpack("PIPPLllL", bytes) print(f"Bytes: {bytes!r} Interpreted: {msg}") return super().nativeEvent(eventType, message) app = QApplication() window = Window() window.show() app.exec()
Which does not work since the data is always empty:
Traceback (most recent call last): File "d:\documents\temp2.py", line 33, in <module> window.show() ~~~~~~~~~~~^^ File "d:\documents\temp2.py", line 26, in nativeEvent msg = struct.unpack("PIPPLllL", bytes) struct.error: Error calling Python override of QWidget::nativeEvent(): unpack requires a buffer of 48 bytes
I tried this:
def nativeEvent(self, eventType, message): if eventType == b'windows_generic_MSG': message2 = Shiboken.VoidPtr(message, 48) bytes = message2.toBytes() print(message2, bytes) msg = struct.unpack("PIPPLllL", bytes) print(f"Bytes: {bytes!r} Interpreted: {msg}") return super().nativeEvent(eventType, message)
It does not seem to change anything:
shiboken6.Shiboken.VoidPtr(Address 0x000000D9360DE0D0, Size 0, isWritable False) b'' shiboken6.Shiboken.VoidPtr(Address 0x000000D9360DEC40, Size 0, isWritable False) b'' ... more lines like above Traceback (most recent call last): File "d:\documents\temp2.py", line 28, in <module> window.show() ~~~~~~~~~~~^^ File "d:\documents\temp2.py", line 12, in nativeEvent msg = struct.unpack("PIPPLllL", bytes) struct.error: Error calling Python override of QWidget::nativeEvent(): unpack requires a buffer of 48 bytes
And this:
def nativeEvent(self, eventType, message): if eventType == b'windows_generic_MSG': message.size = 48 bytes = message.toBytes() print(message, bytes) msg = struct.unpack("PIPPLllL", bytes) print(f"Bytes: {bytes!r} Interpreted: {msg}") return super().nativeEvent(eventType, message)
No good either:
Traceback (most recent call last): File "d:\documents\temp2.py", line 28, in <module> window.show() ~~~~~~~~~~~^^ File "d:\documents\temp2.py", line 9, in nativeEvent message.size = 48 ^^^^^^^^^^^^ AttributeError: Error calling Python override of QWidget::nativeEvent(): 'shiboken6.Shiboken.VoidPtr' object has no attribute 'size' and no __dict__ for setting new attributes
Is this a bug or is it me missing something? Does anybody know how I can read a native event from
nativeEvent()
? (Let's say that I don't have an objective further than that and just want to understand the event data)