How to use pyglet within a class - python

In all the tutorials on the web I've seen with Pyglet, it doesnt seems that any of them have used classes to contain the pyglet.window.Window instance. For example, most tutorials seem to go something like
import pyglet
game_window = pyglet.window.Window()
#game_window.event
def on_draw():
#dostuff
while __name__ == "__main__":
pyglet.app.run()
I'm having trouble restructuring this code into a class. My code which is intended to do so, is here:
import pyglet
from pyglet.gl import *
from Board import Board
class Frontend:
def __init__(self,xs, ys):
self.GameInstance = Board(xs,ys)
self.GameWindow = pyglet.window.Window(width=512, height=512,visible=False)
#GameWindow.event
def on_draw(self):
self.GameWindow.clear()
f = Frontend()
When I run this code, I get the following error:
Traceback (most recent call last):
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 7, in <module>
class Frontend:
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 13, in Frontend
#GameWindow.event
NameError: name 'GameWindow' is not defined
When I replace #GameWindow.event with #self.GameWindow.event in an attempt to resolve the NameError I get:
Traceback (most recent call last):
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 7, in <module>
class Frontend:
File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 13, in Frontend
#self.GameWindow.event
NameError: name 'self' is not defined
Which i expect. However, I'm not sure why this code isnt working - can someone explain why and how to fix it?

You can inherit from Window.
This should work:
class Frontend(pyglet.window.Window):
def __init__(self, xs, ys):
self.GameInstance = Board(xs,ys)
super().__init__(width=512, height=512,visible=False)
def on_draw(self):
self.clear()
Your code is not working because you can not reference the instance of the Frontend class outside the methods. If you will have only one instance of the Frontend class you can do something like:
class Frontend:
window = pyglet.window.Window()
def __init__(self):
...
#window.event
def on_draw():
...

As I've commented on ragezor's answer, the pyglet docs recommend inheritance.
But another option may be to separate the event handling logic in its own class, as an EventDispatcher:
http://pyglet.org/doc-current/programming_guide/events.html#creating-your-own-event-dispatcher
Personally, if I knew would only have one Frontend instance, I would question the necessity of having a class. But that's a whole can of worms. Thought I'd give you another nice option, at least, you can't go wrong inheriting from Window though, especially if all your events are Window-related.
A third idea (fourth I guess since ragezor gave you two options):
class Frontend:
def __init__(self,xs, ys):
self.GameInstance = Board(xs,ys)
self.GameWindow = pyglet.window.Window(width=512, height=512,visible=False)
self.on_draw = self.GameWindow.event(self.on_draw)
def on_draw(self):
self.GameWindow.clear()
In other words, apply the #GameWindow.event decorator manually.
One last thing, don't use camelcase for attributes, it goes against PEP8 convention and confused me for a second while editing this code. Call it game_window instead.

My guess is that you need to do
#self.Gamewindow.event

Related

Python set self-variables by other class using cls?

I wonder if it is possible to set variables of a class by a different class using cls?
The story behind it:
I'm writing tests for different purposes but see that one part of the setup is the same as in an already existing class. So I would do the setUp by the already existing one:
The original code:
class TestBase(unittest.TestCase):
def setUp(self):
self.handler = txt.getHandler(hcu.handler3())
self.curves = self.handler.curves()
self.arguments = (getInit())
self.ac = self.connect2DB(self.arguments)
self.au = AutoUtils()
This has worked well so far.
Now in my TestClient I'd like to make use of that:
from .testsDB import TestBase as tb
class TestClient(unittest.TestCase):
def setUp(self):
tb.setUp()
And modified in the TestBase the setUp to the following:
#classmethod
def setUp(cls):
cls.handler = txt.getHandler(hcu.handler3())
cls.graph = cls.handler.curves()
cls.argv = (getInit())
cls.ac = cls.connect2DB(cls.arguments)
cls.au = AutoUtils()
But I'm getting an error as soon as I use one of the values defined in the variables of the TestClient-class:
def test_Duplicates(self):
self.testDB = self.ac.connect(self.ac.client, self.arguments[4])
With the error:
In test_Duplicate (Curves.tests_client.TestClient) :
Traceback (most recent call last):
File "/home/qohelet/Curves/tests_client.py", line 49, in test_Duplicate
self.testDB = self.ac.connect(self.ac.client, self.arguments[4])
AttributeError: 'TestClient' object has no attribute 'ac'
Is it actually possible what I'm trying?
EDIT:
After writing this and seeing the answers I did another review. Yes indeed there is a circular issue I'm having.
TestBase has the function connect2DB which will be executed on setUp.
If it refers to itself (as in the original) it's fine.
If I replace the self with cls it will try to execute TestClient.connect2DB in the setUp - which does not exist. So it would require self again as putting connect2DB into TestClient is not an option.
How to solve that?
Surely your new class should just inherit the setup()?
from .testsDB import TestBase as tb
class TestClient(tb):
def test_Duplicates(self):
self.testDB = self.ac.connect(self.ac.client, self.arguments[4])
The whole point of inheritance is that you don't modify what you inherit from. Your new class should just make use of what is supplied. That is why inheritance is sometimes called programming by difference.

