I am learning wxPython. In one of the examples, the code is like follows:
import wx
class App(wx.App):
def OnInit(self):
frame = wx.Frame(parent=None, title = 'bare')
frame.Show()
return True
app=App()
app.MainLoop()
And I noticed that class App has no constructor but a function OnInit. As far as I know, Python classes are constructed with __init__ function.
So, is OnInit functions are for specific classes? Or it is another type of constructor?
Please forgive my ignorance since I am new to this. Thanks.
According to wx.App.__init__ documentation:
You should override OnInit to do applicaition initialization to ensure
that the system, toolkit and wxWidgets are fully initialized.
-> OnInit method is only for classes that derive wx.App.
Assuming you got the code from "wxPython in Action" book- good book would recommend,
It goes on to say (Im sure you have red this by now)...
Notice that we didn’t define an init()method for our application
class. In Python, this means that the parent method,
wx.App.init(), is automatically invoked on object creation. This
is a good thing. If you define an init() method of your own, don’t
forget to call the init()of the base class, like this:
class App(wx.App):
def __init__(self):
# Call the base class constructor.
wx.App.__init__(self)
# Do something here...
If you forget to do so, wxPython won’t be initialized and your OnInit()method won’t get called.
Related
In writing a tkinter root window as a class, I'm using the following code:
class RootWin(Tk):
def __init__(self,...args go here...):
super().__init__()
Although the code is correct, and works, I am uncomfortable writing code that I don't fully understand, and despite the many explanations I have come across, none have clarified this for me.
I understand that the line class RootWin(Tk): indicates that I am creating a class called RootWin that inherits from Tk. In the next line, self refers to the instance of this class I will create later in my code, and the args specify the parameters I want to pass to this specific instance. That much is very clear.
Then, the explanations I've come across indicate that super().__init__() runs the init method of Tk (the parent class).
But why is it necessary to run the init method of the Tk class? If class RootWin(Tk) already indicates that my new RootWin class inherits from Tk, then why would anything more be required?
Perhaps the best way to pose this question is to ask it in three explicit parts, and request three answers, with apologies, if that's asking a lot. I really want to understand this!
Question 1: What is accomplished by the line
class RootWin(Tk):
Question 2: What is accomplished by the line
def __init__(self,...args go here...):
Question 3: what is accomplished by the following line that has not already been accomplished by the two previous lines?
super().__init__()
Any advice appreciated.
But why is it necessary to run the init method of the Tk class?
Your own class has some initialization it performs, correct? There is code in your __init__ that must run for your class to be useful. This is where, for example, you would create other widgets for your app, variables, etc.
The tkinter base classes are the same way. They have code in their own __init__ method that must be run for the class to be useful. This code doesn't run automatically if you create your own __init__. Therefore, you must call it so that the widget is properly initialized.
Question 1: What is accomplished by the line class RootWin(Tk):
Answer: it begins the definition of a new class name RootWin that inherits from the class Tk
Question 2: What is accomplished by the line def __init__(self,...args go here...)
Answer: it defines a method that is automatically called by python when you create an instance of your custom class. It also defines the arguments that your function may require.
When you do foo = RootWin(), python will automatically call RootWin.__init__ and pass in the instance (self) as the first argument. The rest are to be supplied by the caller.
Question 3: what is accomplished by the following line that has not already been accomplished by the two previous lines? super().__init__()
Answer: First, it has not been accomplished by the two previous lines. Because of the two previous lines, python will not automatically call the __init__ method of the base class. That responsibility becomes yours when you define a custom __init__. When you call super().__init__() you are explicitly requesting that the __init__ method of the base class be called.
The advantage to requiring you to explicitly call it is that you now have a choice of when or if to call it. While you almost always should, you might choose to do some custom initialization either before or after the base class has been initialized.
Note that none of this is unique to tkinter. This is how all python objects work.
I've been working in python on a project where I have a GUI which I split up a bunch of the work between classes. I don't know a lot of the best practices for passing data around between classes, and I've frequently run into the issue, where I have to implement something, or change something for work, and I've resorted to making a lot of the classes objects of another class in order to give it the data I need.
Any ideas or suggests would be greatly appreciated on how to keep my classes independent for later modification and still pass the relevant data around without affecting interfaces too much?
As an example
class Window():
def __init__(self, parent=None):
self.parent = parent
def doStuff(self):
#do work here
class ParseMyWork(Window):
def __init__(self, parent=None):
self.parent=parent
I often find myself doing stuff like the above giving objects to class Window
or simply inheriting everything from them as in ParseMyWork
There must be better and cleaner ways of passing data around without making my classes utterly dependent on eachother, where one little change creates a cascade effect that forces me to make changes in a bunch of other classes.
Any answers to the question don't necessarily have to be in python, but it will be helpful if they are
If I'm understanding your question correctly, I would say that inheritance is not necessary in your case. Why not give ParseMyWork a function for dealing with a specific Window task?
class Window():
def __init__(self, parent=None):
self.parent = parent
def doStuff(self):
#do work here
class ParseMyWork():
def __init__(self, parent=None):
self.parent=parent`
def doWindowActivity(self, window):
window.doStuff
Then you can use the function like this
work_parser = ParseMyWork()
window = Window()
work_parser.doWindowActivity(window);
That way you can use your work_parse instance with any window instance.
Apologies in advance for my Python, it's been a while so if you see any rookie mistakes, do point them out.
Keep it simple.py:
def doStuff(window):
#do work here
return window
def parseStuff(stuff):
pass
really.py:
from simple import doStuff, parseStuff
def really_simple(window):
okay = doStuff(window)
return parseStuff(okay)
don't complicate the class:
from really import really_simple
really_simple(window)
imo: classes are overly complicated objects, and in a lot of cases more confusing than they need to be, plus they hold references and modify stuff, and can be difficult to decouple once they have been tied to other classes. if there isn't a clear reason why a class needs to be used, then it probably doesn't need to be used.
Classes are super powerful, so it's good you're getting started with em.
Discalimer: Haven't worked in python for a while now, so things might not be exact. The general idea still applies though.
Getting into your question now:
I would say the best way to achieve what you want is to create an instance of the first object where you will extract information from.
Now when creating a class, it's vital that you have attributes within them that you will want to be stored within it that you would like to retrieve once the class is instantiated.
For example, using your Window class example above, let's say that you have an attribute called resolution. It would look something like this:
class Window():
def __init__(self, parent = None):
self.parent = None
self.resolution = '40x80'
Now the resolution information associated with your Window class is forever part of any Window class instance. Now, the next step would be to create a get method for resolution. This should be done as follow:
class Window():
def __init__(self, parent = None):
self.parent = None
self.resolution = '40x80'
def getResoultion():
return self.resolution
Now, the reason we created this get method is because we can now set a variable to the information that is returned with it.
So let's say that you have everything associated with your Window class in its own file (let's say the file name is called Window.py). In a separate file (let's call it main.py), you can do the following:
import Window
windowInstance = Window()
windowResolution = windowInstance.getResolution()
If you print out the variable windowResolution, you should get that 40x80 printed out.
Now, as a side note, I do believe it is possible to get the information associated with an attribute with an instance of a class by simply doing something like
windowResolution = windowInstance.resolution
but that is bad practice in general. The reason, in a nutshell, is because you are now exposing attribute names of your class which you do not want to do because it makes it easy for a person outside of your code to learn the name where that information is held and change it. This can then lead to a myriad of other problems when it comes to making an overall program work. That is why it is best practice to use getters and setters. I already showed what getters are. Simply a get method for attributes. Setters, as you can probably assume, allow for one to set the information of an attribute to something else. Now you might say "Gabe, if we can create setter methods, what's the point of it if they just change it". My answer to that is to not give a setter method to all attributes. For attributes you don't mind for a person to change, give it a setter method, but for attributes you do not want any outside users to touch, simply don't create a setter method for it. Same goes with getter methods too. Users don't need to see all of the information of all attributes that makes your program work. Here's a better explanation: https://en.wikipedia.org/wiki/Mutator_method
Now, back to your example. Now let's say you have your ParseMyWork class in its own file like we did with your Window class, and let's say that ParseMyWork needs the resolution info from Window class. You can do the following :
import Window
import ParseMyWork
windowInstance = Window()
windowResolution = windowInstance.getResolution()
parseInstance = ParseMyWork(windowResolution)
This will only pass the window resolution information associated with your Window class. Hope this helps.
I apologize if the question is not a correct statement about what is going on or it turns out to be specific for the example that I describe. It is just what I noticed. I have been learning how to make GUIs using Tkinter in Python 2.7 and I have followed several tutorials, and I have seen several different styles for structuring the code.
One way is the following:
import Tkinter as tk
root = tk.Tk()
root.title("My App")
root.mainloop()
The other way I have seen is:
import Tkinter as tk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
tk.Tk.title("My App")
root = App()
root.mainloop()
The second method creates a class App that inherits from the tk.Tk class, thus making App a subclass of tk.Tk? def __init__(self): is the constructor for class App I am defining. But then I must also call the __init__() function from the tk.Tk class as well. If that is true, why is that? When I just run root = tk.Tk(), its __init__() function is called then?
Yes, when you run root=tk.Tk() then an instance of the class tk.Tk is instantiated -- which means calling the __init__ of this class.
In the second method you want to create a new class -- which might be useful especially in a larger project, to be able to port it anywhere else.
You cannot append something to the parent's __init__ method, you can just override it by defining it anew. So if you still want all the useful stuff to happen, which is executed in the tk.Tk.__init__(), you have to call it explicitly.
One might argue, that a better style would be to use super() instead of hardcoding the parent class name. But this gets relevant in still more complicated projects...
When you create a class object, it's constructor gets called automatically. This is what is happening in both snippets. The first one instantiates an object for the Tk class so therefore the __init__ method for the Tk class gets called. Where in the second way, you are not creating an object for the Tk class. You are creating an object for your App class. This does not mean it will call the constructor for the class that it has inherited from. You need to call it explicitly.
I am trying to learn PyQt on my own from rapid gui programming with python and qt and having trouble understanding the meaning/requirement of below line of code mentioned in one of the example in the book.
class Form(QDialog):
def __init__(self,parent=None):
super(Form,self).__init__(parent) # Trouble understanding here
So, my question is what is the need of super(Form,self).__init__(parent) or what purpose it is trying to full fill in this code.
Take a look at the documentation of super():
Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.
So basically this line of code:
super(Form,self).__init__(parent)
finds the "closest" set __init__() method in classes from which current class (Form) is inheriting and initiates self object using this method and passing parent as the first argument.
In the project that I'm building, I'd like to have a method called when I paste some text into a specific text field. I can't seem to get this to work, but here's what I've tried
I implimented a custom class (based on NSObject) to be a delegate for my textfield, then gave it the method: textDidChange:
class textFieldDelegate(NSObject):
def textDidChange_(self, notification):
NSLog("textdidchange")
I then instantiated an object of this class in interface builder, and set it to be the delegate of the NSTextField. This however, doesn't seem to do anything. However, when I build the example code from http://www.programmish.com/?p=30, everything seems to work perfectly fine. How do I impliment this delegate code so that it actually works?
The reason this isn't working for you is that textDidChange_ isn't a delegate method. It's a method on the NSTextField that posts the notification of the change. If you have peek at the docs for textDidChange, you'll see that it mentions the actual name of the delegate method:
This method causes the receiver’s delegate to receive a controlTextDidChange: message. See the NSControl class specification for more information on the text delegate method.
The delegate method is actually called controlTextDidChange_ and is declared on the NSTextField superclass, NSControl.
Change your delegate method to:
def controlTextDidChange_(self, notification):
NSLog("textdidchange")
and it should work for you.