Tkinter canvas default width = '10c' - python

I was looking through the tkinter widgets at https://effbot.org/tkinterbook/canvas.htm and noticed that the width configure option for the canvas defaults to '10c'
width=
Canvas width. Default value is ā€˜10cā€™. (width/Width)
What does that mean? What effect does that have on how its width is handled by pack and grid geometry?

Question: Canvas default width = '10c', What does that mean?
Reference:
width
Specifies a desired window width that the Canvas widget should request from its geometry manager. The value may be specified in any of the forms described in the COORDINATES section below.
COORDINATES
Coordinates and distances are specified in screen units, which are floating-point numbers optionally followed by one of several letters m|c|p.
If no letter is supplied then the distance is in pixels.
If it is c then the distance is in centimeters;

Related

How does size work within objects Tkinter

Midway through making my program I realise there are some discrepancies between the height / width properties of objects.
For example in my document here, the main green frame has a width of 640 whereas the buttons are only a size of 3 yet they appear so much larger. How exactly is width and height calculated (is it always pixels)
Image
The width and height attributes don't always refer to pixels. For some widgets, the width and height is in characters. For example, `Label(root, text="Hello", width=10) will make a widget that is wide enough to hold 10 average sized characters in the default font.
Just about any widget that has text will measure width and height in characters (Text, Label, Button, etc). Widgets that do not have text as part of their normal appearance (Frame, Canvas, etc) are measured in pixels.
For some, the value of width and height depends on other options. For example, in a Button or Label, if the widget sets the image attribute then the values will be in pixels, and if the image attribute is not set then the values will be in characters.
The documentation for each widget will say what the width and height represents.
Ya, Height and Width is measured in pixels

Move tkinter view on widget

There is a way for directly move the current view of the Canvas to a widget out of the current visual?
I mean if i have a canvas with width=5000 and height=1000 and on my screen i have canvas window that shows the portion screen width=300 and screen height=300 there is a function for move the view to an element that is at coords (600,700) of the canvas withot using the scrollbars?
Scrollbars don't do anything magic. To make a scrollbar work, they are simply configured to call the xview or yview method of the canvas. There's nothing preventing you from directly calling those methods yourself.
The xview_moveto and yview_moveto take a fraction as an argument, and scrolls the canvas so that that fraction is above or to the left of the visible portion of the canvas. For example, to see an element at an x coordinate of 600 on a canvas with a drawable area 1000 pixels wide you can use the fraction 600/1000.
The xview_scroll and yview_scroll take a number and a string describing that number. The string should be either "units" or "pages". Thus, a value of 10 and a string of "units" will scroll the view by 10 pixels in the x direction.
Here is an example using the moveto methods. It creates a canvas with a scrollable region that is 5000 pixels wide and 1000 pixels tall, but with a displayable area of 300x300. It then draws a rectangle starting at 600,700, and then scrolls it into view. Even though the rectangle is drawn "off screen", it will appear in the upper-left of the canvas.
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=300, height=300, scrollregion=(0,0,5000,1000))
canvas.pack(fill="both", expand=True)
canvas.create_rectangle(600, 700, 650, 750, fill="red")
canvas.yview_moveto(700/1000)
canvas.xview_moveto(600/5000)
root.mainloop()

Tkinter - relation between font type and width

