How do I reference my window variable in a separate class? - python

I'm using python's arcade library and I keep getting the "NameError: name 'window' is not defined" error. I tried deleting the main function and just running the
window = MyGame()
for button in window.buttonList:
button.draw()
arcade.run() without the function around it, but now I need to run this from another file without using os.exec or subprocess while still being able to go back and run the first one. I need to use a main function, but I don't know how to do it without raising an error. Here is my code
from subprocess import call
from tkinter import *
from tkinter import filedialog
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Menu"
class MenuItem():
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
def draw(self):
pass
def func(self):
pass
class FreeDraw(MenuItem):
def func(self):
window.close()
window.set_visible(False)
#run other file
def draw(self):
window.buttonShapes.append(arcade.create_rectangle_outline(self.x, self.y, self.width, self.height, arcade.color.BLACK))
class MyGame(arcade.Window):
""" Our custom Window Class"""
def __init__(self):
""" Initializer """
# Call the parent class initializer
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
# Set the working directory (where we expect to find files) to the same
# directory this .py file is in. You can leave this out of your own
# code, but it is needed to easily run the examples using "python -m"
# as mentioned at the top of this program.
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)
self.buttonList = [FreeDraw(SCREEN_WIDTH/2, 100, 400, 100)]
self.buttonShapes = arcade.ShapeElementList()
arcade.set_background_color(arcade.color.ASH_GREY)
def setup(self):
pass
def on_draw(self):
""" Draw everything """
arcade.start_render()
arcade.draw_text("Free Draw", (self.buttonList[0].x - self.buttonList[0].width / 2) + 115,
self.buttonList[0].y - 25,
arcade.color.BLACK, 30)
self.buttonShapes.draw()
def on_key_press(self, key, modifiers):
pass
def on_key_release(self, key, modifiers):
pass
def on_mouse_motion(self, x: float, y: float, dx: float, dy: float):
pass
def on_mouse_release(self, x: float, y: float, button: int,
modifiers: int):
for button in self.buttonList:
if x <= button.x + (button.width / 2) and x >= button.x - (button.width / 2):
if y <= button.y + (button.height / 2) and y >= button.y - (button.height / 2):
button.func()
self.buttonList[0].func()
def main():
window = MyGame()
for button in window.buttonList:
button.draw()
arcade.run()
main()

You can use arcade.View instead of arcade.Window in your separate classes. Example:
import arcade
class View1(arcade.View):
def on_draw(self):
arcade.start_render()
arcade.draw_text('View 1', 300, 200, arcade.color.RED, font_size=30, anchor_x='center')
def on_mouse_press(self, _x, _y, _button, _modifiers):
self.window.show_view(View2())
class View2(arcade.View):
def on_draw(self):
arcade.start_render()
arcade.draw_text('View 2', 300, 200, arcade.color.RED, font_size=30, anchor_x='center')
def on_mouse_press(self, _x, _y, _button, _modifiers):
self.window.show_view(View1())
window = arcade.Window(600, 400)
window.show_view(View1())
arcade.run()
Output:

Related

pyglet.gl AttributeError: 'int' object has no attribute '_get_domain'

