I'm writing a calculator using wxPython for the GUI. I've made a class called display to use StaticText to display the text. Anyways, when I try to update the screen, it raises an exception.
Here's the code:
class display:
def __init__(self,parent, id):
print "display class is working"
global string1
self.view = wx.StaticText(frame, -1, "Waiting", (30,7), style = wx.ALIGN_CENTRE)
#staticmethod
def update(self):
global string1
self.view.SetLabel(string1)
Whenever I try to run the Update() function, it raises this exception:
AttributeError: 'function' object has no attribute 'view'
When I wrote "self.view = wx. etc etc", I tried to set the StaticText to a variable name, so I could use the SetLabel function. The text seems to work until I try to update it. Why can't I update it? How do I fix it?
#staticmethods take no arguments ... so its not actually getting self ... you need to either make it a #classmethod which gets cls or you need to just make it a normal method
class display:
view = None
def __init__(self,parent, id):
print "display class is working"
global string1
display.view = wx.StaticText(frame, -1, "Waiting", (30,7), style = wx.ALIGN_CENTRE)
#classmethod
def update(cls):
global string1
cls.view.SetLabel(string1)
Related
It worked fine all day suddenly it stopped. I don't believe I changed the code at all maybe my brain stopped working???
class BorderWidgetWithLabel(BorderWidget):
def __init__(self, **kwargs):
super(BorderWidgetWithLabel, self).__init__(**kwargs)
self.text=" "
self.text=kwargs.get('text',' ')
print self.text
self.txt_bg_color=kwargs.get("txt_bg_color", [0,0,0,0])
self.bg_color=kwargs.get("bg_color", [0,0,0,0])
self.bind(pos=self.update_canvas)
self.bind(size=self.update_canvas)
self.update_canvas()
def update_canvas(self, *args):
#need to reset everything
self.canvas.clear()
with self.canvas:
get_color(self.border_color)
if(self.text!=""):
texture=simple_text_texture(self.text)
The problem:
/typeclasses/borderwidget.py", line 75, in update_canvas
if(self.text!=""):
AttributeError: 'BorderWidgetWithLabel' object has no attribute 'text'
I started getting that error I added self.text=" " in the __init__ as well as the if statement in the update_canvas. What am I doing wrong??
If I get rid of all the uses of self.text then the print self.text works no problem.
UPDATE:: Fixed by adding text=' ' as a class variable. Is this necessary?? or is there something wrong with the code. As print self.text in the init works fine without the class variable I am unable to provide a less complete sample
UPDATE:: I removed the self.update_canvas() last line of the init and it worked without the class variable but I attempted to reproduce that with the following
class SomeClass:
def __init__(self, **kwargs):
self.text=kwargs.get("text","hello")
self.update_class()
def update_class(self, *args):
if(self.text!=' '):
print self.text
SomeClass()
I don't know why I was unable to reproduce it then
So, it looks like you have
class BW:
def __init__(self):
self.update_canvas()
def update_canvas(self):
pass
class BWL(BW):
def __init__(self):
super(BWL, self).__init__()
self.text = 'text'
self.update_canvas()
def update_canvas(self):
print self.text
Running BWL() would throw the exception you listed. This is because the order of events is
call BWL.init
which calls BW.init (with self = BWL)
which calls self.update_canvas (which is BWL.update_canvas)
which accesses self.text
Then, when BW.init returns, it creates self.text
and finally calls self.update_canvas again.
This is probably not what you want even without the bug... probably remove the call to super or the call to update_canvas in the child, and set up the properties you need in the update_canvas method BEFORE calling the super class.
I'm a beginner in learning python..
I'm looking for help in solving an OOP problem
My main program has something simplified like below:
class abc(Frame):
def _init_(self, master)
Frame.__init__(self)
self.B1 = Mybutton(self.master, self.cmd)
def cmd(self):
print("hello world")
In the main program, I import Mybutton class in another file, which is simplified as below:
class Mybutton():
def _init_(self, parent, command):
self.command = command
def A_ramdom_fcn(self):
...
self.command() ------------------>> here I want to execute the command
in class abc, not in class Mybutton.
How to execute a method from another class that is passed as an instance method, you may ask why not just execute it in class abc, but I have event attached to button press, it needs to do a roundabout to achieve this..
First, fix the typos: missing : in abc's init method, and it should be __init__ (with two underscores) for both classes.
It seems like you've gotten yourself turned around. You've set things up correctly using composition: an abc has a Mybutton, and it looks like you correctly pass the function to Mybutton so that it can execute it. In fact, your code will work as written if you do, for example
a = abc(master) # no context for what master is, but I assume you have it
a.B1.A_ramdom_fcn()
With the way you've set things up, you don't want to import and make instances of Mybutton in your main program (what abc would they belong to?). You want to import and make instances of abc. You then access their internal Mybutton like I've shown in the example above. This works because when you pass self.cmd to the Mybutton constructor while inside the abc constructor, it's already a bound method of the abc you're constructing.
As an addendum, it looks like you might be having an XY problem with regards to why you need such a roundabout method. Is there any reason why you can't simply pass abc.cmd to the button press handler?
Theoretically, what you are trying is possible, you can capture the object method into variable and call it later (python 3):
class Window:
def __init__(self):
self.my_button = Mybutton(self.cmd)
def cmd(self):
print("hello world")
class Mybutton:
def __init__(self, command):
self.command = command
def a_ramdom_fcn(self):
self.command.__call__()
win = Window()
win.my_button.a_ramdom_fcn()
I assume you are trying to make the generic Button class which doesn't know what to do when it's clicked and you want to put the actual logic into your Window class.
That makes sense, but it would be even better to extract the logic into the third, Command class. This allows us to limit the Window responsibility and also avoid the trick with method-as-variable (the command we pass to the button object is just another object):
class HelloWorldCommand:
def execute(self):
print("Hello world")
class Window:
def __init__(self):
self.my_button = Mybutton(
HelloWorldCommand()
)
class Mybutton:
def __init__(self, command):
self.command = command
def a_ramdom_fcn(self):
self.command.execute()
win = Window()
win.my_button.a_ramdom_fcn()
So I'm working on a kivy project and also learning the language for it (I mean python) and I have this little program here. So there are some language button on my first screen but I also have text to change in the second page. How can I call an other class' function in a class, or should I use a different way to change the textes? Any tipp would be helpful :) thanks
class ScreenOne(Screen):
def d_language(self):
self.hellolabel.text='Hallo'
def fr_language(self):
self.hellolabel.text='Bonjour'
class ScreenTwo(Screen):
def d_languagetwo(self):
self.otherlabel.text='Zweite seite'
def fr_languagetwo(self):
self.otherlabel.text='Deuxième page'
You can use the screen manager to get to the other screen
def d_language(self):
self.hellolabel.text = 'Hallo'
#now change the other label
s2 = self.manager.get_screen('name of the other screen')
#or ...
#s2 = self.manager.screens[1] # will also work...
s2.otherlabel.text = 'Zweite seite'
#or ...
#s2.d_languagetwo()
...
I have a class named TerminalPanel which has the following method:
def OnSerialRead(self, event):
"""Handle input from the serial port."""
text = event.data
Now, I want to get the value of text from another method (get_data) in another class (GraphicsPanel).
How do I get this value? I tried marito = TerminalPanel.OnserialRead.text, but I get AttributeError: 'function' object has no attribute 'text'
Update
I have set-up the TerminalPanel class to include the variable text as part of it:
def OnSerialRead(self, event):
"""Handle input from the serial port."""
self.text = event.data
But now when I call it like this: marito = TerminalPanel.text inside my GraphicsPanel class I get the following error:
AttributeError: type object 'TerminalPanel' has no attribute 'text'
What am I doing wrong?
I think the problem is a lack of context and confusion what actually to do. I suppose you try to rework the wxTerminal.py from pyserial. I have to admit this part of pyserial is neither very readable (has been created by wxGlade) nor is it easy to understand (requires understanding of the wxPython event system and spinning off of threads (to keep the GUI responsive when reading on the serial port).
However, according to your problem description, it seems to me you want to do the following:
Get the value of event.text when it arrives and process it further in your GraphicsPanel instance.
You have to possibilities:
1) Bind to the event:
In your GraphicsPanel class:
class GraphicsPanel(wx.Panel):
def __init__(...):
...
self.parent = self.GetParent() # this should result in a wx.Frame instance!
# binding on wx.Frame required, because wx.Panel will not catch the event
self.parent.Bind(EVT_SERIALRX, self.OnSerialRead)
def OnSerialRead(self, event):
text = event.text
...
event.Skip() # important: you have to skip it also in ``TerminalPanel`` if you
# want to bind twice
2) Call the routine in GraphicsPanel instance with event.text as argument.
class TerminalPanel(wx.Panel):
def __init__(...):
...
self._grphpnl = GraphicsPanel(...)
self.Bind(EVT_SERIALRX, self.OnSerialRead)
def OnSerialRead(self, event):
text = event.text
# do something with it in GraphicsPanel instance
self._grphpnl.OnSerialText(text)
...
Somewhere else in your code:
class GraphicsPanel(wx.Panel):
...
def OnSerialText(text):
# do something with the text
That variable is defined at function scope. There is no way to get that value.
To make the value available to anything outside of the method you need to store the value on the class self.text = event.data or return the value return text
You need to decide what is right for the situation though, I'm guessing by the name of the function that returning the data is the right thing to do.
You need to return the value!
def OnSerialRead(self, event):
"""Handle input from the serial port."""
text = event.data
return text
Then you can access the value like this
marito = TerminalPanel.OnserialRead(event)
Or save the value in the class:
class Reader():
def OnSerialRead(...):
...
self.text = event.data
and then access the value from the class like so:
marito = Reader.text
i'm following a few different guides to re-learn Tkinter by writing a little application that grabs stock prices. My issue that I am up a wall against is calling the .get() method from my entry widget variable. I've seen a couple other suggestions to put all the widget creating inside a function and then call the function in the init method, however I'm getting the same error, even when using the self argument in front of my entry variables. I know it's an issue with the way i'm passing data from function to function, but I can't wrap my head around it. Here's the code, sorry for the wall of text:
class MyApp:
def __init__(self, parent):
self.myParent = parent
self.myContainer1 = Frame(parent)
self.myContainer1.pack()
self.createWidgets()
button1 = Button(self.myContainer1, command = self.button1Click)
button1.configure(text = "get quote")
button1.pack()
def createWidgets(self):
root.title("Stock App")
self.symbol = Entry(self.myContainer1)
self.symbol.pack()
self.symbol.focus_set()
def button1Click(self):
stock = symbol.get()
print stock
I've taken it down to simplest form even and just had the button1Click call a callback function-
def button1Click(self):
print callback()
def callback():
print symbol.get()
This returns the exact same error:
NameError: global name 'symbol' is not defined
Is it getting destroyed too early? how do I fix this?
I've referenced multiple documents for tkinter and have seen some great fixes but none are extensible, or um unable to see how they relate to me using it inside of an object.
Thanks in advance for the help.
As far as I can tell inside of your button1Click method you need to add self as in:
def callback():
print self.symbol.get()
You're missing self. to make the callback:
def callback():
print self.symbol.get()
instead.