=== tux_race1 is now known as tux_racer [06:24] good evening [06:24] can any1 help with installing video drivers === mrjohns_ is now known as mrjohns === kermiac_ is now known as kermiac [14:01] jcastro, hello, is there any way that there`d be a class on doing unittesting using python? [14:06] zubin71: that's something you'd be interested in seeing in a class? === kermiac is now known as kermiac_ [14:07] Pendulum, yes, im new to python programming.... And i came across this topic pretty recently... [14:07] we have a small OS community here... [14:07] we`d love to have classes on unit testing... [14:08] OSS* [14:08] typo [14:10] Pendulum, are you an ubuntu developer? python? If holding classes if difficult , it`d be great if there were at least some ubuntu community documentation... [14:11] zubin71: I'm not, but I'm a member of the Ubuntu Classroom team :) [14:11] so I'm bringing your suggestion back so we can look for an instructor :) [14:13] awesome! also, it`d be great if I could help by taking sessions on a subject in a couple of months... maybe on unittesting itself, if im comfortable with it in the near future... :) [14:25] Pendulum, well, c ya later! have a nice day! === yofel_ is now known as yofel === ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - http://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Event: Ubuntu Opportunistic Developer Week - Current Session: Using GTK+ signals in Python - Sense Hofstede - Instructor: qense || Questions in #ubuntu-classroom-chat [19:01] Hello everyone! [19:01] This session I will be talking about GTK+ signals. [19:03] Signals aren't specific to GTK+, but opportunistic programmers will deal mostly with GTK+ signals. [19:03] What are signals? [19:03] Signals are a nifty way of allowing an application or library to respond to certain events. [19:04] Signals are emitted at all sorts of events, so you can listen to almost anything if you know where to look. [19:04] I assume that most of you are using Python, so I'll be mainly using Python examples. [19:05] However, since the PyGTK library is generated from the C GTK+ library it is not that different. [19:05] Object.connect("signal-name", callback_function) is equal to g_signal_connect(signal_owner, "signal-name", G_CALLBACK (callback_function)) [19:06] A really good source of information is http://www.pygtk.org/docs/pygtk/ [19:06] This is the online documentation of PyGTK and you can find, amongst other things, all signals documented here. [19:07] It is important to keep in mind that most types in the GTK+ and GObject libraries are derived from other GTK+ and/or GObject types. [19:07] All types are derived from gobject.GObject [19:08] A type has got all signals it's derived from. [19:08] gobject.GObject has got only one signal 'notify' [19:08] However, that means that all GTK+ objects have got that signal as well. [19:09] The 'notify' signal is emitted whenever an property of the object is changed. [19:10] However, this doesn't have to mean the value of those properties has changed, it could have been that someone or something assigned the an identical value to a property [19:11] All GTK+ types are derived from gtk.Object (gtk.Object itself is derived from gobject.GObject) [19:11] gtk.Object has one signal as well: 'destroy' [19:11] This is emitted when the object is destroyed [19:11] You use this e.g. when constructing a window. [19:11] window = gtk.Window(); [19:11] window.show(); [19:12] window.connect("destroy", gtk.main_quit()); [19:12] gtk_main(); [19:12] Now, what did I write above? [19:12] First I created a new window, then I showed it and then I connected a callback function. [19:12] Whoops [19:12] I see I connected it wrongly. [19:13] This sure would have generated a bug. [19:13] It should have been [19:13] window.connect("destroy", gtk.main_quit); [19:13] Without the parentheses. [19:14] What you do when connecting is first specifying the signal name, then you give the reference to the callback function. [19:14] However, if you add the parentheses you invoke the method. [19:14] As you can see I connected a method from a library: gtk.main_quit() [19:14] That method ends the GTK+ loop. [19:15] If you wouldn't connect this to a destroy signal you would have to forcefully quit the application in order for the GTK+ main loop to end. [19:16] You can also specify locally defined methods as callback functions. [19:16] Any questions about the working of GTK+ signals, or about what I've told so far? [19:19] ryzrecreel asked: So the callback function can be the method of another object? [19:20] ryzrecreel: Yes, the callback can be any valid method. When connecting signals from inside a class you could e.g. also specify "self.my_wonderful_callback" method as the callback function. [19:20] However, you can't assign MyClass.my_callback as the callback function, you need to pass the method of an instance. [19:21] OK, lets talk a bit more about the callback function. [19:22] Because when a signal is emitted and your well-crafted callback function is called you want to know something more about what happened. [19:22] For that a series of arguments are sent to the callback function. [19:22] You need to make sure that it can accept those arguments. [19:23] Most of those callback functions look the same. [19:23] This is what the PyGTK documentation says the callback function for the 'notify' signal should look like: [19:23] def callback(gobject, property_spec, user_param1, ...) [19:24] If you're defining the callback as a member of a class make sure you add an extra 'self' argument to the beginning [19:24] the first argument of the callback function is 'gobject', but of course you can change the names in your own code. [19:24] 'gobject' is the GObject that changed and therefore emitted the notify signal [19:25] Most of the times you know what object you're getting since you specifically connected your callback to it, but this can be useful when you're connected to multiple objects. [19:25] But mostly it's very useful to have a reference to the object by hand [19:25] the second argument is 'property_spec' [19:26] It provides information about the property that changed so you can access it if you would want to. [19:26] The last is user data; when connecting to a signal you can provide extra userdata as extra arguments at the end of the function. [19:26] You'd do this: [19:27] window.connect("destroy", gtk.main_quit, "test-window", 123); [19:27] and the last two arguments would be the last two arguments for the callback function [19:29] lsteeger asked: What happens if the object used for the callback function in 'connect' call is destroyed before the event occurs? [19:30] lsteeger: If you didn't disconnect the callback function first you will get an error. [19:31] When you connect to a signal using the .connect() function the connect() function returns a handler id. [19:31] You can pass that handler id as the sole argument for .disconnect() for disconnecting from the signal. [19:32] Naturally, when you remove the object you connected to the callbacks are disconnected automatically. [19:32] There are a few very interesting signals. [19:32] gtk.Widget has the most, which means all GtkWidgets have got them. [19:33] To give you an idea of what you can do with GTK+: all you see happening on screen is mostly done with publicly accessible signals and methods. [19:34] There is a 'show' signal that is emitted when the show() method is called. [19:35] There is a 'show-help' signal that is emitted when the user presses Ctrl+F1 on his or her keyboard. [19:37] An interesting signal is "enter-notify-event", which is emitted whenever a mousebutton enters the widget. [19:38] It is used by many widgets like buttons. [19:38] lsteeger asked: If I extend a widget, can I define 'new' signals of my own? [19:38] lsteeger: Excellent question! [19:39] Yes you can, it is exactly what all widgets are doing. [19:40] You do that with the "gobject.signal_new()" function since actually signals are provided by GObject. [19:41] Lets paste the function from the documentation: [19:41] def gobject.signal_new(signal_name, type, flags, return_type, param_types) [19:41] The first argument is the name you give to the signal. [19:41] This has to be a unique name. [19:41] The second is the object (type) you're adding the signal to. [19:42] If you want to add a signal to myproject.MyWidget you write myproject.MyWidget there, without quotation marks. [19:42] The third argument is an interesting one: there you provide flags. [19:43] it goes a bit too far to explain them all, but you can make the signals do more than what I showed with the 'destroyed' signal. [19:43] most of the times you provide something like gobject.SIGNAL_RUN_LAST as the flag. [19:43] It has got something to do with when you emit the signal. [19:44] If you want to provide multiple flags you use | to separate them [19:45] The next argument is the return type of your callback function, which could be something like gobject.TYPE_STRING or gobject.TYPE_NONE if your callback doesn't return anything at all. [19:45] The last argument is a tuple of types of the arguments passed to the callback. [19:46] e.g. (myproject.MyWidget, gobject.TYPE_BOOL) [19:46] You're not finished with just defining a signal, you'll also want to emit it something. [19:46] somehwere [19:47] You do that with gobject.emit() method. [19:47] The first argument is the signal name [19:47] The others are the arguments that are sent to the callback [19:48] If you want to emit a signal inside your MyWidget class you call self.emit() [19:49] lsteeger asked: With multiple subscribers to an object's events, does the emit() infrastructure apply a hierarchy to their invocation? [19:50] lsteeger: Yes it does, the first callback that is connected to a signal is the first to be called. [19:51] you can use the . stop_emission(signal_name) method to stop the emission, if you wanted to. [19:51] lsteeger: yes, First In, First Out indeed [19:52] However, the default signal handler is always at the end of the list. [19:52] You'll have to use the .connect_after() method to be added after that callback. [19:53] Default signal handlere? What is that? [19:53] It is the default signal handler, and it's always called. [19:53] If it's specified, of course. [19:54] You can do that by creating a function in a class with the name "do_signal_name" [19:55] If you want to override default signal handlers, make sure you add __gtype_name__ = "MyWidget" as a class property [19:55] class MyWidget (gtk.Widget): [19:55] __gtype_name__ = "MyWidget" [19:56] Any questions about what I've told this session? [19:56] Or other questions? [19:58] Remember, if you want to learn what signals there are, go to http://www.pygtk.org/docs/pygtk/ and take a look at the page of the widget you want to know more about. [19:59] ryzrecreel asked: when using quickly with glade the connects are made for you. Is there any way to over ride that? [19:59] ryzrecreel: In the generated code you can see that the signals are connected using .connect_object() [20:00] That means it searches for the callback functions in the object you provide. [20:00] The callback functions are provided in Galde [20:00] Glade [20:00] you can change those there. === ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - http://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi [20:00] QUESTION: In a multi-core/processor environment, do multiple event handlers get invoked asynchrounously? [20:01] lsteeger: That doesn't depend on multi-threading, signal handlers don't get handled asynchronously, but one by one. [20:01] OK, thank you for listening, this was all! [20:01] This also was the last session of the Ubuntu Opportunistic Developer Week [20:01] I hope you enjoyed it.