The Code:-
from tkinter import *
import sys
import time
import random
root = Tk()
canvas = Canvas(root,height=700,width=700,bg='pink')
canvas.pack()
canvas.create_rectangle(0,0,10,700,fill='blue')
canvas.create_rectangle(690,0,700,700,fill='blue')
canvas.create_rectangle(0,0,700,10,fill='blue')
canvas.create_rectangle(0,690,700,700,fill='blue')
canvas.create_arc(110,9,130,29,extent=359,fill='black',style=ARC)
canvas.create_rectangle(290,500,410,510,fill='red')
root.mainloop()
Everything appears fine with color, only the arc doesn't get filled up.
How can I color the arc?
According to the documentation, you cannot fill an arc except if its style is either PIESLICE or CHORD.
This actually makes sense: how would you fill a geometric object which is not closed?
You can simply remove the style attribute and it should work.
canvas.create_arc(110, 9, 130, 29, extent=359, fill='black')
I find it easier to use the outline = colour method while leaving the entry of style = 'arc' alone this will change the colour to what you want because of a tkinter querk that for small line widths you only ever see the outline. A more thorough way would be outline = colour, fill = colour this will be a complete uniform color no matter the thickness
Related
This problem drives me crazy as it looks trivial but i have already wasted many hours to find a solution but still no success. I need help.
Let's say the line is 'HelloHelloHelloHelloHello', the font is Georgia 17. How to find a correct value for the width to get the width of the text widget equal to the length of line? "The width of the widget in characters (not pixels!), measured according to the current font size." My findings show that people asking similar questions get answers about using font measure method, but it doesnt work...
import tkinter
import tkinter.font as tkFont
txt='HelloHelloHelloHelloHello'
root=tkinter.Tk()
t_Font = tkFont.Font(family='Georgia', size=17)
width=t_Font.measure(txt)
t=tkinter.Text(root,width=width,font=('Georgia',17))
t.insert(1.0,txt)
t.pack()
The result is ridiculous http://joxi.net/E2p1NJlT7NgjvA.jpg (with width=280). Empirical research shows that 20 is a correct value..but how to get it? Using len(txt) looks much better but i believe there should be a good solution. Can't understand what I am missing here...
If you want the Text widget having width in pixels around the width of the text, you can put the Text widget inside a frame and set the size (in pixels) of the frame to the desired value and then use .place() on the Text widget to fill the frame:
t_Font = tkFont.Font(family='Georgia', size=17)
width, height = t_Font.measure(txt), t_Font.metrics('linespace')
print(width, height)
lines = 20
# +4 to include the width of the border (default 1) and padding (default 1)
frame = tkinter.Frame(root, width=width+4, height=lines*height+4)
frame.pack()
# put text box inside the frame
t = tkinter.Text(frame, font=t_Font)
t.insert(1.0, txt)
t.place(relwidth=1, relheight=1) # fill the available space of the frame
I wanted to create a transparent box with a red outline between these two specified points at (614, 162) and (759, 306). However, it returns me an invisible or no box at all. But for (100, 50) and (160, 100), the box is visible.
import tkinter as tkr
app = tkr.Tk()
app.title("AI Cashier")
app.geometry("1366x768")
app.wm_attributes("-transparentcolor", "white")
app.config(bg = "White")
can = tkr.Canvas(app,bg = "White",highlightthickness = 0)
can.create_rectangle(100,50,160,100,outline = "red", width = 2)
can.pack()
app.mainloop()
Could anyone explain to me because I'm still new to tkinter. Or is it a bug?
Why does my create_rectangle disappears after specifying these points using tkinter?
It is because the canvas is only a couple hundred pixels wide and tall, so you are drawing outside the visible area of the canvas.
A simple fix for the code in the question is to make the canvas bigger. You can either give it an explicit width and height (eg: can = tkr.Canvas(..., width=800, height=400)), or force the canvas to fill the window (eg: can.pack(fill='both', expand=True')). In either of those cases, the image will be visible.
I am trying to place images next to each other side by side but the labels overlap and the label sticks out.
from tkinter import *
root = Tk()
root.geometry("1000x700")
root.resizable(0, 0)
##############################################
TFi = PhotoImage(file="images/Topframe.png")
TF = Label(root, image=TFi)
TF.place(x=-3, y=-3)
BFi = PhotoImage(file="images/Botframe.png")
BF = Label(root, image=BFi)
BF.place(x=-3, y=650)
LF1i = PhotoImage(file="images/LeftFrame1.png")
LF1 = Label(root, image=LF1i)
LF1.place(x=-3, y=50)
##############################################
root.mainloop()
Is it possible to place an image in Tkinter without a Label or canvas
Your most common choices for labels are a canvas or a label. You can also put images on buttons, and embed them in a text widget.
The best choice for creating labels that are next to each other are to use pack or grid. pack is good if you're making a single horizontal or vertical grouping, but grid is better if you're making both rows and columns of widgets.
You can use place, but that requires that you do all of the math to compute the location of each image, and usually results in a user interface that isn't very resilient to changes in screen resolution. It also sometimes ends up causing you to have to do changes to every widget even if you only want to tweak the layout slightly.
My guess for why they overlap is that you aren't aware that the coordinates you give place by default specify the center of the image rather than the upper-left corner. You can specify which part of the image is at the given coordinate with the anchor option.
the label sticks out.
I'm not exactly sure what you mean by that, but if you mean that it has a 3D appearance, you can control that by giving it a borderwidth of zero and/or a relief of "flat".
Can I use rbg instead of hex in tkinter? If so, how can I do it?
I am planning to use this feature to make sort of a gradient from one color to another and I plan to make a for loop to change it from 1 to 255 in a few seconds.
from tkinter import *
root = Tk()
root.configure(background="can i use rgb instead of hex here?")
root.mainloop()
No, tkinter does not support RGB, but you can write a small helper function to remedy this:
Maybe something like this, where the argument rgb must be a valid rgb code represented as a tuple of integers.
import tkinter as tk
def _from_rgb(rgb):
"""translates an rgb tuple of int to a tkinter friendly color code
"""
return "#%02x%02x%02x" % rgb
root = tk.Tk()
root.configure(bg=_from_rgb((0, 10, 255)))
root.mainloop()
If you find it more readable, you can also use fstrings to achieve the exact same result:
def _from_rgb(rgb):
"""translates an rgb tuple of int to a tkinter friendly color code
"""
r, g, b = rgb
return f'#{r:02x}{g:02x}{b:02x}'
Note that the colorsys module from the Python standard library can help translate from HSV, HLS, and YIQ color systems
def rgbtohex(r,g,b):
return f'#{r:02x}{g:02x}{b:02x}'
print(rgbtohex(r=255, g=255, b=255))
Hope this helps some of you
This will make a gradient.
from tkinter import *
root=Tk()
root.title("colors")
cv=Canvas(root, width=20, height=255)
cv.pack()
def _from_rgb(rgb):
"""translates an rgb tuple of int to a tkinter friendly color code
"""
return "#%02x%02x%02x" % rgb
for canvas in range(255):
cv.create_line(0,canvas, 20,canvas, fill=_from_rgb((canvas, canvas,
canvas)))
You can have fun with this.
You can try this to:
from tkinter import *
def dec2hex(r,g,b):
return f'#{r:02x}{g:02x}{b:02x}'
root=Tk()
cv=Canvas(highlightthickness=0)
cv.pack(expand=True, fill=BOTH)
for color in range(510):
cv.create_line(0,color, 3000,color, fill=dec2hex(0, round((510-color)/2), round(color/2)))
for color in range(510):
cv.create_line(0,(color+510), 3000,(color+510), fill=dec2hex(round(color/2), 0, round((510-color)/2)))
Sorry for not answering correctly, I didn't think it through properly. Now that I have seen your comment #Mike-SMT, I've improved it
from tkinter import *
import random
import time
window = Tk()
window.title("Random colours")
colours = ["black",
"cyan",
"magenta",
"red",
"blue",
"gray"
]
bgColour = window.configure(background = random.choice(colours))
window.update()
time.sleep(1)
bgColour1 = window.configure(background = random.choice(colours))
window.mainloop()
Have fun with this, you can get creative and do things like making this into a forever changing background colour, or making a sequence. There are so many different colours on Tkinter that you can use, so you can manually change each colour after every few seconds if you really want. Another thing I forgot to mention previously, you can't use a time.sleep() option as Mike said, but it will work if you use a ".update()" line of code, as shown above.
I'm new to Python, and I'm trying to write a program that displays an 8x8 grid. The vertical lines are supposed to be red and the horizontal lines are supposed to be blue. But I can't seem to figure it out. I know it must be in a loop, but I'm not sure even where to start. Please help!
Here's my code so far:
from tkinter import *
class Canvas:
def __init__(self):
self.window = Tk()
self.window.title("Grid")
self.canvas = Canvas(window, width = 200, height = 200,
bg = "white")
self.canvas.pack()
def drawGrid(self):
self.canvas.create_line()
Thanks!
Take a look at http://effbot.org/tkinterbook/canvas.htm#Tkinter.Canvas.create_line-method for details about the create_line() method.
You need two arguments: the coordinates of the line and a fill color. The coordinates are a list of [x0, y0, x1, y1], and they correspond to pixel values with an origin at the top-left corner of the parent widget, so to draw a horizontal green line on your 200x200 Canvas, you'd write:
self.canvas.create_line(0,0,200,200, fill='green')
To create a grid of lines, a for or while loop would work, which modified the list of coordinates at every iteration and passed it to a new create_line() function at the end of each loop.
That should get you started.