Change the width of a rectangle in tkinter's canvas widget - python

I've tried several ways to change the width of the blue rectangle in this example code. Nothing seems to work. In the code, "a" represents a float variable between 1.00, and 0.00. That value is used to calculate "b," which is the desired width of the blue rectangle in pixels. I have some fairly complicated code that generates that value, and at least that works. In order for the code to work, the width of the blue rectangle must rely on "b." I've tried "Canvas.itemconfig()," and it didn't work.
import tkinter
from tkinter import *
root = Tk()
root.maxsize(320,240) # Sets max size of window
root.minsize(320,240)
canvas_height = 23
canvas_width = 315
w = Canvas(root, width=canvas_width, height=canvas_height)
w.pack()
w.create_rectangle(5, canvas_height, canvas_width, 2, fill="yellow")
w.create_rectangle(5, canvas_height, canvas_width, 2, fill="blue")
a = 1.0 # More complicated code creates this float between 0.00 and 1.00. It is a percentage of the desired 'blue rectangle' width
b = int(a * canvas_width)
root.mainloop()
If anyone could help, I would greatly appreciate it!
P.s. I'm new to the Stackoverflow community, so please let me know if there's anything I can do to make my questions easier to answer.

The rectangle is defined by a couple of coordinates for opposite corners. Get the coordinates of the left edge, add the width to the x coordinate, and use that to set the coordinates of the right edge.
First, keep track of the object id so you can change it later:
blue = w.create_rectangle(5, canvas_height, canvas_width, 2, fill="blue")
To resize, get the coordinates...
x0, y0, x1, y1 = w.coords(blue)
Do some math...
x1 = x0 + b
And reset the coordinates
w.coords(blue, x0, y0, x1, y1)

Related

Calculated Values of Mass and Area in Simple CAD Program are Very Incorrect

# NG
import tkinter as tk
# Create the main window
window = tk.Tk()
window.title("Simple CAD")
# Define the size of the canvas inches
CANVAS_WIDTH = 5
CANVAS_HEIGHT = 5
# Define the size of the window pixels
WINDOW_WIDTH = 500
WINDOW_HEIGHT = 500
# Conversion factor to convert inches to pixels
INCHES_TO_PIXELS = 100
# Canvas for user to draw shape
canvas = tk.Canvas(window, width=CANVAS_WIDTH * INCHES_TO_PIXELS, height=CANVAS_HEIGHT * INCHES_TO_PIXELS)
canvas.pack()
# Create a list to store the coordinates of shape
shape_points = []
# Define function for mouse movement on the canvas
def handle_mouse_event(event):
# Check if the mouse pointer is within bounds of canvas
if 0 <= event.x <= CANVAS_WIDTH * INCHES_TO_PIXELS and 0 <= event.y <= CANVAS_HEIGHT * INCHES_TO_PIXELS:
# Add the coordinates of the mouse event to the list of shape points
shape_points.append((event.x, event.y))
# Draw traced shape on the canvas
if len(shape_points) > 1:
canvas.create_line(shape_points[-2], shape_points[-1])
# Bind mouse inputs to the canvas
canvas.bind("<Button-1>", handle_mouse_event)
canvas.bind("<B1-Motion>", handle_mouse_event)
canvas.bind("<ButtonRelease-1>", handle_mouse_event)
# Define function to calculate area and volume of shape
def calculate_area_and_volume():
# Check if the shape is closed
if shape_points[0] != shape_points[-1]:
# Add the first point to the end of the list to close the shape
shape_points.append(shape_points[0])
# User inputted extrude value
extrude_length = float(input("Enter the extrude length in inches: "))
# Calculate area of the shape in in^2
area = 0
for i in range(len(shape_points) - 1):
x1, y1 = shape_points[i]
x2, y2 = shape_points[i + 1]
area += (x1 * y2) - (x2 * y1)
area = abs(area) / 2
# Vol calculation of object in in^3
volume = area * extrude_length
# Output values
print("Area:", area, "in^2")
print("Volume:", volume, "in^3")
# Create button to close (fully define SolidWorks :/ traced shape
close_button = tk.Button(window, text="Close Shape", command=calculate_area_and_volume)
close_button.pack()
# Create button to calculate the area and volume
calculate_button = tk.Button(window, text="Calculate Area and Volume",
command=calculate_area_and_volume)
calculate_button.pack()
window.mainloop()
Basically, this is a passion project of mine as a MechE student. I wanted to make a VERY simple CAD program with Python (the only language I know) in which a user can sketch an object, and then define a value for its thickness (extrude in CAD). To my knowledge, I have done the shoestring formula correctly for calculating area--basically just a derivation of Herons' Formula right?
Unfortunately, something is wrong because the canvas is set to 5x5 inches and this should theoretically mean absolute maximum area would be 25in^2, but when I tried drawing a square, it came out to be around 20,000 in^2. It was definitely not a perfect square, but if anything the area should have been less than 25 in^2.
I thought this was maybe an issue of the shape not being fully defined and therefore having near infinite area, but I implemented two different ways to make sure this doesn't happen. The first is a GUI button on the canvas that the user can click and it will close the shape for them. Even if they do not end up clicking this button, there is a second checker before the calculations to make sure that the shape is closed.
There's also a possibility I messed up the Shoestring formula like I alluded to above but that doesn't seem very likely.
I'm at a complete loss for why the calculations are this off and any help at all would be greatly appreciated!

how do i define the height of rectangle?

