Drawing on canvas with python and tkinter - python-3.x

I am trying to display mouse position on timer. I use winfo_pointerxy(), here is part of the code from my_func():
curr_x, curr_y = mouseFrame.winfo_pointerxy()
curr_x = mouseFrame.canvasx(curr_x)
curr_y = mouseFrame.canvasy(curr_y)
mouseFrame.create_oval(curr_x, curr_y, curr_x + 5, curr_y + 5, fill='green')
start_btn.after(time_interval, my_func)
It seems like I use canvasx() wrong cause it still returns position counted from the left-up corner of the screen.

According to this tkinter reference (which I use constantly)
Because the canvas may be larger than the window, and equipped with
scrollbars to move the overall canvas around in the window, there are
two coordinate systems for each canvas:
The window coordinates of a point are relative to the top left
corner of the area on the display where the canvas appears.
The canvas coordinates of a point are relative to the top left
corner of the total canvas.
If your canvas is against the upper left corner of the window (display) and you have not scrolled the canvas, the two sets of coordinates should be the same.

Related

ggez resize window without distording drawn elements

I use ggez and would like to resize the window. The only way I found is
graphics::set_drawable_size(&mut ctx, width, height);
However, when I use it, the white circle I drawn turns into a white ellipse, and a seemingly grey circle appears below. So is there another way of resizing window, one that doesn't distort what is drawn ?
use
graphics::set_screen_coordinates(ctx,rect)
right after declaring changing size with graphics::set_mode(ctx,windowmode) turns the ellipse back into a circle. The gray shape vanishes after reducing the window (this is a pretty obscure thing).

MFC — spread a control to left, right and bottom

There is a CTreeCtrl in an arbitrary position on a fixed size CDialog.
Could you please advice how to position this CTreeCtrl in OnInitDialog so that its left, right and bottom sides were touched to the dialog sides, and there was an indent N on top?
I've been experimenting for several hours now, but it doesn't stick correctly to right and bottom:
CRect rect;
GetWindowRect(&rect);
rect.top = N;
m_Tree.MoveWindow(&rect);
I also tried GetClientRect.
I need to get the following:
By far the easiest solution in this case it to just use the inbuilt Dynamic Layout functionality:
Select the control in the IDE.
Set the Sizing Type property to Both.
Set Sizing X and Sizing Y to 100.
Then, as long as your dialog Border property is set to Resizing the tree control will stretch as you wanted:
No coding required as you can see:
Much easier!
Manual Method
But, if you do things manually you need to be sure that you understand what type of coordinates the API calls provide you. Coordinates can be relative:
Screen Coordinates
Client Coordinates
For example:
CWnd::GetWindowRect:
The dimensions are given in screen coordinates relative to the upper-left corner of the display screen. The dimensions of the caption, border, and scroll bars, if present, are included.
CWnd::GetClientRect:
The client coordinates specify the upper-left and lower-right corners of the client area. Since client coordinates are relative to the upper-left corners of the CWnd client area, the coordinates of the upper-left corner are (0,0).
CWnd::MoveWindow:
For a top-level CWnd object, the x and y parameters are relative to the upper-left corner of the screen. For a child CWnd object, they are relative to the upper-left corner of the parent window's client area.
Your tree control is a child so when you move it, the coordinates need to be relative to the upper-left corner of the parent window's client area.
Note, there is a handy CWnd::ScreenToClient API to translate from one system to the other. But this is not required in this instance.
Manual Method — Example
Putting it all together:
CRect rct;
GetClientRect(&rct); // The client area of your window (in client coordinates)
rct.top += N; // Adjust the top margin as required
myTree.MoveWindow(&rct); // Now move the child control
Please note that I have not debugged this to verify the code but it conveys the ideas.
Where possible I use the built in dynamic resizing, althought it can be very tricky to work out the sizing values. But in your case it is simple - 100.
I should point out that the above code will manually get it to the right place. But then you have to resize it as the window resizes. Try the Dynamic Layout approach instead.

How to make tkinter::pack() place label on top left corner in below program?

I am using pack() to align label and buttons on tkinter.The following code:
from tkinter import *
wind=Tk()
wind.geometry('450x450')
l1=Label(wind,text='Did you mean:')
l1.pack(side=LEFT)
b1=Button(wind,text='Button1',width=450)
b1.pack()
b2=Button(wind,text='Button2',width=450)
b2.pack()
wind.mainloop()
gives output:1
I tried removing the side=LEFT from l1.pack(side=LEFT) it gives: 2.
For me expected output is label l1 on top left corner and the buttons stacked below it.
pack works with a box model, aligning widgets along one side of the empty space in a container. Thus, to put something along the top, you need to use side="top" (or side=TOP if you prefer using a named constant), and it needs to come before other widgets.
In your specific case, to get the widget aligned at the top, you would do the following:
l1.pack(side=TOP)
By default this will center the widget along the top edge. If you also want the label aligned to the left, you would use the anchor option, which takes points of a compass ("n", "s", "e", "w", "nw", etc).
Thus, to place the widget at the top, and anchor it to the top-left corner you would do something like this:
l1.pack(side=TOP, anchor=NW)

How to add a floating text on a scrollable canvas in tkinter

I want to create a floating text (does not scroll even if the canvas below scrolls) in tkinter. I tried searching for floating labels but could not find.
Right now the parent of the canvas is a frame which is scrollable.
Added another canvas on top of that canvas with the same parent frame and lifted it up by
tk.Misc.lift(floating_canvas)
Now the below canvas is scrolabble while the above one is static

NSDocument - setting a reasonable starting location for the window

I'm playing about with the most recent NSDocument in a Swift document-based-app. One thing that's a bit odd is that the starting location for a new window is near the bottom of the screen.
Playing with the Storyboard a bit, its not clear how to use the built-in settings to come up with a reasonable "near the top" selection - the setting moves up from the bottom, not down from the top, so the position would change depending on the screen size?
I assume there's a position mechanism I can hook, but it's not obvious in the shell code that's supplied. Any hints?
OS X coordinate system is flipped in contrast to iOS. So the 0,0 is the bottom left corner.
You can calculate the position of your window in similar manner (any screen size)
CGFloat width = NSWidth([self.window screen].frame);
CGFloat height = NSHeight([self.window screen].frame);
[self.window setFrame:NSMakeRect(100, height - 100, width, height) display:YES];
Most easiest is to set initial height to 900 and forget about it and enable window restoration -> this will cause to open the window where it previously was and this is where it user wants.
Select your window in Storyboard. And fill initial position coordinates

Resources