What does the +0+0 in geometry() mean in tkinter? - python

I understand the very beginning which creates the window size, but I see people put +x+x after the initial 400x300 or whatever size. I've looked all over for an answer but can't seem to find one.

width x height + x position + y position, positions relative to the top left corner of the screen in pixels
Edit:
Here's a brief summary of the function from tcl.tk, written up much more concisely than I could hope to achieve.

root.geometry("%dx%d+0+0" % (w, h))
its just where do you want the pixel from, setting the top and left corner of the screen
you can also see the link http://effbot.org/tkinterbook/place.htm

Related

Weird things happening when making image get bigger on mouse hover in Pygame

I am making a scene where there is a thumbs-up image that is supposed to get bigger on mouse hover, and shrink back to normal size when the mouse is no longer hovering.
This is how I make the thumbs-up image:
thumbs_up_image = pygame.image.load("./plz_like.png")
thumbs_up_rect = thumbs_up_image.get_rect(topleft=(screen.get_width() // 2 - thumbs_up_image.get_width() + 75,
screen.get_height() // 2 + thumbs_up_image.get_height() - 225))
And this is how I make it get bigger:
if thumbs_up_rect.collidepoint(pygame.mouse.get_pos()):
thumbs_up_image = pygame.transform.scale(thumbs_up_image,
[n + 50 for n in thumbs_up_image.get_size()])
thumbs_up_rect = thumbs_up_image.get_rect()
This is how the image is blited:
screen.blit(thumbs_up_image, thumbs_up_rect)
The problem is that when I hover on the thumbs-up image, it first goes to the top-left corner of the screen. Then, when I hover on it again, it gets super big and pixelated.
What am I doing wrong?
I managed to figure it out by myself.
This is how I do it:
First, I prepared a bigger version of the image and it's rect: (as shown below)
big_thumbs_image = pygame.transform.scale(thumbs_up_image, [i + 50 for i in thumbs_up_image.get_size()])
big_thumbs_image_rect = thumbs_up_image.get_rect(
topleft=(screen.get_width() // 2 - thumbs_up_image.get_width() + 55,
screen.get_height() // 2 + thumbs_up_image.get_height() - 250))
Then, when the small image's rect collides with the mouse, blit the bigger image:
if thumbs_up_rect.collidepoint(pygame.mouse.get_pos()):
screen.blit(big_thumbs_image, big_thumbs_image_rect)
You are not showing the code that actually renders the image to the screen.; But basically: you are not saving the original size - at each hover event it will grow and grow (and it will grow once per frame, if that code is run in the mainloop).
You need a variable to hold the original image, one to tell your code the image has already been resized, and an else clause on this if to restore the original image: pygame won't do that for you.
Also, when you use the get_rect for the image, its top-left position will always be "0, 0" - you have to translate this top-left corner to a suitable coordinate- getting the rectangle center of the original sprite (wherever the data of its location on the screen is kept), and setting the same center on the new rect should work.
And finally, prefer "rotozoom" than "scale" - Pygame documentation is clear that the second method uses better algorithms for scaling.
Try using this pygame function:
pygame.transform.rotozoom(Surface, angle, scale)
I also had some issues with pixilation in a game but it seemed to work with this.

Wand - Right aligning text with offset

Gravity seemed like what I wanted but it does not let me change the x offset.
bg.caption(f"{xp} / {req_xp}", left=200, top=165, font=montserrat_bold, gravity='north_east')
Correctly offsets in the y direction but no matter what I put for left it remains glued to the right. Is this a bug with wand? I saw several examples of pure imagemagick where alignment seemed possible.
Captions are created by building a new bounding box (width x height), and renders the text to fit within the box -- while respecting the gravity parameter. After the text has been rendered, the bonding box is composited at the left x top coordinates of the image.
[...] it remains glued to the right. Is this a bug with wand?
With gravity set to "north_east" & width undefined, the text will remain "glued to the right".
Try the following ...
bg.caption(f"{xp} / {req_xp}",
left=200,
top=165,
width=100,
height=50,
font=montserrat_bold,
gravity='north_east')
Adjust the width= & height= parameter values to respect the pointsize of montserrat_bold variable.

How to crop an image such that if coordinates don't exist, the other side is extended, hence keeping the size of the crop the same?

I'm currently cropping images this way:
self.crop = self.img[self.y_center - self.radius:self.y_center + self.radius,
self.x_center - self.radius:self.x_center + self.radius:, ]
Where y_center and x_center are defined by clicks, and radius is the size of the crop. But I repeatedly run into a problem where the click is on an extreme side of an image. In that case, how do I extend the side on the other side of the image?
Basically I do not want to compromise the size.
The simple & stupid (r) way:
check if the rectangle around the point goes beyond the image
move it the corresponding amount of pixels if it does
repeat for all the 4 sides
Not so s&s is how to handle the case where the rectangle is larger than the entire image, but we'll see...
# X,Y - size of the image - 1 (maximum possible values for x,y)
# x,y - click coordinates relative to the image
t=x+radius; if t>X: x-=t-X
t=y+radius; if t>Y: y-=t-Y
t=x-radius; if t<0: x-=t #t<0 so it's increased actually
t=y-radius; if t<0: y-=t
del t
crop = img[x-radius:min(x+radius,X), y-radius:min(y+radius,Y)]
With min, we handle the case when the rectangle is larger than the image.
We check from the "high" side because we chose the order of adjustments so that the last ones have docked the rectangle to the "low" side.

Create a line using a list of coordinates in python GUI

I've been trying to create a graph using a create_line and a list of (x,y) points.
import Tkinter
Screen = [a list of screen coordinates]
World = []
for x,y in screen:
World.append(somefunctiontochange(x,y))
if len(World) >= 2:
Canvas.create_line(World)
The line doesn't show in my canvas though, and no error was given. Any help?
Took me a while but this is how you draw to a canvas in the way you want:
import Tkinter as tk
root = tk.Tk()
root.geometry("500x500")
root.title("Drawing lines to a canvas")
cv = tk.Canvas(root,height="500",width="500",bg="white")
cv.pack()
def linemaker(screen_points):
""" Function to take list of points and make them into lines
"""
is_first = True
# Set up some variables to hold x,y coods
x0 = y0 = 0
# Grab each pair of points from the input list
for (x,y) in screen_points:
# If its the first point in a set, set x0,y0 to the values
if is_first:
x0 = x
y0 = y
is_first = False
else:
# If its not the fist point yeild previous pair and current pair
yield x0,y0,x,y
# Set current x,y to start coords of next line
x0,y0 = x,y
list_of_screen_coods = [(50,250),(150,100),(250,250),(350,100)]
for (x0,y0,x1,y1) in linemaker(list_of_screen_coods):
cv.create_line(x0,y0,x1,y1, width=1,fill="red")
root.mainloop()
You need to supply create_line with the x,y positions at the start and end point of the line, in the example code above (works) I'm drawing four lines connecting points (50,250),(150,100),(250,250),(350,100) in a zigzag line
Its worth pointing out also that the x,y coords on a canvas start at the top left rather than the bottom left, think of it less like a graph with the x,y = 0,0 in the bottom left of the canvas and more how you would print to a page starting in top left corner moving to the right in the x and with the y incrementing as you move down the page.
I used:
http://www.tutorialspoint.com/python/tk_canvas.htm as reference.
If you aren't getting errors and you're certain your function is being called, you probably have one of three problems:
Is your canvas visible? A common mistake for beginners is to either forget to pack/grid/place the canvas, or to neglect to do that for all of its containers. An easy way to verify is to temporarily give your canvas a really bright background so that it stands out from the rest of the GUI.
Have you set the scroll region? The other explanation is that the drawing is happening, but it's happening in an area that is outside the viewable portion of the canvas. You should be setting the scrollregion attribute of the canvas after creating your drawings, to make sure everything you're drawing can be made visible.
Does your canvas and canvas objects have an appropriate color? It's possible that you've changed the background of the canvas to black (since you don't show that code in your question), and you're using a default color of black when creating your lines.

Negative coordinates in pygame

What would be the best way to use negative coordinates in pygame?
At the moment I have a surface that is 1.5 times the original surface then everything that needs to be drawn is shifted up by a certain amount (to ensure the negative coordinates become positive) and drawn.
Is there an easier/alternate way of doing this?
A simple solution is to write a linear mapping function from world coordinates to pygame screen coordinates
def coord(x,y):
"Convert world coordinates to pixel coordinates."
return 320+170*x, 400-170*y
and use it when drawing all world objects. Have a look here for a complete example.
There is no way to move the origin of a surface from 0,0.
Implement your own drawing class which transforms all the coordinates passed in into the space of the surface.
If it's similar to an RPG map situation, where you have world coordinates and screen coordinates:
use a function that translates world to local, and vice versa.
But I wasn't sure I'd you were looking for Rect's properties?
rect.bottomright = (width, height) # bottom right at window corner
If you want to use center coordinates to blit, vs top left being (0,0)
ship.rect.center = (20, 30) # don't need to translate by adding w/2 to topleft
See also: Rect.move_ip()

Categories