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 indexing
Solution: 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 RGBA
Solution: 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 indexing
Solution: 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 found
Solution: 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 indexing
Solution: 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 defined
Solution: 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 |