pygobject / pgi

[Unmaintained: Use PyGObject instead] GTK+ / GObject Introspection Bindings for PyPy.
GNU Lesser General Public License v2.1
74 stars 16 forks source link

Assertion 'GDK_IS_SCREEN (screen)' fails in frozen app #38

Closed mherrmann closed 7 years ago

mherrmann commented 7 years ago

Firstly, thanks for sharing this library. The concept is very elegant and useful.

I want to look up the icon for a directory (/home/michael in the code below):

import pgi
pgi.install_as_gi()
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk,Gio

file_path = '/home/michael'

f = Gio.file_new_for_path(file_path)
file_info = f.query_info('standard::icon', 0, None)
icon_name = file_info.get_icon().get_names()[0]
icon_theme = Gtk.IconTheme.get_default()
icon_filename = icon_theme.lookup_icon(icon_name, 32, 0)
print(icon_filename.get_filename())

This works fine when I do it in my Python shell. However, when I freeze the above code with PyInstaller, I get:

(process:15580): Gtk-CRITICAL **: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
Traceback (most recent call last):
  File "main.py", line 13, in <module>
AttributeError: 'NoneType' object has no attribute 'lookup_icon'
Failed to execute script main

The main problem seems to be the failing assertion GDK_IS_SCREEN. Googling for this assertion, I found that it may be related to the environment variables DISPLAY and XDG_CURRENT_DESKTOP. Unfortunately, that doesn't seem to be it as they are both set correctly (to :0 and Unity, respectively).

Do you happen to know what else could cause the assertion GDK_IS_SCREEN to fail, in a frozen app?

lazka commented 7 years ago

Looks like gtk init failed (you can check the return of Gtk.init_check(None)). no idea why.

I'd try to get things working with pygobject instead to rule out any missing pgi features.

mherrmann commented 7 years ago

Wow, that was a quick response. Thanks!

I've been having trouble getting pygobject installed in my virtualenv. Why would you recommend pygobject over pgi in this case?

lazka commented 7 years ago

try virtualenv --system-site-packages venv

Why would you recommend pygobject over pgi in this case?

Because pgi is currently so far away from feature complete that you can't run any reasonable sized/useful application with it.

mherrmann commented 7 years ago

The above code would be all I need so I was hoping that if it works from the shell then I may also be able to use it when my app is frozen. But I'll follow your advice. Thanks again!

lazka commented 7 years ago

Oh ok. just wanted to mention that I've only seen the above error when DISPLAY was missing, as you suspected. Not sure how "freezing" could affect that..

mherrmann commented 7 years ago

One difference I could see is that PyInstaller doesn't seem to ship dependencies as .py files but somehow encodes them inside a binary. It must then use some import hook to load them. I saw that pgi also uses import hooks. Could it be that the two clash somehow?

lazka commented 7 years ago

Yeah, that might be a problem and prevent python overrides from loading (this isn't tested at least).Try calling Gtk.init(sys.argv) right after import.

mherrmann commented 7 years ago

You're a genius. Calling Gtk.init(sys.argv) right after import fixes the problem!

lazka commented 7 years ago

I've opened #39 for this. Thanks.