1. Problems list for porting Jokosher from GTK+2/PyGTK to GTK+3/PyGI
This is working list of problems for my Google Summer of Code project to port Jokosher (which is fairly classic GTK+2/PyGTK application) to Gtk+3 using Python Gobject Introspection. More about GObject Introspection read here.
1.1. Problem #1
See Jokosher/JokosherApp.py, line 2054
Solution: Problem with GtkTextBuffer.get_text function - now it requires additional Boolean value for including hidden text. Had to take get_bounds out of params because it otherwise didn't allow Boolean to follow.
Status: SOLVED |
1.2. Problem #2
(jokosher:1971): Gtk-WARNING **: Unknown property: GtkDialog.has-separator
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/AddInstrumentDialog.py", line 111, in OnSelected
self.OnOK()
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/AddInstrumentDialog.py", line 127, in OnOK
item = self.model[i[0]]
TypeError: 'TreePath' object does not support indexingSolution: it is a GtkIconView, get_selected_items method now returns !GList with GtkTreePath. API can be found here: http://developer.gnome.org/gtk3/3.0/GtkTreeModel.html#GtkTreePath-struct We use GtkTreePath.to_string() method to extract selected value from GtkTreePath (which is counted by value of i)
Status: SOLVED |
1.3. Problem #3 - Problems with Unicode symbols
[(u'Akustisk\u0101 \u0123it\u0101ra', 'acousticguitar')]
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/AddInstrumentDialog.py", line 111, in OnSelected
self.OnOK()
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/AddInstrumentDialog.py", line 135, in OnOK
self.project.AddInstruments(instrList)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/Project.py", line 1190, in AddInstruments
instr = self.AddInstrument(name, type, _undoAction_=undoAction)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/UndoSystem.py", line 95, in UndoWrapper
project.SaveIncrementalAction(inc)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/Project.py", line 867, in SaveIncrementalAction
incr_file.write(action.StoreToString())
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/IncrementalSave.py", line 178, in StoreToString
self.WriteToXMLAttributes(None, arg, node)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/IncrementalSave.py", line 195, in WriteToXMLAttributes
Utils.StoreVariableToNode(value, node, "type", "value")
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/Utils.py", line 380, in StoreVariableToNode
node.setAttribute(valueAttr, str(value))
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0101' in position 8: ordinal not in range(128)Solution: Not sure if it's jhbuild problem, or something I can fix within Jokosher.
Status: NEED MORE INFORMATION |
1.4. Problem #4 - Gdk drawable methods replaced by Cairo context drawing
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/EventLaneViewer.py", line 152, in OnDraw
gc = wnd.new_gc()
AttributeError: 'gtk.gdk.X11Window' object has no attribute 'new_gc'Solution: replace GDK methods with Cairo ones, using pycairo.
Notes: Old method
http://developer.gnome.org/gdk/stable/gdk-Drawing-Primitives.html#gdk-draw-line
New method
http://cairographics.org/manual/cairo-Paths.html#cairo-line-to
http://zetcode.com/tutorials/cairographicstutorial/basicdrawing/
Status: SOLVED |
1.5. Problem #5
(jokosher:2646): Gtk-WARNING **: Unknown property: GtkDialog.has-separator
Solution: Problem within "Project Properties" dialog .ui file, which has has_separator attribute enabled, which are removed in 3.0. It gives separator between form stuff and buttons. Not sure what replaces it in 3.0.
Status: NEED MORE INFORMATION |
1.6. Problem #6
Traceback (most recent call last):
File "/home/peteris/Dokumenti/pyintrospection-gtk3/Jokosher/InstrumentViewer.py", line 324, in OnInstrumentSelected
self.modify_bg(Gtk.StateType.NORMAL, self.SELECTED_COLOUR)
File "/opt/gnome/lib/python2.6/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
TypeError: argument 2: Must be Gdk.Color, not RGBASolution: replace modify_bg with override_background_color()
Status: SOLVED |
1.7. Problem #7
GLib-GIO-Message: Using the 'memory' GSettings backend. Your settings will not be saved or shared with other applications.
Solution: Could not reproduce, but will have to look at Gconf replacement stuff anyway later.
Status: NEED MORE INFORMATION |
1.8. Problem #8
Traceback (most recent call last):
File "/home/peteris/Dokumenti/pyintrospection-gtk3/Jokosher/InstrumentViewer.py", line 224, in OnEditLabel
width = self.labeleventbox.size_request()[0]
TypeError: 'Requisition' object does not support indexingSolution: change size_request to get_preffered_size(). It retuns two GtkRequisition objects, which in turn has 'width' and 'height' attributes. So for example to get minimal size of widget, get_preffered_size()[0].width minimal size is first GtkRequisition of tulpe
Status: SOLVED |
Notes: Fixing this I encountered strange error which causes every GtkWdiget to be double in width with my current jbhuild setup.
1.9. Problem #9
File "/home/peteris/Dokumenti/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 745, in OnPreferences
prefsdlg = PreferencesDialog.PreferencesDialog(self.project, self, self.icon)
File "/home/peteris/Dokumenti/pyintrospection-gtk3/Jokosher/PreferencesDialog.py", line 75, in __init__
self.recordingSoundSystem.append_text(_("Custom"))Solution: GtkComboBox is replaced by GtkComboBoxText and remove GtkRenderCellText because Gtk will create one when adding text entries.
Status: SOLVED |
1.10. Problem #10
File "/home/peteris/Dokumenti/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 410, in About
Gtk.AboutDialog.set_website(self.AboutLinkActivate)
TypeError: unbound method set_website() must be called with AboutDialog instance as first argument (got instancemethod instance instead)Solution: Use new_with_model() to initialise GtkComboBox properly.
Status: SOLVED |
Notes: solved with applying set_website and set_website_label on GtkAboutDialog object. not fully sure this is right way.
1.11. Problem #11
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 1502, in OnInstrumentConnectionsDialog
InstrumentConnectionsDialog.InstrumentConnectionsDialog(self.project, self)
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentConnectionsDialog.py", line 54, in __init__
self.Populate()
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentConnectionsDialog.py", line 126, in Populate
combobox = Gtk.ComboBox(liststore)
TypeError: GObject.__init__() takes exactly 0 arguments (1 given)Solution: Use new_with_model() to initialise GtkComboBox properly.
Status: SOLVED |
1.12. Problem #12
/usr/lib/gstreamer0.10/gstreamer-0.10/gst-plugin-scanner: /opt/gnome/lib/libxml2.so.2: no version information available (required by /usr/lib/libgstreamer-0.10.so.0)
** Message: pygobject_register_sinkfunc is deprecated (GstObject)
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/ControlsBox.py", line 217, in OnEffectsButtonClicked
self.mainview.icon)
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 52, in __init__
self.gtk_builder = Globals.LoadGtkBuilderFilename("InstrumentEffectsDialog.ui")
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/Globals.py", line 371, in LoadGtkBuilderFilename
builder.add_from_file(os.path.join(GTK_BUILDER_PATH, filename))
File "/opt/gnome/lib/python2.6/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
glib.GError: Invalid object type `GtkComboBoxEntry'Solution: Change GtkComboBoxEntry to GtkComboBoxText with has-entry enabled. Remove GtkRenderCellText too.
Status: SOLVED |
1.13. Problem #13
Traceback (most recent call last):
File "/opt/gnome/lib/python2.6/site-packages/gi/overrides/Gtk.py", line 298, in _full_callback
raise AttributeError('Handler %s not found' % handler_name)
AttributeError: Handler on_listActiveEffects_selected not found
Traceback (most recent call last):
File "/opt/gnome/lib/python2.6/site-packages/gi/overrides/Gtk.py", line 298, in _full_callback
raise AttributeError('Handler %s not found' % handler_name)
AttributeError: Handler on_listEffects_selected not foundSolution: This is not a porting bug, this is undefined handler for signal. Defering it for solving later.
Status: NEED MORE INFORMATION |
1.14. Problem #14
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/ControlsBox.py", line 217, in OnEffectsButtonClicked
self.mainview.icon)
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 131, in __init__
self.filterEffects = self.modelEffects.filter_new()
File "/opt/gnome/lib/python2.6/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
TypeError: filter_new() takes exactly 2 argument(s) (1 given)Solution: filter_new() which is GtkTreeModelFilter method requires additional argument of GtkTreePath root. Set to None fixed it.
Status: SOLVED |
1.15. Problem #15
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 308, in OnClose
self.instrument.project.disconnect_by_func(self.OnProjectPlay)
TypeError: nothing connected to <bound method InstrumentEffectsDialog.OnProjectPlay of <InstrumentEffectsDialog.InstrumentEffectsDialog instance at 0x945856c>>
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 1047, in OnDestroy
Globals.settings.general["instrumenteffectwindowwidth"] = self.width
AttributeError: InstrumentEffectsDialog instance has no attribute 'width'Solution: Happened in combination with another bug, but can't reproduce it anymore. InstrumentEffectsDialog has this attribute defined properly.
Status: CAN'T REPRODUCE |
1.16. Problem #16 - GtkTreePath syntax changed, doesn't support indexing
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 639, in OnEffectSettings
self.effectpos = self.modelActiveEffects[selection[1]].path[0]
TypeError: 'TreePath' object does not support indexingSolution: Use path.get_indices() to get list of ints for selected object indexes (GtkTreePath).
Status: SOLVED |
1.17. Problem #17
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 653, in OnEffectSettings
self.settings_gtk_builder = Globals.LoadGtkBuilderFilename("EffectSettingsDialog.ui")
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/Globals.py", line 371, in LoadGtkBuilderFilename
builder.add_from_file(os.path.join(GTK_BUILDER_PATH, filename))
File "/opt/gnome/lib/python2.6/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
glib.GError: Invalid object type `GtkComboBoxEntry'Solution: Similar to previous problems, change GtkComboBoxEntry to GtkComboBoxText with has-entry enabled. Remove GtkRenderCellText too.
Status: SOLVED |
1.18. Problem #18 - GtkHScale should be initialised with new() method
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 741, in OnEffectSettings
self.sliderdict[property.name] = hscale = Gtk.HScale(adj)
TypeError: GObject.__init__() takes exactly 0 arguments (1 given)Solution: !HScale should created properly by method new(GtkAdjustment).
Status: SOLVED |
1.19. Problem #19 - Another path[0] cases
Changed path[0] to path.get_indices()[0] in OnEffectDeleted, OnEffectUp, OnEffectDown too.
Status: SOLVED |
1.20. Problem #20 - using set_cursor()
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrāde/pyintrospection-gtk3/Jokosher/InstrumentEffectsDialog.py", line 622, in OnEffectDeleted
self.listActiveEffects.set_cursor(None, None, False)
File "/opt/gnome/lib/python2.6/site-packages/gi/types.py", line 44, in function
return info.invoke(*args)
TypeError: argument 1: Must be Gtk.TreePath, not NoneType
Method must get three arguments, and first of them must be TreePath object (other two can be None and False).Solution: set_cursor must have three params, and first one should be GtkTreePath. Must understand which one I should set to.
Status: UNRESOLVED |
1.21. Problem #21 - Waveform drawing doesn't work
Waveform drawing doesn't work and event doesn't get created. I don't get any errors or warnings. It seems that I need to convert pygst to Gst/GI for it to work properly.
Status: UNRESOLVED |
1.22. Problem #22 - GtkMenu.popup() requires additional param
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/EventLaneViewer.py", line 231, in OnMouseDown
self.contextMenu.popup(None, None, None, mouse.button, mouse.time)
TypeError: popup() takes exactly 7 arguments (6 given)Solution: provide additional parameter for method, which is data for function which is passed as third parameter, For more see http://developer.gnome.org/gtk3/stable/GtkMenu.html#gtk-menu-popup
Status: SOLVED |
1.23. Problem #23 - "import gst" and similar strings must be change to "from gi.repository import Gst", also "gst." must be changed to "Gst."
Solution: Grep for import clauses, and use customised script to replace gst. with Gst.
Status: SOLVED |
1.24. Problem #24 - GtkMenu.popup() requires additional param
Traceback (most recent call last):
File "Jokosher/Jokosher", line 106, in <module>
JokosherApp.MainApp(openproject, loadExtensions, startupType)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 260, in __init__
self.CheckGstreamerVersions()
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 1672, in CheckGstreamerVersions
gnl = Gst.registry_get_default().find_plugin("gnonlin")
File "/data/opt/gnome/lib/python2.7/site-packages/gi/module.py", line 274, in __getattr__
return getattr(self._introspection_module, name)
File "/data/opt/gnome/lib/python2.7/site-packages/gi/module.py", line 105, in __getattr__
self.__name__, name))
AttributeError: 'gi.repository.Gst' object has no attribute 'registry_get_default'Solution: use Gst.Registry.get_default() method. This repeats several times in next lines in the code.
Status: SOLVED |
1.25. Problem #25 - Empty plugin list
Solution: when using GObject Introspetion and Gstreamer, you must initialise Gstreamer with Gst.init(None), where None in this case is list of params passed to it (t.i. we pass nothing).
Status: SOLVED |
1.26. Problem #26 - Gstreamer error exceptions doesn't work
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 883, in OnNewProject
project = ProjectManager.CreateNewProject(name, author)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 41, in CreateNewProject
project = InitProjectLocation(projecturi)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 79, in InitProjectLocation
except Gst.PluginNotFoundError, e:
NameError: global name 'Gst' is not definedSolution: although annotations specification mentions availability to define throwing exceptions in case of error (http://live.gnome.org/GObjectIntrospection/Annotations), it isn't implemented in GObject Introspection yet, therefore it is not fixable at this point.
Status: SOLVED |
1.27. Problem #27 - wrong parent defined when constructing object
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 899, in OnNewProject
dlg = Gtk.MessageDialog(self.dlg,
AttributeError: MainApp instance has no attribute 'dlg'Solution: Change self.dlg to self.window, as it is rightful parent of message dialog window.
Status: SOLVED |
1.28. Problem #28 - use right constructor for Gst.Pipeline object
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 883, in OnNewProject
project = ProjectManager.CreateNewProject(name, author)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 41, in CreateNewProject
project = InitProjectLocation(projecturi)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 77, in InitProjectLocation
project = Project.Project()
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/Project.py", line 144, in __init__
self.mainpipeline = Gst.Pipeline("timeline")
TypeError: GObject.__init__() takes exactly 0 arguments (1 given)Solution: use Gst.Pipeline.new() method (constructor).
Status: SOLVED |
1.29. Problem #28 - use right constructor for Gst.Bin object
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 883, in OnNewProject
project = ProjectManager.CreateNewProject(name, author)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 41, in CreateNewProject
project = InitProjectLocation(projecturi)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 77, in InitProjectLocation
project = Project.Project()
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/Project.py", line 145, in __init__
self.playbackbin = Gst.Bin("playbackbin")
TypeError: GObject.__init__() takes exactly 0 arguments (1 given)Solution: use Gst.Bin.new() method (constructor).
Status: SOLVED |
1.30. Problem #29 - where to find and how to use gst_parse_bin_from_description
Traceback (most recent call last):
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/JokosherApp.py", line 883, in OnNewProject
project = ProjectManager.CreateNewProject(name, author)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 41, in CreateNewProject
project = InitProjectLocation(projecturi)
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/ProjectManager.py", line 77, in InitProjectLocation
project = Project.Project()
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/Project.py", line 149, in __init__
self.masterSink = self.MakeProjectSink()
File "/home/peteris/Dokumenti/Izstrade/pyintrospection-gtk3/Jokosher/Project.py", line 1609, in MakeProjectSink
sinkBin = Gst.Parse().bin_from_description(sinkString, True)
File "/data/opt/gnome/lib/python2.7/site-packages/gi/module.py", line 274, in __getattr__
return getattr(self._introspection_module, name)
File "/data/opt/gnome/lib/python2.7/site-packages/gi/module.py", line 105, in __getattr__
self.__name__, name))
AttributeError: 'gi.repository.Gst' object has no attribute 'Parse'Solution: use Gst.parse_bin_from_description() method. Parse as object isn't exported to annotations (and propably won't be).
Status: SOLVED |
1.31. Problem #30 - how to use Gst.Iterator.next() method
Solution: Previously using Gstreamer python bindings you never came into contact with iterator objects. In Gst/GI it's the only way to get sinks from bin. Therefore, to access this list (when getting it with Gst.Bin.iterate_sinks()), you must use next() method now on Gst.Iterator as returned value, which will step by step give you sinks of the mentioned bin. However, next() method is not usable without changing it's syntax, because it returns GstIteratorResult and passes actual return value to pointer which is only param of the method. As Python doesn't allow such syntax, I use (out caller-allocates) annotation for this param and use this method in this way:
return_result, return_value = Gst.Iterator.next()
P.S.: problem was reported, patch provided and fixed in Gstreamer 0.11 branch http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?h=0.11&id=59bf122584a6c33db99ba4da1851aab09092d61a
Status: SOLVED |
1.32. Problem #31 - How to use Gst.ElementFactory.make()
Solution: Use Gst.ElementFactory.make() method instead of gst.element_factory_make(). Also pass second argument as name (or None if you want Gstreamer to assign name itself).
Status: SOLVED |
1.33. Problem #32 - Problem with GObject Introspection and floating reference GObject (GInitiallyUnowned)
Solution: Short recap of the problem - In 0.11 series Gstreamer starts to use Glib floating reference support. In 0.10 series Gstreamer GI support worked with (transfer full) for floating ref objects as returned values (for not fully understood reasons, but 0.10 used it's own float ref object system), but in 0.11 this resulted in segfault. Someone must use (transfer none) to get floating ref object as return value. After receiving object, it is sinked with ref_sink() in bindings (for example, in pygobject or gjs). and floating reference is converted to common one, with binding as owner of it. Mind you it is temporary solution as Gstreamer and GI devs look for more elegant solution. For more read here https://bugzilla.gnome.org/show_bug.cgi?id=656205
Status: TEMP. SOLVED |