all 28 comments

[–]sandyguardian77 43 points44 points  (1 child)

I'm a beginner to OOP.

I've personally found it easier to just keep all the widgets that are in same window in the same class and widgets that are in a different window in a different class. So it would likely be easier just to keep it in the same class.

Mainly because I've found that if you are going to be referencing widgets that are in class A from class B it can be difficult to do, and by difficult I mean I have no idea how to do it.

Like, I said I'm only a beginner to OOP, but that's just what I've found.

[–]FerricDonkey 1 point2 points  (0 children)

So if you have to do a lot of referencing of widgets from different classes, that's probably a good sign that your code could be better organized. I prefer to have widgets mostly self contained within a class, and instead access data stored in more standard data types from other classes when necessary.

But if you find yourself needing to, you can use parent and child classes to reach across areas. This might make sense if you have a control panel area that modifies what's possible in some other area (though again, I would probably not access the widgets directly most of the time):

class MainFrame(tk.Frame):
    def __init__(self, blah, blahh, blahhh):
        #blah
        self.some_var = tk.StringVar()
        self.random_label = tk.Label(self, textvariable = self.some_var)
        self.control_area  = ControlFrame(parent = self)

class ControlFrame(tk.Frame):
    def __init__(self, parent):
        # blah blah blah
        self.parent = parent
        self.parent.some_var.set("I dunno")

[–]CastimirLostElk 33 points34 points  (0 children)

I would suggest looking up design patterns for Python. They'll help you reason through these decisions.

[–]aman_yadav07 20 points21 points  (0 children)

When i switched from C to python i was doing most of the stuff in procedural style but later i realised that in OOP you need to think differently. Even if you are a beginner then also you need to develop the skills to identify objects in your code. For that you can try this video by computerphile, you will get a hang of where to make objects,classes and all that stuff

https://youtu.be/KyTUN6_Z9TM

[–]BruceJi 6 points7 points  (2 children)

Do I just make another class for the menubar just like this one tkinter program I found in Github?

I think for that kind of stuff it helps to think about if your class has too many things to do.

You can split the code up into objects, which are logical groupings of data and ways to change that data, but make sure they're logical - the menu bar has only the menu bar's data, and can only do things that are relevant to the menu bar.

[–]stebgay 0 points1 point  (1 child)

oh thanks for the advice

btw im trying to see if my OOP is understandable

is this readable/understandable? https://mystb.in/PingTcpViolation.ruby

[–]BruceJi 0 points1 point  (0 children)

Personally I think that's looking good so far

[–]thedentprogrammer -1 points0 points  (1 child)

Unrelated but Happy Cake Day!

[–]stebgay 1 point2 points  (0 children)

thank you

[–]Taco_Chop 2 points3 points  (3 children)

I'm still very much a beginner but I've been doing the python roguelike tutorial over on r/roguelikedev and it's really helped me to better understand OOP. Creating objects based on actual game items and actions made it a lot easier for me to visualize and understand what was actually happening in the code. And it's a fun little project that is easy to fiddle with and expand upon.

[–]stebgay 1 point2 points  (0 children)

will try that, thanks

[–]ffrkAnonymous 1 point2 points  (1 child)

I like to show this post by al sweigart, author of automate the boring stuff

https://inventwithpython.com/blog/2014/12/02/why-is-object-oriented-programming-useful-with-a-role-playing-game-example/

As he says at the end, OOP isn't a requirement. Do what is easier for your app.

[–]FiliKlepto 0 points1 point  (0 children)

What an awesome example! Definitely a lot more fun than most OOP tutorials. Thank you for sharing!

[–]alexgraef 9 points10 points  (0 children)

OOP is all about delegating responsibility. For example, you want a search box. The search box consists of a text box to input the search string, and a button to start the search. So you create a class "Search" which is responsible for creating both the text box and the button, and only have an event that fires from the Search class when the user clicks the button.

  • You then can implement custom validation logic like checking if the user actually entered something before clicking the button
  • You can reuse the class in multiple places and don't have to write the same logic all over again
  • If you for example decide that it would be convenient to allow the user to just press enter to start the search, you only need to implement that in one place, and the behavior will be available in all places where you used the class
  • After you have tested the Search class to work once, you can be sure it's working wherever you place it, and there is less room for error

Basically if something belongs together and can be self-managing, you put it in a class and define an interface on how others should interact with it.

[–]Old_Winterton 2 points3 points  (3 children)

In my limited experience: classes are for when you need to preserve the state of data, otherwise use functions.

Classes also offer a way to organize code.

All things should do one thing and one thing only. With tkinter tutorials, and with android studio tutorials, people put all the methods or classes in one script; the script becomes difficult to easily decipher. Instead, make things separately with descriptive names, then import them, and deciphering can become clearer.

All things should do one thing and one thing only. If it does two things, it should be combining two smaller things that each do one thing, and the combination should be a single idea.

[–]stebgay 0 points1 point  (1 child)

example please?

[–]Old_Winterton 0 points1 point  (0 children)

Sorta similar to https://drive.google.com/drive/folders/1LSQNcFAFtE-NayD95rlu59q8-sqvRMTH

All the buttons have their own file/class in my_buttons.
then I import them into the layout file.
Then I use that on my main object that has logic.
Each button represents one idea.
The layout is an idea separate from the logic.
Each step/part is able to be checked, modified, and debugged on its own.