I apologize in advance if my question is a duplicate however I have not found an answer to this question.
I'm learning Tkinter and I'm struggling with understanding the relation between a label's font type, it's size and it's width and the length of the string in it.
Specifically, what my problem is:
I have created a widget: a 800x640 canvas on which I want to place other
widgets.
On this canvas I want to place a label with some text which has the following
attributes: font: Helvetica, font size: 20, text = "main application". I want
to place this label widget at the very most top left corner of the
widget(meaning at point 0,0 with respect to the canvas). I want the label to
be 200 in width meaning it's background to take almost 1/3 of the canvas's
size(after I manage to do this I plan to add 2 more labels as well). I guess
the height of the label is determined by the font size in this case 20. I
placed the label at coordinate y=20 and this coordinate seems to be ok.
I did some googling and found out that the width parameter of the label widget is not the actual width but something related to the font and size of the label's text: something like if I understood correctly: if the width is 6 than the label will be wide enough to contain 6 characters of, in my case verdana size 20. But I was not able to figure out what width and what x coordinate I should give my label so it starts at the x point of the canvas. Here is the code that I wrote:
from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox
from tkinter import Menu
# Define the application class where we will implement our widgets
class Application(Frame):
def __init__(self, master):
super(Application, self).__init__(master)
# CANVAS COLOUR DEFAULTS TO THE COLOUR OF THE WORKING WINDOW
canvas = Canvas(master, width=800, height = 640, bg="gray") # IF YOU DO .PACK() HERE IT WILL RETURN NONE AND THEN YOU WILL HAVE PROBLEMS BECAUSE .PACK() RETURNS A 'NONE' TYPE OBJECT
canvas.place(relx=0.5, rely=0.5, anchor=CENTER)
# The 'menu' of the application. The selection labels
main_application_label = Label(master, text="main_application", font=("Helvetica", 20))
main_application_window = canvas.create_window(103,20, window=main_application_label)
main_application = Tk()
main_application.title("main_application")
app = Application(main_application)
app_width = 800
app_height = 640
screen_width = main_application.winfo_screenwidth()
screen_height = main_application.winfo_screenheight()
x_coord = (screen_width/2) - (app_width/2)
y_coord = (screen_height/2) - (app_height/2)
main_application.geometry("%dx%d+%d+%d" % (app_width, app_height, x_coord, y_coord))
main_application.mainloop()
I have managed to somehow get the label at around point 0,0(by giving more values till I got it right) but the actual width of the label is not 200 pixels(~1/3 of the canvas). Please help me understand what values to the width parameter I should give so that my label's background is 1/3 of the canvas's size and if possible explain the relation between character font and width parameter so I can do that for any widgets regardless of their text's length. Thank you for reading my post!
Edit: What I wanted to do was to place 3 widgets(labels in this case but it doesn't matter) on the canvas. I did not understand what the 'anchor' option does and that was confusing me because I was expecting the center of the widget to be placed at the given coordinates all times but as I was changing anchor the placement of the center of the widget was changing and that was confusing me. It's all clear now thanks to #Bryan Oakley. Thanks.
If you want the upper left corner of the text to be at (0,0), you don't have to adjust the coordinates based on the width. You can use the anchor option when creating the canvas object:
main_application_window = canvas.create_window(0, 0, anchor="nw",
window=main_application_label)
If you really need to compute the actual size of the string, you can create a Font object and then use the measure method to find the actual width of a string in the given font.
from tkinter.font import Font
font = Font(family="Helvetica", size=20)
string_width = font.measure("main_application")
string_height = font.metrics("linespace")
This gives you the size of the rendered string. If you're using a label widget you'll also need to take into account the amount of padding and borders that the widget uses.
When you create items on a canvas, you can specify the width and height. For example, this makes the widget 200 pixels wide:
main_application_window = canvas.create_window(0, 0, anchor="nw", width=200,
window=main_application_label, width=400)

Drawing rectangle on python Tkinter canvas that covers the entire canvas does not show border on top and left

I'm trying to create a rectangle inside a Tkinter (Python 2.7) canvas that is the same dimension as the canvas. Here is the relevant part of the code:
self.canvas = Canvas(self, width=100, height=100, backround="yellow")
self.canvas.create_rectangle(0,0,100,100)
This draws a rectangle but I can't see the left and top border of the rectangle. If I start the rectangle from let's say 5,5 instead of 0,0 I can see the border of the rectangle. Any ideas as to why this happens, and how I can get around it?
Unfortunately, the canvas border is included in the drawable region. Try setting the borderwidth and highlightthickness attributes to zero on the canvas.
You'll also want to adjust the coordinates of your rectangle to end at 99, since counting starts at zero (if the width is 100, the coordinates go from 0 to 99).

How do I set the width of an Tkinter Entry widget in pixels?

I noticed that the width argument for the Tkinter entry widget is in characters, not pixels.
Is it possible to adjust the width in pixels?
You can also use the Place geometry manager:
entry.place(x=10, y=10, width=100) #width in pixels
You cannot specify the width in pixels using the '-width' option, but there are ways to accomplish the same thing. For example, you could pack an entry in a frame that has no border, turn off geometry propagation on the frame, then set the width of the frame in pixels.
You can use "ipadx" and "ipady" while packing the "Entry" widget.
You can also use it with "grid".
import tkinter as tk
root = tk.Tk
e = tk.Entry()
e.pack(ipadx=100, ipady=15)
tk.mainloop()

Categories

Resources