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