Text widget is not accessible to a helper function in Python3x tkinter - class

I am learning python tkiner from a reference book. The examples are coded in plain style, i.e., not in class format. I want to learn coding in classes because I think it helps manage long codes.
I am trying to make the text widget (named textPad) accessible to a helper function inside a class called TextEditor. The job of the helper function is to select all the text which I type. However, as soon as I run the script, I get global error that the textPad is not defined. Even when I add self. to textPad, i.e., self.textPad, I get an attribute error that Class object has no attribute textPad. The code is part of an excercise to make a full functional text editor. Below, I provide the core code which generates the error. What is the wrong with this code?
Could you please clarify my doubts: where is the best place to define helper functions: inside class or outside class? In both cases, how to make them accessable?
from tkinter import *
class TextEditor():
def __init__(self, root):
self.select_all() #helper function declare
myMenu = Menu(root, tearoff=0) #Menu bar
editMenu = Menu(root, tearoff)
editMenu.add_command(label="Select All", accelerator="Ctrl+A", command=select_all)
myMenu.add_cascade(label="Edit", menu=editMenu)
root.config(menu=myMenu)
textPad = Text(root, wrap="word", undo=True)
textPad.pack(expand="yes", fill="both")
def select_all(self):
textPad.tag_add('sel', '1.0', 'end')
if __name__ == '__main__':
root=Tk()
app = TextEditor(root)
root.mainloop()
This is the error:
Traceback (most recent call last):
File "C:\Python33\gui\tkguibook\textpad.py", line 21, in <module>
app = TextEditor(root)
File "C:\Python33\gui\tkguibook\textpad.py", line 6, in __init__
self.select_all() #helper function declare
File "C:\Python33\gui\tkguibook\textpad.py", line 17, in select_all
textPad.tag_add('sel', '1.0', 'end')
NameError: global name 'textPad' is not defined
Thank you in advance for your kind help!

First of all, I advise you to watch some tutorials on object-oriented paradigm in Python without using tkinter directly.
The problem with your code is that textPad is not a property of the class, but it's a simple local variable to the __init__ method or constructor. To make it a property, you should use self to declare and then refer to the just declared property.
For example, suppose I have the following class:
class TextEditor:
def __init__(self):
# stuff
and you want to add a property, visible in all the points in your class, you can do it in this way:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text() # using 'self' to declare a property
now, if you want to refer to that property in another method, you should use always the self:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text()
def set_text(self, new_text):
self.textPad.insert(tkinter.END, "hello") # using 'self' to refer to the property
To know more about self.

Related

Python C API - How to inherit from your own python class?

The newtypes tutorial shows you how to inherit from a base python class. Can you inherit from your own python class? Something like this?
PyObject *mod = PyImport_AddModule("foomod");
PyObject *o = PyObject_GetAttrString(mod, "BaseClass");
PyTypeObject *t = o->ob_type;
FooType.tp_base = t;
if (PyType_Ready(&FooType ) < 0) return NULL;
though you need to define your struct with the base class as the first member per the documentation so it sounds like this is not possible? ie how would I setup the Foo struct?
typedef struct {
PyListObject list;
int state;
} SubListObject;
What I'm really trying to do is subclass _UnixSelectorEventLoop and it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
I think you're basically right on your assessment:
it seems like my only solution is to define a python class that derives from my C class and from _UnixSelectorEventLoop with my C class listed first so that it can override methods in the other base class.
You can't define a class that inherits from a Python class because it'd need to start with a C struct of basically arbitrary size.
There's a couple of other options that you might like to consider:
You could create a class the manual way by calling PyType_Type. See this useful answer on a question about multiple inheritance which is another sort of inheritance that the C API struggles with. This probably limits you too much, since you can't have C attributes, but you can have C functions.
You could do "inheritance by composition" - i.e. have you _UnixSelectorEventLoop as part of the object, then forward __getattr__ and __setattr__ to it in the event of unknown attributes. It's probably easier to see what I mean with Python code (which is simply but tediously transformed into C API code)
class YourClass:
def __init__(self,...):
self.state = 0
self._usel = _UnixSelectorEventLoop()
def __getattr__(self, name):
return getattr(self._usel, 'name')
def __setattr__(self, name, value):
if name in self.__dict__:
object.__setattr__(self, name, value)
else:
setattr(self._usel, name, value)
# maybe __hasattr__ and __delattr__ too?
I'm hoping to avoid having to write this C API code myself, but the slots are tp_getattro and tp_setattro. Note that __getattr__ will need to be more comprehensive in the C version, since it acts closer to the __getattribute__ in Python. The flipside is that isinstance and issubclass will fail, which may or may not be an issue for you.

How can I extend a class in Python curses module

In Python curses, a new window object can be created with the curses.newwin() function. How can I extend the class of the objects that are instantiated from the newwin function?
I have tried dir(curses) but couldn't find any obvious class names there for me to extend.
curses.newwin returns a extension type.
Unfortunately, you can't set attributes of extension types.
As a workaround, you can redefine curses.newwin to return a new class instance that wraps the return value of the original curses.newwin(..):
orig_newwin = curses.newwin
def newwin(*args):
win = orig_newwin(*args)
return Wrapper(win)
curses.newwin = newwin

Python 2.7: Issues When Importing a Class

