Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gtk.CssProvider.load_from_data TypeError: Item 0: Must be number, not str

I was getting this error when running my gtk project from a terminal with python3 myapp.py, but not when launching my app via Sublime-Text-3's python build system! How weird.

TypeError: Item 0: Must be number, not str

The code at fault was essentially:

color_scheme = {'fg_color':'#ffffff', 'bg_color': '#000000',}
css = """
    GtkLabel {
        color: %(fg_color)s;
        background: %(bg_color)s;
    }
"""

# ...

cssprovider = Gtk.CssProvider()
css_data = css % color_scheme
cssprovider.load_from_data(css_data)
like image 714
ThorSummoner Avatar asked Dec 27 '14 06:12

ThorSummoner


3 Answers

As mentioned in other answers (including yours), style_provider.load_from_data() is expecting bytes, not a string.

Instead of encoding your unicode string, you can define you CSS as a byte stream directly:

css = b"""
        #MyWindow {
            background-color: red;
        ...
    """

(Notice the b)

like image 127
Alberto Caso Avatar answered Oct 21 '22 12:10

Alberto Caso


I was able to dig up this from google: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698459

Josselin Mouette [2013-01-19 11:55 +0100]:

Le vendredi 18 janvier 2013 à 21:10 +0000, Tony Houghton a écrit :

TypeError: Item 0: Must be number or single byte string, not str

Well, if Python wants a byte string, send it a byte string, not a unicode one. That is, b"""blah blah blah""".

Indeed, closing. Alternatively, if you have an (unicode) string you can also call .encode() on it to turn it into a byte array.

Martin

First attempt to use bytes(css_data) did not work, but

css_data.encode()

worked!

like image 40
ThorSummoner Avatar answered Oct 21 '22 11:10

ThorSummoner


Just in case somebody wants a complete example which works and where you can see something.

WARNING: The gi package from PyPI (which can be installed with pip) is the wrong one!

#!/usr/bin/env python3
from gi.repository import Gtk, Gio, Gdk


# See also:
# http://wolfvollprecht.de/blog/gtk-python-and-css-are-an-awesome-combo/
class HeaderBarWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self,
                            title="Stack Demo",
                            decorated=True,
                            name="MyWindow")

        style_provider = Gtk.CssProvider()

        css = """
        #MyWindow {
            background-color: red;
            border-radius: 10px;
            outline:none;
        }

        #header {
            background-color: blue;
        }
        """
        style_provider.load_from_data(bytes(css.encode()))
        Gtk.StyleContext.add_provider_for_screen(
            Gdk.Screen.get_default(), style_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
        )

        self.set_border_width(10)
        self.set_default_size(400, 200)

        hb = Gtk.HeaderBar(name="header")
        hb.set_show_close_button(True)
        hb.props.title = "HeaderBar example"
        self.set_titlebar(hb)

        button = Gtk.Button()
        icon = Gio.ThemedIcon(name="mail-send-receive-symbolic")
        image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
        button.add(image)
        hb.pack_end(button)

        box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        Gtk.StyleContext.add_class(box.get_style_context(), "linked")

        button = Gtk.Button()
        button.add(Gtk.Arrow(Gtk.ArrowType.LEFT, Gtk.ShadowType.NONE))
        box.add(button)

        button = Gtk.Button()
        button.add(Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE))
        box.add(button)

        hb.pack_start(box)

        self.add(Gtk.TextView())

win = HeaderBarWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

gives:

enter image description here

like image 21
Martin Thoma Avatar answered Oct 21 '22 12:10

Martin Thoma