This has very little to do with object orientation, and much more to do with Tkinter.
I myself find very bad the inherited design of the classes of the application of Tkinter classes. Since the early 90s, in C++ programming for Windows, and unfortunately, all the documentation of Tkinter does as in this example: inherits the main part of the application from the window component of the framework (in this case, the Seaofbtcapp class inheriting from Tkinter.Tk).
You don’t get almost anything out of it, unless someone thought it was cute back there in Windows programming. But your program doesn’t have much to do with a window to BE a window, which that heritage implies. It’s much simpler if it has a window. Then it does the network and file accounts and transactions it has to do, and when interacting with the user, then yes, it uses the window methods.
In the "real world" someone woke up to this about 10 years ago, and wrote some good articles - a "composition vs heritage" debate. That is: your program can be a class that has several attributes, among them a window (composition) or a window (inheritance). Unfortunately, although it is almost consensual that composition is better in terms of maintenance of the program, this clarification was not given in the existing documentation and examples.
Specifically entering your question: in Tkinter, the first parameter of each component is always your "parent" - in the case of a single window, in general that window. Now, because of the design choice, the main window of the program is the program itself. That is, the "self".
So the class that could only worry about the logic of inputs and outputs and currency exchange transactions, which is already complicated enough, has to also worry about accommodating all methods and attributes to manage a Tkinter application - which are of the order of 250 items.
You can have a program working exactly the same way if you don’t inherit anything from your class, and create an attribute self.window = tkinter.Tk()
- ready, the 262 attributes needed to manage the window application are isolated in self.window - and you are free to have attributes such as self.wallet_number, self.balance, self.last_quotation for your application logic.
Object orientation is really cool, but when it’s understood organically. The wrong use of this style of window inheritance applications, just forces an unnatural use that complicates and mixes concepts, It’s got to be so confusing for you.
OOP until permtie you create a class that doesn’t worry nothingness with the interface - only with the logic of the application itself - and then a subclass that inherits everything it does, and brood additional attributes to be the window, text entries, and buttons of your program.
Let’s think of an application two orders of magnitude simpler - instead of wanting to start from a bitcoin wallet, without understanding right how a wallet works, without understanding right how Tkinter works, and without understanding right how it works object orientation (it’s - it looks like you were in a bush without a dog) - a simple schedule that only has phone, email and people’s names.
In Python, we can use a Person class to have the name, address and phone data. Hence each person who is in the memory of the program will be an "instance" of the class, or an "object":
class Pessoa:
def __init__(self, nome="", email="", telefone=""):
self.nome = nome
self.email = email
self.telefone = telefone
Done. In Python, we have the lists. Our simple application can keep the data of several people in a list. And have a Tkinter application class. The application can have: a space for the name, an email, a button for the phone, a button for "next" a button for "previous" and a button for "new". We won’t have multiple instances of the application, even creating a class for it - the advantage here is that several methods linked to the class can share data: for example, everyone can access the list of names.
import Tkinter
class person:
def init(self, name="", email="", phone=""):
self name = name
self.email = email
self.phone = phone
def create_entry(root, label):
frame = Tkinter. Frame(root)
label = Tkinter. Label(frame, text=label + ":")
variable = Tkinter. Variable()
entry = Tkinter. Entry(frame, textvariable=variable)
label.pack()
entry.pack()
frame.pack()
Return variable
class App:
def __init__(self):
self.window = tkinter.Tk()
self.name_var = create_entry(self.window, "Nome")
self.email_var = create_entry(self.window, "Email")
self.phone_var = create_entry(self.window, "Telefone")
self.data = [Person()]
button_frame = tkinter.Frame(self.window)
button_frame.pack()
button_prev = tkinter.Button(self.window, text="<", command=self.previous)
button_new = tkinter.Button(self.window, text="+", command=self.new)
button_next = tkinter.Button(self.window, text=">", command=self.next)
button_prev.pack(side="left"); button_new.pack(side="left"); button_next.pack(side="left")
self.index = 0
def save_person_data(self):
person = self.data[self.index]
person.name = self.name_var.get()
person.email = self.email_var.get()
person.phone = self.phone_var.get()
def display_person_data(self):
person = self.data[self.index]
self.name_var.set(person.name)
self.email_var.set(person.email)
self.phone_var.set(person.phone)
def next(self):
self.save_person_data()
self.index += 1
if self.index >= len(self.data):
self.index = 0
self.display_person_data()
def previous(self):
self.save_person_data()
self.index -= 1
if self.index < 0:
self.index = len(self.data) - 1
self.display_person_data()
def new(self):
self.save_person_data()
self.data.append(Person())
self.index = len(self.data) - 1
self.display_person_data()
app = App()
tkinter.mainloop()
Ready - this is a minimal application that should be more understandable. The application class has a window, and has variables to set and read the content of text entries.
If we put two more methods and the respective buttons - to save and load the data from the disk, it could already function as a mini notebook.
And it’s easy to see that in all the methods of a class, the "self" is always the object itself, and "self.something" is the corresponding attribute - with the small class we have control over all the methods and attributes of the same and this is more noticeable.
I guess that answer doesn’t clear up much, does it? Mine may be exaggerated, but I do not know if for someone who is with the degree of confusion that the OP is about to get a very large application, this will clarify something.
– jsbueno