I have been searching high and low for an answer and cannot seem to find one. I am running into a fundamental issue when attempting to import a class from another file. I am relatively new to Python and OOP in general, so forgive me if my query is rudimentary.
The Issue: I want to import a CHILD class into a PARENT class. Simple enough, but when I import the class it immediately executes.
The Question: How do I import a class so it can be referenced globally in my parent class?
Here is a basic example of the PARENT class:
from child import CHILD
class PARENT:
def _init_(self):
print "START PARENT CLASS"
def goTo(self,enter):
if enter == "1":
c.childScreen()
else:
self.parentScreen(self):
def parentScreen(self):
enter = raw_input("ENTER [1] to go to CHILD class:")
self.goTo(enter)
p = PARENT()
c = CHILD()
Okay, so to my beginner eyes this conceptually should work. I imported the class CHILD and created a reference to it "c = CHILD". This concept works when both class's are in the same file but not when they are in two different files. Why?
Instead of importing CHILD from child and storing it as a reference it instead executes immediately and does not initiate the PARENT class. Why doesn't this work?
I have seen people reference the whole 'name' == 'main' but I don't really know how to implement that and I feel as if there is an easier way.
Any help would be appreciated. Thank you!
You are importing the CHILD class properly, but you are calling it from outside your PARENT class. The PARENT class thinks that the variable c is a local variable to the function goTo. You could use a global variable c, but anyone would tell you that that is a big no no.
To answer your other question you probably have some code that executes in CHILD. If you only want this code to run when you run the file in which the CHILD class then put it after a
if __name__ == '__main__':
This only allows the code preceding it to run if executed directly and it will not run if you import the class. see examples below.
You can just create an instance variable of the CHILD class in your __init__ and use it in the rest of your PARENT class.
class PARENT(object):
def _init_(self):
print "START PARENT CLASS"
self.c = CHILD() # create instance of CHILD
def goTo(self,enter):
if enter == "1":
self.c.childScreen() # then you can access CHILD class like this
else:
self.parentScreen(self):
def parentScreen(self):
enter = raw_input("ENTER [1] to go to CHILD class:")
self.goTo(enter)
if __name__ == '__main__':
p = PARENT()
or you can actaully inherit CHILD into PARENT:
class PARENT(CHILD):
def _init_(self):
print "START PARENT CLASS"
def goTo(self,enter):
if enter == "1":
# now you can access the CHILD functions as if the we were coded in the
# PARENT class
self.childScreen()
else:
self.parentScreen(self):
def parentScreen(self):
enter = raw_input("ENTER [1] to go to CHILD class:")
self.goTo(enter)
if __name__ == '__main__':
p = PARENT()

How can i reach a class variable from another class in Lua?

I am using director class for scene transitions and i need to use the variable in a class in another class. So how can i call it?
local a= require "welcome"
variableName is text display object in welcome class
print(a.variableName.text)
However i get nil.
Could you help me out? Thanks
Make the variable a property of the returned table:
local Class = {}
function Class.new()
local class = {}
class.variableName = display.newText("Hello mom!", 100, 100, "Helvetica", 18)
return class
end
return Class
Then you can reference it:
local a = require ("class").new()
print(a.variableName.text)
OR
If you want to pass variables between the screens in Rauber's Director Class, you can:
local parameters = {p1="some text", p2="some more text"}
director:changeScene(parameters, "sceneName")
In your screen, make the new function accept the parameters:
function new(parameters)
print(parameters.p1, parameters.p2) --> some text some more text
end
OR
Put _G in front of your variable
_G.myGlobalVar = "some awesome stuff"
Then you can reference it in another class
print(_G.myGlobalVar) --> some awesome stuff

Fields in CoffeeScript?

class #A
A_Function_Alias: => #my_function
my_function: =>
usage_of_alias: =>
#A_Function_Alias.call()
What i want, is usage_of_alias to be
usage_of_alias: =>
#A_Function_Alias
And have it behave the same. i.e. I want a more functional style syntax here. I've tried multiple combinations with no success. The fact that i have to evaluate my function to get the goodies inside bothers me.
One application would be instead of this:
event: => new Event(#my_function)
which is accessed as event.call().hi()
i could have some other declaration that would allow me to access event as event.hi()
Something that behaves more like a field instead of a property.
I'm thinking you want this:
class #A
my_function: => alert 'my function!'
A_Function_Alias: #::my_function
usage_of_alias: =>
#A_Function_Alias()
# some other code...
See what this compiles to here.
When evaluating a class # is the class constructor object, the class object itself. And the :: operator lets you drill into the prototype. So #::foo in a class body compiles to MyClass.prototype.foo.
So what this is doing is first making a normal instance method named my_function, defined on A.prototype.my_function. Then we make a new instance method named A_Function_Alias and directly assign the function from class objects prototype that we just created. Now my_function and A_Function_Alias both point to the exact same function object.
But as a more sane alternative, might I suggest a pattern that defines a private inner function that the class can use, and then assigning it more directly, without crazy the prototype accessing?
class #A
# Only code inside this class has access to this local function
innerFunc = -> alert 'my function!'
# Assign the inner funciton to any instance methods we want.
my_function: innerFunc
A_Function_Alias: innerFunc
usage_of_alias: =>
#A_Function_Alias()
# or
#my_function()
# or
innerFunc()
# they all do the same thing