"Create a rectangle with coordinates x1=15, y1=20, width=120, height=150"
Does it have to do something with the coordinates? Cause there's no 'height' option
from tkinter import *
window = Tk()
root.geometry("300x300")
canv = Canvas(window, width=200, height=250, bg="white")
canv.pack(pady=15)
coords = [15, 20, 0, 0]
rect = canvas.create_rectangle(coords, width=120)
window.mainloop()```
Yes, your coords define the positions of two opposite corners of the rectangle, [x1, y1, x2, y2]. You have the coordinates of the top left corner already, so you need to figure out the coordinates of the bottom right corner using the given height and width - you simply add these to the coordinates.
In this example you simply would change your coords from [15, 20, 0, 0] to [15, 20, 135, 170].
One thing to note is that the coordinate system in Tkinter is defined with (0,0) at the top left of the window, so a higher y coordinate means further down the window and higher x coordinate means further right.
The coordinates are how you define the height and width of the rectangle. No height definition is required.
This is from : https://pythonguides.com/python-tkinter-canvas/
Python Tkinter Canvas Rectangle
Python Tkinter Canvas has built-in features to create shapes.
To create a rectangle create_rectangle() method is used.
This method accepts 4 parameters x1, y1, x2, y2. Here x1 and y1 are the coordinates for the top left corner and x2 and y2 are the coordinates for the bottom right corner.

Why is it that whenever I run this code I get a white rectangle on my screen?

from tkinter import *
window = Tk()
window.geometry('1000x1000')
window.configure(bg='black')
myCanvas = Canvas(window)
myCanvas.pack()
def create_circle(x, y, r, canvasName):
x0 = x - r
y0 = y - r
x1 = x + r
y1 = y + r
return canvasName.create_oval(x0, y0, x1, y1)
create_circle(100, 100, 50, myCanvas)
window.mainloop()
The output looks like this:
Why is there a white rectangle there? I am just trying to print a circle on a black canvas.
There are two bugs that are causing your problem:
1.Any default canvas's color are white.
2.The canvas also has a default highlight boarder which is also white.
To solve both of these problems you can change:
myCanvas = Canvas(window)
to
myCanvas = Canvas(window, bg='black',highlightthickness=0)
Then the white rectangle will disappear
if you want to keep the highlight boarder you can also change the color of the boarder using highlightbackground="black"
or any other desired color.
Finally, if you want to change the circle's color because the circle blends into the canvas color add: outline="white"
to when you make the oval

How can I draw a point with Canvas in Tkinter?

I want to draw a point in Tkinter,Now I'm using Canvas to make it,but I didn't find such method to draw a point in Canvas class.Canvas provides a method called crete_line(x1,y1,x2,y2),so i tried to set x1=x2,y1=y2 to draw a point, but it doesn't work.
So anyone can tell me how to make it,it will be better if use Canvas can make it,other solution will be also accepted.Thanks!
There is no method to directly put a point on Canvas. The method below shows points using create_oval method.
Try this:
from Tkinter import *
canvas_width = 500
canvas_height = 150
def paint(event):
python_green = "#476042"
x1, y1 = (event.x - 1), (event.y - 1)
x2, y2 = (event.x + 1), (event.y + 1)
w.create_oval(x1, y1, x2, y2, fill=python_green)
master = Tk()
master.title("Points")
w = Canvas(master,
width=canvas_width,
height=canvas_height)
w.pack(expand=YES, fill=BOTH)
w.bind("<B1-Motion>", paint)
message = Label(master, text="Press and Drag the mouse to draw")
message.pack(side=BOTTOM)
mainloop()
The provided above solution doesn't seem to work for me when I'm trying to put a sequence of a few pixels in a row.
I've found another solution -- reducing the border width of the oval to 0:
canvas.create_oval(x, y, x, y, width = 0, fill = 'white')
With create_line you have other possible workaround solution:
canvas.create_line(x, y, x+1, y, fill="#ff0000")
It overwrites only a single pixel (x,y to red)
Since an update of the Tk lib (somewhere between Tk 8.6.0 and 8.6.9) the behavior of create_line had changed.
To create a one pixel dot at (x, y) in 8.6.0 you add to write
canvas.create_line(x, y, x+1, y, fill=color)
Now on 8.6.9 you have to use:
canvas.create_line(x, y, x, y, fill=color)
Note that Debian 9 use 8.6.0 and Archlinux (in early 2019) use 8.6.9 so portability is compromised for a few years.

Python circle - moves and detects obstacles (moves alone, not with arrows)

I want to make a circle move and avoid obstacles with collision detection. Here's the code I have.
from Tkinter import *
window = Tk()
canvas = Canvas(window,width=800, height=500, bg='pink')
canvas.pack()
finishline = canvas.create_oval(700, 300, 700+50, 300+50,fill='green')
robot = canvas.create_oval(20,200,20+45,200+45,fill='yellow')#(x1, y1, x2, y2)
ob1 = canvas.create_rectangle(200,400,200+50,200+1,fill='black')
canvas.update()
ob1 = canvas.create_rectangle(500,200,150+400,300+100,fill='blue')
canvas.update()
You could always use the canvas.find_overlapping method (found here: http://effbot.org/tkinterbook/canvas.htm#Tkinter.Canvas.find_overlapping-method), and if it ever returns a value other than your own little circle, you can make the circle go in the other direction or something.
It's kind of hard to give a specific answer with such unspecific requirements.

Categories

Resources