Why it says that super() takes atleast 1 argument

class Member():
def __init__(self, MemberName, MemberID, SubcribtionPaid):
self.__MemberName = MemberName
self.__MemberID = MemberID
self.__SubcribtionPaid = False
def SetMemberName(self):
print(MemberName,self.__MemberName)
def SetMemberID (self):
print(MemberID,self.__MemberID)
def SetSubcriptionPaid(self):
print(SubcribtionPaid,self.__SubcribtionPaid)
class Jmember(Member):
def__init__(self,MemberName,MemberID,SubcribtionPaid,DateofJoining):
super().__init__(MemberName,MemberID,SubcribtionPaid)
self.__DateofJoining = DateofJoining
def SetDateofBirth(self):
print(DateofBirth,self.__DateofJoining)
NewMember = Jmember("Armeen","1245","True","12/3/2015")
NewMember.SetMemberName()
NewMember.SetMemberID()
NewMember.SetSubcriptionPaid()
NewMember.SetDateofJoining()
I basically copy pasted the code.I used pycharm. I still dont get how to use code block. I dont know what to do.
Sorry if i caused a problem.
I wrote a code in python,where one class inheritates the attributes of another class. When i run the code , error occurs on line 26 saying that super() takes atleast 1 argument .Even though i wrote the arguments. Did I make a mistake there. The code, the traceback
I want to see the output of the new member that includes member name, id , subcribtion paid and date of joining. But error is shown.
Updated my post to reflect your posted code:
You said that you are using PyCharm. pay attention to the red squiggly lines under sections as they are pointing out errors.
First error: you did not have a space between def and init
def__init__(self, MemberName, MemberID, SubcribtionPaid):
Second Error: found in your class function calls:
You do not have to call the class that is essentially what (self) is doing
def SetMemberName(self):
print(MemberName,self.__MemberName)
Third error: was found in your Traceback
You were trying to call a function that you forgot to create
Traceback (most recent call last):
File "/Users/sumbody/Projects/Python/MemberTest2/main.py", line 29, in <module>
NewMember.SetDateofJoining()
AttributeError: 'Jmember' object has no attribute 'SetDateofJoining'
Here is the working code:
class Member():
def __init__(self, MemberName, MemberID, SubcribtionPaid):
self.__MemberName = MemberName
self.__MemberID = MemberID
self.__SubcribtionPaid = False
def SetMemberName(self):
print(self.__MemberName)
def SetMemberID (self):
print(self.__MemberID)
def SetSubcriptionPaid(self):
print(self.__SubcribtionPaid)
class Jmember(Member):
def __init__(self,MemberName,MemberID,SubcribtionPaid,DateofJoining):
super().__init__(MemberName,MemberID,SubcribtionPaid)
self.__DateofJoining = DateofJoining
def SetDateofBirth(self):
print(self.__DateofJoining)
def SetDateofJoining(self):
print(self.__DateofJoining)
NewMember = Jmember("Armeen","1245","True","12/3/2015")
NewMember.SetMemberName()
NewMember.SetMemberID()
NewMember.SetSubcriptionPaid()
NewMember.SetDateofJoining()
Some advice, when learning to code and debug your own code, it is not a bad thing to take some code that runs and then break it. It sounds weird, but in doing so you will learn to recognize errors when seen in the editor and at runtime. Happy coding!

defining a function inside a function in python3