imports
from pyglet.gl import *
import pyglet
from pyglet.window import key
the code
self.batch = pyglet.graphics.Batch
x,y,z = 0,0,0
X,Y,Z = x+1,y+1,z+1
color = ('c3f', (1,1,1)*4)
self.batch.add(4, pyglet.gl.GL_QUADS, None, ('v3f', (x,y,z, X,y,z, X,Y,z, x,Y,z)), color) # problem here
My ide says that function got "4" aka int and expected batch, but i looked at some documentation and it was the same as in the code above.
i am using python 3.8.
Oh and if needed here is all of my code (i do not think you need it):
from pyglet.gl import *
import pyglet
from pyglet.window import key
import math
WIDTH = 1000
HEIGHT = math.floor(WIDTH / 12 * 9)
class Model:
def __init__(self):
self.batch = pyglet.graphics.Batch
x,y,z = 0,0,0
X,Y,Z = x+1,y+1,z+1
color = ('c3f', (1,1,1)*4)
self.batch.add(4, pyglet.gl.GL_QUADS, None, ('v3f', (x,y,z, X,y,z, X,Y,z, x,Y,z)), color)
def draw(self):
self.batch.draw()
class Window(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_minimum_size(math.floor(WIDTH*0.5), math.floor(HEIGHT*0.5))
self.model = Model()
def on_draw(self):
self.clear()
self.model.draw()
if __name__ == '__main__':
window = Window(width=WIDTH, height=HEIGHT, caption="pyglet.gl test", resizable=True)
glClearColor(0, 160, 160, 1)
pyglet.app.run()
Oh, I sloved it my self. Im just stupid.
I said:
self.batch = pyglet.graphics.Batch
But i had to add () at the end:
self.batch = pyglet.graphics.Batch()

How do you add a controllable graphic with an image overtop in kivy?

I am new to python and have messed around with Kivy a little. This is the first app of my own design I've been tying to make. The goal is for it to be a game where there is a character that moves in all directions around the screen. My problem right now is that I can't get the character widget to display and I don't know if it's a problem with the widget or the image in the widget. When I run the program all I get is a black screen and no errors. Can anyone see where I went wrong?
Also if you have any recommendations in a better way to structure anything it would be appreciated :)
import kivy
kivy.require('1.7.2')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.properties import NumericProperty
from kivy.graphics import Rectangle, Color, Canvas
from kivy.uix.image import Image
class WidgetDrawer(Widget):
def __inti__(self, imageStr, **kwargs):
super(WidgetDrawer,self).__inti__(**kwargs)
with self.canvas:
self.size = (Window.width*.05, Window.width*.05)
self.x = self.center_x
self.y = self.center_y
self.pos = (self.x, self.y)
self.rect_pl = Rectangle(source= imageStr, pos=self.pos, size=self.size)
self.bind(pos=self.update_graphics_pos)
self.rect_pl.pos = self.pos
def update_graphic_pos(self, value):
self.rect_pl.pos = value
def setSize(self, width, height):
self.size = (width,height)
class Player(WidgetDrawer):
impulse_x = 3
impulse_y = 3
winre = -0.1
velocity_x = NumericProperty(0)
velocity_y = NumericProperty(0)
def move(self):
self.x = self.x + self.velocity_x
self.y = self.y + self.velocity_y
if self.x > Window.width*.95 or self.x < Window.width*.05:
velocity_x = 0
if self.y > Window.height*.95 or self.y < Window.height*.05:
velocity_y = 0
def determineVelocity(self):
self.velocity_x = self.impulse_x + self.winre
self.velocity_y = self.impulse_y + self.winre
def update(self):
self.determineVelocity()
self.move()
class GUI(Widget):
def __init___(self, **kwargs):
super(GUI, self).__init__(**kwargs)
self.character = Player(imageStr = './character.png')
self.character.x = Window.width/4
self.character.y = Window.height/2
self.add_widget(self.character)
class GameApp(App):
def build(self):
parent = Widget()
app = GUI()
parent.add_widget(app)
return parent
if __name__ == '__main__':
GameApp().run()
The problem is self.add_widget(self.character) i.e. adding widget in __init__ method. Try to run python main.py -m inspector, Ctrl+E and get to GUI(). No children, nothing. Add children after __init__.
About the structure:
use kv language
use one naming style
fix typos(__inti__ != __init__)
if you have 1.7.2 version, you definitely need to update asap

Trouble with Kivy Python? Function error and image error

I am trying to use Kivy to build an app.
Here is the code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line
from kivy.core.window import Window
class Background_Animation(Widget):
def __init__(self, imageStr, **kwargs):
super(Background_Animation, self).__init__(**kwargs)
self.__init__= __init__(self, imageStr, **kwargs)
with self.canvas :
self.size= (Window.width * 0.002 * 25, Window.height *0.002 * 25 )
# bind the fbo to the current opengl context
self.bind(pos == self.update_graphics_pos)
# x center position
self.x = self.center_x
# declare the image
imageStr= Image("~/Downloads/psychTREE.jpg", **kwargs)
# y center position
self.y = self.center_y
self.pos= (self.x, self.y)
self.image= self.pos
return image
def build(self):
self.build = build
run = __init__(self, imageStr, **kwargs)
return run
if __name__ == "__main__" :
build(self, imageStr, **kwargs).run()
When I try to run the code, it says name "build" is not defined . Any ideas on how to solve this problem? Also, how would I make the image appear in the gui?

Python Tkinter keyboard using bind

