pyblish/pyblish-lite

High Dpi Fix raises Exception

Closed this issue · 11 comments

window.py", line 1074, in paintEvent scale = self.windowHandle().screen().logicalDotsPerInch() / 96.0 AttributeError: 'NoneType' object has no attribute 'screen'

I saw the high dpi fix and tested the latest release.
This was a quick test in nuke 11.3. This all might be related to RDP too. Was on windows, I will report back if this also happens without RDP.

Thanks for reporting this. This is because of Qt 4 (e.g. Maya 2016 and below) which doesn't support QScreen. Try sticking with the version before that, and I'll disable this on older systems. It would be great if you could have a look at that. To just go "if Qt < 5: don't use this function".

Hm Nuke11.3 is based on Qt 5.6.1....

Hmmm, looking closer at your message, the problem is windowHandle. There's already a check for Qt 5, forgot about that one.

def paintEvent(self, event):
if Qt.__qt_version__.startswith("5") and os.name == "nt":
# Only tested with Windows DPI scaling
scale = self.windowHandle().screen().logicalDotsPerInch() / 96.0
else:
scale = 1.0

That is odd indeed. Let me know if you find out more.

Hey Marcus,
happy new year!
I looked into the issue and it is caused by us. We are wrapping Lite into another widget.
Because of that, the widget is not the "native" widget anymore.

I added

self.setAttribute(QtCore.Qt.WA_NativeWindow)

in line62 in window.py and it solved the issue.
But I do understand that this is maybe not sth that belongs in here so, I think I can do this also after I made the instance in our code...

so PR or not PR is the question :-)
cheers

Great, I think we should definitely handle that.

Forcing a NativeWindow doesn't seem right, I think it would be better if we accepted that the window isn't native, and either avoid doing native things or do them in a non-native way. Lite should support this usecase.

In this case, we could check whether there is a handle, and if not ask the parent (i.e. your custom wrapper) for a handle. If neither of them are willing to provide a handle, we should abandon ship and provide the user with our reasoning so that they can address it.

Up for a PR like that? :)

ha, you are right!
Now that you mention it, I think just adding
self.window().windowHandle()....
should do the trick...
I dont think we need to LBYL.
I'll test...

https://doc.qt.io/qtforpython/PySide6/QtWidgets/QWidget.html?highlight=nativewindow#PySide6.QtWidgets.PySide6.QtWidgets.QWidget.window

In my tests here it always worked, wrapped and normal, the documentation has this weird part in brackets.
the next ancestor widget that has (or could have) a window-system frame.
I created a PR, we can get the window and check isWindow to make it secure... but I dont know if that is necessary.

        scale = 1.0
        if Qt.__qt_version__.startswith("5") and os.name == "nt":
            # Only tested with Windows DPI scaling
            if self.window().isWindow():
                scale = self.window().windowHandle().screen().logicalDotsPerInch() / 96.0
        for delegate in self._delegates:
            delegate.set_dpi_scale(scale)
        super(Window, self).paintEvent(event)

we could do it like this, but as I said I don't know in which case self.window is not a native/system window...

Ah, perfect. Just commented on the PR. We definitely need to be more careful; an error on that line would be very cryptic to any user, casual and advanced.

was this the PR this issue is refering too?
#119

if so can this issue be closed since PR went in?

Seems like it, thanks for cleaning house!