I am trying to define a function inside a function in python3 as
from gi.repository import Gtk, GObject
class EntryWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Generate Init")
self.set_size_request(100, 50)
self.nument = Gtk.Entry()
<did some work>
def get_nument(self,nument):
numele= self.nument.get_text()
print(numele)
<did some more work and define a function again>
def get_specs(self,spec):
numspec=self.spec.get_text()
resulting to an error:
Traceback (most recent call last):
File "hw3.py", line 42, in get_nument
self.spec.connect("activate",self.get_specs)
AttributeError: 'EntryWindow' object has no attribute 'get_specs'
I am really new to python, so trying hard for understanding the scope of self and origin of this error. Also, possibly I am doing things really funny by declaring a function inside a function, according to this post.
What I need is to define a function(get_specs) which will be called by another function (get_nument).
This is actually a gtk3 code, but I guess its problem with python.
The complete code, at its present state can be seen here.
Kindly help.
This:
File "hw3.py", line 42, in get_nument
self.spec.connect("activate",self.get_specs)
In get_nument, reference get_specs as just get_specs. So, try:
self.spec.connect("activate", get_specs)
It's just a function that you've declared in the scope of get_nument, so it's just like any variable. An example:
def foo(self):
x = 34
def bar():
# ...
# Use x:
print(x)
# Use bar:
print(bar()) # Note: no self, because bar isn't part of self.

Python : AttributeError

I get an AttributeError I can't seem to work out.
I'm working with two classes.
The first class goes something like that.
class Partie:
def __init__(self):
# deleted lines
self.interface = Interface(jeu=self)
def evaluerProposition(self):
# computations
self.interface.afficherReponse()
Introducing second class (in a separate file).
class Interface:
def __init__(self, jeu):
self.jeu = jeu
self.root = tkinter.Tk()
# stuff
def onClick(self, event):
# talk
self.jeu.evaluerProposition()
def afficherReponse(self):
# stuff
I start the whole thing by
partie = Partie()
All manipulations on my widget work fine until some click event causes
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeInterface.py", line 197, in clic
self.jeu.evaluerProposition()
File "C:\Users\Canard\Documents\My Dropbox\Python\AtelierPython\Mastermind\classeJeu.py", line 55, in evaluerProposition
self.interface.afficherReponse()
AttributeError: 'Partie' object has no attribute 'interface'
I typed in the interpretor
>>> dir(partie)
and got a long list in return with 'interface' among the attributes.
Also typed
>>> partie.interface
<classeInterface.Interface object at 0x02C39E50>
so the attribute seems to exist.
Following the advice in some former post, I checked the instance names do not coincide with module names.
I am confused.
Most likely, in some code that you're not showing us, you're doing something like this:
self.some_button = tkinter.Button(..., command=self.interface.onClick())
Note the trailing () on onClick(). This would cause the onClick method to be called at the time the button is created, which is probably before your constructor is done constructing the instance of the Partie class.

Using python static class C#/Java style, scope difference errors

I have two files, namely game.py and map.py. The following simplified code resides in them:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from datetime import *
from map import *
class Game:
Scene = QGraphicsScene
View = QGraphicsView
#staticmethod
def start():
Game.App = QApplication(sys.argv)
Game.Scene=QGraphicsScene();
Game.Scene.setBackgroundBrush(QBrush(QColor(Qt.green)));
Game.View=QGraphicsView(Game.Scene);
print Game
map=Map()
Game.App.exec_()
if __name__=='__main__':
Game.start()
and file map.py:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from game import *
class Map(QObject):
def __init__(self,parent=None):
super(Map,self).__init__(parent);
print Game
v=Game.View
print v
v.setWindowTitle("sth")
Running game.py results in
__main__.Game
game.Game
<class 'PyQt4.QtGui.QGraphicsView'>
Traceback (most recent call last):
File "/home/abiusx/workspace/borj/trunk/game.py", line 119, in <module>
Game.start()
File "/home/abiusx/workspace/borj/trunk/game.py", line 66, in start
map=Map()
File "/home/abiusx/workspace/borj/trunk/map.py", line 16, in __init__
v.setWindowTitle("asb")
TypeError: QWidget.setWindowTitle(QString): first argument of unbound method must have type 'QWidget'
The problem is, the code in map.py that references Game.View, detects it as a class (as defined in class body) but not what is overwritted on it (an actual instance).
Also Game is known as main.Game in game.py but as game.Game in map.py
Could anyone help me?
the code in map.py that references Game.View, detects it as a class
That's because View = QGraphicsView sets it to a class. It only becomes an instance when you run Game.start. (To be honest, I don't understand why you're setting this class variable to a class object initially, or why the Game class exists at all.)
Also Game is known as main.Game in game.py but as game.Game in map.py
The module name changes to __main__ when you run a module as a script.
Whenever a file is read in Python, when it reaches a class definition it defines that class.
In my scenario, game and map both relied on each other. this is a well known circular reference problem in python.
I added another module, main.py, used game and map in it, and game in map. Problem solved.

Categories