I have a problem using the bind option so I can click a button in my keyboard,
and call a function once the key is pressed.
I tried taking other codes that have the similar purpose and I saw that I'm doing pretty much the same, though I still have some problem I must've missed.
I will be very thankful if you help me with this.
Here's my code:
# -*- coding: utf-8 -*-
#Imports
from Tkinter import *
from PIL import ImageTk, Image
import time
import tkMessageBox
#===========================================================================================================================================#
#Tkinter Class
class App(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
#===========================================================================================================================================#
#Game Pieces Classes
class Board:
def __init__(self, rows = 7, columns = 6, picture_height = None, picture_width = None):
self.rows = rows
self.columns = columns
self.picture = ImageTk.PhotoImage(Image.open(r"C:\Users\Ariel\Desktop\Python\4inarow.gif"))
self.picture_height = self.picture.height()
self.picture_width = self.picture.width()
def create_and_pack(self, canvas):
board_item = canvas.create_image(700, 370, image = self.picture)
def __str__(self):
print "Rows:", self.rows, "Columns:", self.columns
class Disk:
def __init__(self, player_number = None):
self.picture = ImageTk.PhotoImage(Image.open(r"C:\Users\Ariel\Desktop\Python\me" + str(player_number) + ".gif"))
self.player_number = player_number
def create_and_pack(self, canvas, x, y):
disk_item = canvas.create_image(x, y, image = self.picture)
def get_x_parameter(self, number):
#X growing by 70~73 per number
x = 330
for i in range(7):
if number == i:
x = x + i * 72
return x
def get_y_parameter(self, number):
#Y lowered by 70~73 per number
y = 635
for i in range(6):
if number == i:
y = y - i * 72
return y
def place(self, canvas, x, y):
#First left down circle parameters
#480, 635
canvas.move(self.picture, x, y)
def __str__(self):
print "The disk's picture string:", self.picture, "The player disk's number:", self.player_number
#===========================================================================================================================================#
#Game Class
class Game:
def __init__(self, board = None, disk1 = None, disk2 = None):
self.disk1 = disk1
self.disk2 = disk2
self.board = board
#===========================================================================================================================================#
#KeyboardClass
class Keyboard:
def __init__(self, key_number = None):
self.key_number = key_number
def press_and_place(self, canvas, number, function):
canvas.focus_set()
canvas.bind("<" + str(number) + ">", function)
#===========================================================================================================================================#
#Main.
myapp = App()
myapp.master.title("4 in a Row")
myapp.master.maxsize(2000, 1200)
#---------------------------------------------------------------------------------------------------#
GameBoard = Board(7, 6)
FirstPlayerDisk = Disk(1)
SecondPlayerDisk = Disk(2)
GameClass = Game(GameBoard, FirstPlayerDisk, SecondPlayerDisk)
#---------------------------------------------------------------------------------------------------#
#Creating Canvas and placing the disks and the board.
board_canvas = Canvas(width = GameBoard.picture_width, height = GameBoard.picture_height)
board_canvas.pack(expand=1, fill=BOTH)
GameBoard.create_and_pack(board_canvas)
FirstPlayerDisk.create_and_pack(board_canvas, 330, 635)
SecondPlayerDisk.create_and_pack(board_canvas, 260, 635)
#---------------------------------------------------------------------------------------------------#
#Creating Keyboard instance and placing the first disk in the last row in a column of choice
number_choice = 3
KeyboardClass = Keyboard(number_choice)
first_player_x = FirstPlayerDisk.get_x_parameter(number_choice)
first_player_y = FirstPlayerDisk.get_y_parameter(number_choice)
KeyboardClass.press_and_place(board_canvas, number_choice, FirstPlayerDisk.place(board_canvas, first_player_x, first_player_y))
#---------------------------------------------------------------------------------------------------#
myapp.mainloop()
Thanks a lot in advance.
I believe your problem lies in this line:
KeyboardClass.press_and_place(board_canvas, number_choice, FirstPlayerDisk.place(board_canvas, first_player_x, first_player_y))
the third argument FirstPlayerDisk.place(board_canvas, first_player_x, first_player_y) is actually a None type as
def place(self, canvas, x, y):
#First left down circle parameters
#480, 635
canvas.move(self.picture, x, y)
returns None
From How to bind a keypress to a button in Tkinter and this site, you need to pass the function, that is, simply FirstPlayerDisk.place (no parenthesis following it).

where does this object come from

I'm a relatively new programmer, and i'm in the process of making a game. I am using some code from my previous project which ran fine. But now when i try to call a certain function, which i don't think should need any parameters, it returns some strange errors.
i have this class which i have copied from my previous project:
import pyglet as p
class Button(object):
def __init__(self, image, x, y, text, on_clicked):
self._width = image.width
self._height = image.height
self._sprite = p.sprite.Sprite(image, x, y)
self._label = p.text.Label(text,
font_name='Times New Roman',
font_size=20,
x=x + 20, y=y + 15,
anchor_x='center',
anchor_y='center')
self._on_clicked = on_clicked # action executed when button is clicked
def contains(self, x, y):
return (x >= self._sprite.x - self._width // 2
and x < self._sprite.x + self._width // 2
and y >= self._sprite.y - self._height // 2
and y < self._sprite.y + self._height // 2)
def clicked(self, x, y):
if self.contains(x, y):
self._on_clicked(self)
def draw(self):
self._sprite.draw()
self._label.draw()
i have my window event that calls the function (w is the window):
#w.event
def on_mouse_press(x, y, button, modifiers):
for button in tiles:
button.clicked(x, y)
and three variations of the function it calls that each has a different 'errors':
def phfunc(a):
print(a)
returns this thing: <Button.Button object at 0x0707C350>
def phfunc(a):
print('a')
returns: a
which it actually should
def phfunc():
print('a')
returns a long list of callbacks resulting in this:
File "C:\Google Drive\game programmeren\main.py", line 15, in on_mouse_press
button.clicked(x, y)
File "C:\Google Drive\game programmeren\Button.py", line 25, in clicked
self._on_clicked(self)
TypeError: phfunc() takes no arguments (1 given)
my best guess is that the argument it has is the self from the Button class. is this correct, and should i worry about this?
You call the function reference stored in self._on_clicked with self as a parameter. self is the instance of your Button class:
self._on_clicked(self)
The default representation for your custom Button class is <Button.Button object at 0x0707C350>.
Since you did so explicitly, that is not something to worry about.

Categories