How to specify borders in urwid? - python-3.x

I am new to urwid and think I missunderstood something. I don't see why this doesn't work. And I don't understand the error message.
#!/usr/bin/env python3
import urwid
def show_or_exit(key):
if key in ('q', 'Q'):
raise urwid.ExitMainLoop()
txt.set_text(repr(key))
txt = urwid.Text('FooBar')
fil = urwid.Filler(txt, valign='middle', height=('relative', 70))
box = urwid.LineBox(fil)
pad = urwid.Padding(box, align='center', width=('relative', 85))
loop = urwid.MainLoop(pad, unhandled_input=show_or_exit)
loop.run()

I've also had problems like this, to get a better grasp of what's going on you probably should read the documentation section about widgets sizing modes. Basically, this has to do with the way the widgets rendering work, which is different for each widget depending on its "sizing mode". This is one of the trickiest things to understand about Urwid, once you get that then you're able to be more productive with it. :)
Here is a working version of the code you provided:
#!/usr/bin/env python3
import urwid
def show_or_exit(key):
if key in ('q', 'Q'):
raise urwid.ExitMainLoop()
txt.set_text(repr(key))
txt = urwid.Text('FooBar')
widget = urwid.LineBox(txt)
widget = urwid.Padding(widget, align='center', width=('relative', 85))
widget = urwid.Filler(widget, 'middle')
loop = urwid.MainLoop(widget, unhandled_input=show_or_exit)
loop.run()

Related

'_Screen' object has no attribute 'tk' when trying to use canvasvg.saveall() on turtle

I have made a strange program that can draw fractals and circles and spirals and I have been trying for hours to get a way to save the turtle output to a image file (preferably png or jpeg).
I am getting the '_Screen' object has no attribute 'tk' when trying to use canvasvg.saveall() on turtle. here is the code:
import turtle
import random
import canvasvg
root = turtle.Screen()
drawing = 1
def save():
canvasvg.saveall("spircles.svg", root)
print("turning angle:")
turningangle = float(input())
print("size:")
forward = float(input())
print("spiral:")
try:
spiral = float(input())
if spiral == None:
spiral = random.random()
except:
pass
spiral = random.random()
turtle = turtle.Turtle(visible=False)
turtle.speed(speed=0)
turtle.hideturtle()
turtle.ht()
print("drawing. spiral:", spiral)
try:
while drawing == 1:
root.listen()
root.onkey(save, "s")
turtle.left(turningangle)
turtle.forward(forward)
turningangle += spiral
spiral += (spiral / turningangle)
except Exception as e:
drawing = 0
pass
print("done. press enter to exit. error:", e)
input()
exit()
turtle.mainloop()
anybody know an easy way of doing this? have tried PIL and it hasn't worked. I also want to not have to install third party programs. I want to be able to install some modules with pip (if necessary) and be able to run it without hassle. it should save to an image file when the user presses "s".
I have tried PIL, and canvasvg.saveall() and I want canvasvg.saveall() as it seems to be the easiest way of doing this.
While Turtle uses tkinter.Canvas to draw your shapes, the Screen object is not a tkinter.Canvas object, nor is it a tkinter.Widget at all. Turtle provides a method for this task, it's called turtle.getcanvas and you can use it on your Screen object. So canvas = root.getcanvas() should work just fine.
It seems like you can use canvasvg.saveall(filename, canvas), but be aware that they state not all items are supported.
def save():
canvas = root.getcanvas()
canvasvg.saveall("spircles.svg", canvas)

Calling a function within a function causing problems in execution