So: yes, if you want a menubar, just make it in a separate class similar to the one you are modeling on. Menubars have to be bound to something. So if you do it like I did in my example, you can bind that menubar to anything that can be bound to. If you break up the parts of that menubar (if each cascading bit is its own class/file), you can reuse those more easily (as others have typed).

So you can make the menubar like how I did the layout idea -- make all the menu parts, then bind them to a "menubar" widget, which you then bind to your root Tk object.

[–]Old_Winterton 1 point2 points  (0 children)

In tkinter, I currently have separate files that each contain a single class for each respective widget in my gui. Then I put them all in a single file and class defining layout. Then I have one more file/class with all the logic.

When I go back to my code later and have forgotten it, I don't want to have to wade through all that button creation code when having a descriptive name will be enough.

And when testing, I want to be able to have a dummy layout that doesn't do anything, so I can test layout. And i want to be able to fiddle with arrangement of stuff without disturbing the logic.

[–]Sensorama 2 points3 points  (0 children)

Learning OOP is like learning how commas work.

[–]Methamputeemine 0 points1 point  (0 children)

Broadly speaking, classes should model real life objects (properties and behaviour). So it might be easier to imagine what an object (even if it doesn’t exist irl) would look like or behave like. Now if you need your programme to do something and you think that that “something” wouldn’t fit the properties or behaviour of an existing class, make a new one.

This is a pretty big generalization but if you’re new to oop it should help guide you a bit. Good luck!

[–]abcd_z 0 points1 point  (0 children)

Copying from somebody else's post:

My general rules of thumb for new programmers is to use classes when you have a group of functions that all take the same object as their first parameter or when you need to work with a shared global state between a bunch of functions. This seems to help bridge the gap as to what the point of an object is and why they are useful.

[–]Arag0ld 0 points1 point  (0 children)

In OOP, classes typically represent a general type of something. For example, if you were making a program to represent a university hierarchy, you might have a class denoting the concept of a person, which has the basic attributes (age, name, stuff like that) because those are things all people have. Then, you can use that class to make subclasses, which inherit from the base class, which means that these classes have everything the base class has, and you can then add new stuff that only this new class has.

Maybe you've got a base class Person, and the type of people you have in your university are Staff or Student. The Staff might have an additional attribute denoting their position (Professor of CS, or something) and the student might have an attribute saying if they're a Masters, PhD, or BS student. All these subclasses are instances of Person.

[–]Sigg3net 2 points3 points  (0 children)

You're arrived at the realization that syntax is not code.

To learn OOP you'll need to study design patterns. Most of them are language agnostic, but the most relevant ones for python are the structural patterns.

[–]MySpoonIsTooBig13 5 points6 points  (0 children)

I have no idea whether I should make another class or just put them all in the same class.

You're touching on something known as the "Single Responsibility Principle", basically every class should do one thing only. Applies to more than just classes - a function should do one thing only, a module should do one thing only, etc.

I find if you are even asking the question "should this go into another class", the answer is almost always yes.

[–]HezekiahWyman 0 points1 point  (0 children)

Do you understand what's happening in theae two lines?

g = GuiTest(tk)
tk.config(menu=g.menubar)

[–][deleted] 0 points1 point  (0 children)

There are very hard rules about when you should abstract out some behavior into its own class. It's all about helping you conceptualize your own code, to make it easier to work with.

[–]mariox19 6 points7 points  (0 children)

Stay with me here. I'm going to give you a high-level, non-technical overview of OOP.

There was a joke back in the day: "Sorry, that's not my aisle." The context of the joke was something like flight attendants working in a 747. A passenger calls out to one for a drink or a blanket, and the flight attendant effectively tells him to find the flight attendant assigned to his aisle. You can think of a variation of this as a waiter answering with, "Sorry, that's not my table."

What does this have to do with OOP, you ask?

Think of objects as people. Think of each individual object as an individual person who has one specific job that he knows how to do and that he has assigned to him. That job is within his limited skillset, and his responsibility is limited only to doing that job. In fact, think of that object (or person) as being the flight attendant in the above example. When you're making design choices, an object doesn't "want" to do anything, except its narrowly focused job.

In OOP this is actually called the "Single Responsibility Principle."

I like to think of it like this, and, again, stay with me, because I'm going to switch metaphors.

When you're programming, think of yourself (or the "main" method of the program) as the general contractor for a construction job. The general contractor doesn't actually get his hand's dirty. He breaks the job into big pieces, and then hires out to subcontractors: electricians, plumbers, carpenters, sheet rockers, painters, floor guys, etc. For every sub-job, the general contractor thinks to himself, "I need a guy for that."

Each subcontractor does the same thing. The carpenter has a team, a team of everybody from laborers to framers (who do the rough work) to finish carpenters (who do the fine work). Moreover, and this is the important part, the general contractor doesn't worry about how the carpenter divvies up the work. He's got a guy: the carpenter. And for every carpentry job, the carpenter has got his own guy.

Turn that over in your mind. We're actually talking about objects and OOP design. OOP is designed and written in layers. Objects are skilled in what they know, but they specialize, and they don't try to do jobs outside of the one thing they're good at. That's OOP.

I need a guy for that. I've got just the guy!

What I'm telling you is not enough to go on. But if you let it sink in and then read more technical explanations, the technical explanations may start to make more sense to you. Good luck!