I am building a snake game using Tkinter only, and I managed to make a working game. The code works perfectly, until I added a start menu to show up before the game. To do this, I encased all my functions within one function called play(), and when I run the code, a menu shows up as expected, and when clicked play the window closes and the game itself shows up.
However, the keybinds for left/right/up/down to control the snake no longer works. I have checked that I have called the correct functions within my mainloop, and I have also tried moving it outside of the mainloop but it throws a referenced before assigned error.
Is there a logic error that I am missing? I am a beginner to Python and the Tkinter module so that is quite likely. Here is my code (where I suspect the problem is):
def play():
#some other functions including moveSnake and placeFood
def leftKey(event):
global direction
direction = "left"
def rightKey(event):
global direction
direction = "right"
def upKey(event):
global direction
direction = "up"
def downKey(event):
global direction
direction = "down"
snake = []
snakeSize = 15
snake.append(canvas.create_rectangle(snakeSize,snakeSize, snakeSize * 2, snakeSize * 2, fill="white", outline = ""))
score = 0
txt = "Score:" + str(score)
scoreText = canvas.create_text(width/2, 20, fill="white", font="Helvetica 20 bold", text=txt)
canvas.bind("<Left>", leftKey)
canvas.bind("<Right>", rightKey)
canvas.bind("<Up>", upKey)
canvas.bind("<Down>", downKey)
canvas.focus_set()
direction = "right"
placeFood()
moveSnake()
window.mainloop()
#new window/start menu
window1 = Tk()
window1.geometry('600x800')
window1.title("Snake")
#play button
playButton = Button(window1,text="Play", command = play)
playButton.pack(side=TOP)
#leaderboard button
leaderboardButton = Button(window1,text="Leaderboard", command = viewleaderboard)
leaderboardButton.pack(side=TOP)
#settings button
playButton = Button(window1,text="Settings", command = viewsettings)
playButton.pack(side=TOP)
window1.mainloop() ```
I managed to fix it without needing to create a class. I moved my keybinds to my main script, right below I created window1. Then I reassigned the bind to the 'window', opposed to 'canvas'. The purpose being that the keybinds were not being called to the correct place. I also add global score and global direction, to avoid it being unrecognised. This fixed my code, though I'm sure it can be optimised much further. Hope it helps out another newbie like me!
** To clarify, 'window' is my original window in which the game lies in and is defined in a function which I have not listed, it is separate to window1 **
global score
score = 0
txt = "Score:" + str(score)
scoreText = canvas.create_text(width/2, 20, fill="white", font="Helvetica 20 bold", text=txt)
window.bind("<Left>", leftKey)
window.bind("<Right>", rightKey)
window.bind("<Up>", upKey)
window.bind("<Down>", downKey)
window.focus_set()
global direction
direction = "right"

Is there a way to move the camera of a 2d world in pyglet?

I'm testing pyglet, and it has everything(except for a good guide) but the only thing that i don't understand is: how do I move the camera to show hidden content?
As stated by Rabbid76, try pyglet.gl.glTranslatef(dx,dy,dz).
The first argument in glTranslatef changes the x-direction of a supposed "camera",
the second changes y, and the third changes z. Heres a quick code example that may also help:
import pyglet
from pyglet.window import key
from pyglet.gl import glTranslatef
def movement(keys):
if keys[key.I]:
glTranslatef(0,10,0)
if keys[key.K]:
glTranslatef(0,-10,0)
if keys[key.J]:
glTranslatef(-10,0,0)
if keys[key.L]:
glTranslatef(10,0,0)
def update(dt):
window.clear()
label.draw()
movement()
if __name__ == '__main__':
window = pyglet.window.Window(height=1000,width=1000)
keys = key.KeyStateHandler()
window.push_handlers(keys)
label = pyglet.text.Label('Hello, world',
font_size=36,
x=window.width//2, y=window.height//2)
pyglet.clock.schedule_interval(update,1/60)
pyglet.app.run()
In the above example, you would use the I, J, K, and L keys to move a label around your window. Hope this was helpful!
For anyone who comes since the pyglet 2 update, you can now use Window.view = Window.view.from_translation(pygmath.Vec3(xpos, ypos, zpos)).
Try using an offset. Fo/x, lets say x = 0, and camoffset = 5. You can render the x as x+camoffset. It works.

I'm new to coding. A while loop in Python won't work properly, but has no errors

I got this code from a book called "Python for Kids," by Jason Briggs. This code was ran in Python 3.4.3. I don't have any outside coding experience outside from this book. I tried multiple possibilities to fix this and looked online, but I couldn't find anything that would work or help my problem. If you have new code or edits for this code, that would be helpful to me continuing to learn Python.
from tkinter import *
import random
import time
class Game:
def __init__(self):
self.tk = Tk()
self.tk.title("Mr. Stick Man Races for The Exit")
self.tk_resizable(0, 0)
self.tk.wm_attributes("-topmost", 1)
self.canvas = Canvas(self.tk, width=500, height=500, highlightthickness=0)
self.canvas.pack()
self.tk.update()
self.canvas_height = 500
self.canvas_width = 500
self.bg = PhotoImage(file="Wallpaper.gif")
w = self.bg.width()
h = self.bg.height()
for x in range(0, 5):
for y in range(0, 5):
self.canvas.create_image(x * w, y * h, image=self.bg, anchor='nw')
self.sprites = []
self.running = True
def mainloop(self):
while 1:
if self.running == True:
for sprite in self.sprites:
sprites.move()
self.tk.update_idletasks()
self.tk.update()
time.sleep(0.01)
g = Game()
g.mainloop()
This code was supposed to make a window with a wallpaper I created in Gimp to fill the window. When I ran the code, nothing happened and no errors appeared. What I need help on is making a window with my wallpaper appear. If you can help, can you give me an explanation with code. I'm sorry if my mistakes are obvious.
These two statements need to be all the way to the left, with no indentation:
g = Game()
g.mainloop()
The code class Game: creates a class, which can be thought of as a recipe for how to create a game. It does not actually create the game, it only provides code to create the game.
In order to actually create the game -- called instantiatiation -- you need to call Game as if it was a function. When you do g = Game() you are actually creating the game object and saving a reference to it. Unless you do this, the game will never be created. Thus, to create a instance of the game, you must define it in one step (class Game()) and create it in another (g = Game())
Warning, there are other problems in the code. This answers your specific question, but you need to fix the indentation of the def mainloop statemen, and there may be other issues.
The biggest problem is that this simply isn't the right way to do animation in Tkinter. It might be ok as a learning tool, but ultimately this is simply not proper usage of tkinter. I don't know if this code is straight from the book or if this is code you're trying on your own, but tkinter simply isn't designed to work this way. You shouldn't be creating your own mainloop function because tkinter has one that is built in.
To fix the mainloop issue, remove the existing mainloop function, and add this in its place (properly indented under class Game():
def mainloop(self):
# start the animation
self.animate()
# start the event loop
self.tk.mainloop()
def animate(self):
if self.running == True:
for sprite in self.sprites:
sprites.move()
self.tk.after(10, self.animate)

PyQt/PySide How to access/move QGraphicsItem after having added it to QGraphicsScene

This might be a very uninformed question.
I've been trying to figure out QGraphics*, and have run into a problem when trying to move an item (a pixmap) relative to or inside of the QGraphicsView.
class MainWindow(QMainWindow,myProgram.Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.scene = QGraphicsScene()
self.graphicsView.setScene(self.scene)
pic = QPixmap('myPic.png')
self.scene.addPixmap(pic)
print(self.scene.items())
This is the relevant part of the program with an arbitrary PNG
My goal, for example, would be to move the trash-can to the left-most part of the QGraphicsView.
I tried appending this to the code above:
pics = self.scene.items()
for i in pics:
i.setPos(100,100)
However, it doesn't make a difference, and even if it did, it would be awkward to have to search for it with a "for in".
So my questions are:
How do I access a QPixmap item once I have added it to a QGraphicsView via a QGraphicsScene. (I believe The QPixmap is at this point a QGraphicsItem, or more precisely a QGraphicsPixmapItem.)
Once accessed, how do I move it, or change any of its other attributes.
Would be very grateful for help, or if anyone has any good links to tutorials relevant to the question. :)
The problem is that you need to set the size of your scene and then set positions of the items, check this example:
from PyQt4 import QtGui as gui
app = gui.QApplication([])
pm = gui.QPixmap("icon.png")
scene = gui.QGraphicsScene()
scene.setSceneRect(0, 0, 200, 100) #set the size of the scene
view = gui.QGraphicsView()
view.setScene(scene)
item1 = scene.addPixmap(pm) #you get a reference of the item just added
item1.setPos(0,100-item1.boundingRect().height()) #now sets the position
view.show()
app.exec_()

Resources