How to resize GraphWin window? - python

I'm using Zelle's graphics library to do some online coursework. Part of the assignment I'm working on seems to assume I can resize an existing GraphWin window. But this hasn't been touched on previously in the course, and looking over the documentation for graphics.py I don't see a way to accomplish this. I poked around a GraphWin object, and nothing seems to alter the window's size. Is it possible to resize a GraphWin window?
I've tried:
from graphics import *
new_win = GraphWin('Test', 300, 300)
new_win.setCoords(0, 0, 100, 200)
new_win.width = 100

The setCoords() method just creates a new virtual coordinate system within an existing window.
We might be able to achieve sufficent functionality for your purpose by dropping down to the tkinter level and specializing GraphWin:
from graphics import *
class ResizeableGraphWin(GraphWin):
""" A resizeable toplevel window for Zelle graphics. """
def __init__(self, title="Graphics Window", width=200, height=200, autoflush=True):
super().__init__(title, width, height, autoflush)
self.pack(fill="both", expand=True) # repack?
def resize(self, width=200, height=200):
self.master.geometry("{}x{}".format(width, height))
self.height = int(height)
self.width = int(width)
# test code
win = ResizeableGraphWin("My Circle", 100, 100)
win.setBackground('green')
c = Circle(Point(75, 75), 50)
c.draw(win) # should only see part of circle
win.getMouse() # pause for click in window
win.resize(200, 400) # should now see all of circle
win.getMouse() # pause for click in window
c.move(25, 125) # center circle in newly sized window
win.getMouse() # pause for click in window
c.setFill('red') # modify cirlce
win.getMouse() # pause for click in window
win.close()
A Python 3 implementation since I called super(). It can probably be retrofit for Python 2.

Zelle's graphics library does not have a method for resizing a window after it has been drawn.

I just found out how to do it
from graphics import *
win= GraphWin("Person",400,400)

Related

Way to set a singled dimension of the root window using python - tkinter?

I'm looking to have a window occupy the width of the screen but not (yet) the height of the screen. I have the root established and working but as far as I can tell the geometry method requires at least a width AND height, not one or the other individually. I would like the window to continue to scale dynamically in height as widgets are added/taken away. There is a starting height of the notebook tab and button
Without the rest of the code for the ReaderUI class shown below, this is what the main method looks like so far...
def main():
root=Tk()
tab_control = ttk.Notebook(root)
first_tab = ttk.Frame(tab_control)
tab_control.add(tab1,text="File 1")
tab_control.pack(expand=1,fill="both")
new_tab_button = Button(tab,text="create new tab", command = lambda: new_tab(tab_control))
new_tab_button.pack(padx = 5, pady = 5)
newUI = ReaderUI(tab1)
width=root.winfo_screenwidth()
height = root.winfo_screenheight()
root.geometry("{}x{}+0+0".format(width,height)
root.resizable(False,False)
root.mainloop()
My question boils down to this: is there a way to have the UI build itself in terms of height (as it would without the geometry method in place) and only establish a width as wide as the screen? Potentially a modification to the line
root.geometry("{}x{}+0+0".format(width,height))
so that height is left unset and free to move.
you can use
winfo_screenwidth
- Returns a decimal string giving the width of window's screen, in pixels.
Code
root.winfo_screenwidth()
root being your Tk() instance
then you can lock the x axis by using
root.resizable(False, True) # (X,Y)
Recourse
https://www.astro.princeton.edu/~rhl/Tcl-Tk_docs/tk8.0a1/winfo.n.html

how can i draw on any window using python

I am making a tutorial to explain things to others. For that tutorial i am trying to make a python program (which is like the paint app)
Which we all use in windows. To draw with pen,brush and to draw shapes like square,circle and have a option for color piker to choose colour to draw.
I already tried with the from tkinter import choosecolor to create paint like software in python.
But with that it draws only on a tkinter canvas.
But i don't want to draw on a canvas i want to draw it on live screen while i make the tutorial.
example image is shown below
I am trying to make a gui window like this to choose color and pen tool to draw on the screen (eg.desktop,web browser etc).
Can anyone give me some suggestion on how can i draw like this on my desktop screen or on any window.
Although in your video,it seems that " draw directly on screen ".Actually,I think it didn't.
There is a easy example to "draw on the screen",You can modify it:
import tkinter as tk
from PIL import ImageGrab,ImageTk
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2) # windows 10
class ToolWin(tk.Toplevel):
def __init__(self):
tk.Toplevel.__init__(self)
self._offsetx = 0
self._offsety = 0
self.wm_attributes('-topmost',1)
self.penSelect = tk.BooleanVar()
self.overrideredirect(1)
self.geometry('200x200')
self.penModeId = None
self.bind('<ButtonPress-1>',self.clickTool)
self.bind('<B1-Motion>',self.moveTool) # bind move event
draw = tk.Checkbutton(self,text="Pen",command=self.penDraw,variable=self.penSelect)
draw.pack()
cancel = tk.Button(self,text="Quit",command=root.destroy)
cancel.pack()
def moveTool(self,event):
self.geometry("200x200+{}+{}".format(self.winfo_pointerx()-self._offsetx,self.winfo_pointery()-self._offsety))
def clickTool(self,event):
self._offsetx = event.x
self._offsety = event.y
def penDraw(self):
if self.penSelect.get():
self.penModeId = root.bind("<B1-Motion>",Draw)
else:
root.unbind('<B1-Motion>',self.penModeId)
def Draw(event):# r = 3
fullCanvas.create_oval(event.x-3,event.y-3,event.x+3,event.y+3,fill="black")
def showTool(): # the small tool window
toolWin = ToolWin()
toolWin.mainloop()
root = tk.Tk()
root.state('zoomed')
root.overrideredirect(1)
fullCanvas = tk.Canvas(root)
background = ImageTk.PhotoImage(ImageGrab.grab(all_screens=True)) # show the background,make it "draw on the screen".
fullCanvas.create_image(0,0,anchor="nw",image=background)
fullCanvas.pack(expand="YES",fill="both")
root.after(100,showTool)
root.mainloop()
Also,you can move the toolbar by dragging it.
(PS: I think you nearly finished it.)

Python with tkinter aspect ratio issue

I am attempting to create a simple window that maintains a square shape when resized, using python 3.6.4 and tkinter 8.6. Here is my code that produces a window, but does not maintain its aspect ratio when resized.
import tkinter as tk
w = tk.Tk()
w.aspect(1,1,1,1)
w.mainloop()
maybe you can use a canvas to make that, he detect event (image size changed) and .place relative x and relative y. I tryed make a script to help you, but you need make somes changes
from tkinter import *
# create a canvas with no internal border
canvas = Canvas(bd=0, highlightthickness=0)
canvas.pack(fill=BOTH, expand=1)
lastw, lasth = canvas.winfo_width(), canvas.winfo_height()
# track changes to the canvas size and draw
# a rectangle which fills the visible part of
# the canvas
def configure(event):
global lastw, lasth
canvas.delete("all")
w, h = event.width, event.height
try:
label.config(font = ('Arial ', int(12 * ((w - lastw) / (h - lasth))))) # -- this formula need change :3
except ZeroDivisionError: pass
lastw, lasth = canvas.winfo_width(), canvas.winfo_height()
canvas.bind("<Configure>", configure)
label = Label(canvas, text = "YOLO")
label.place(relx = 0.5, rely = 0.5) # - this make the widget automatic change her pos
mainloop()
you can see how this work here http://effbot.org/zone/tkinter-window-size.htm

Tkinter Toplevel() positioning without static geometry

Im using Toplevel() for popup windows and I want the popup to be displayed to the right of the mouse when it comes up. I found how to do this but only by specifying the geometry of the window. How can I control where the window comes up without specifying the size. I want the window to be the size it needs to be for whatever data is is going to display.
This is what im using right now:
helpwindow = Toplevel()
helpwindow.overrideredirect(1)
helpwindow.geometry("662x390+{0}+{1}".format(event.x_root - 1, event.y_root - 12))
How can I put only the format settings in the window geometry? Or is their a better way?
Use "+{}+{}" without size
helpwindow.geometry("+{}+{}".format(event.x_root - 1, event.y_root - 12))
ie. moving window :)
import tkinter as tk
def move():
global pos_x
helpwindow.geometry("+{}+200".format(pos_x))
pos_x += 10
root.after(100, move)
root = tk.Tk()
pos_x = 0
helpwindow = tk.Toplevel()
move()
root.mainloop()

python tkinter hide the window during widget creation

I have a small annoying problem so I come to you to see if you can help to solve it.
I have the following code in Python2.7:
# main window
root = tk.Tk()
root.title('My application')
# create the objects in the main window
w = buildWidgetClass(root)
# size of the screen (monitor resolution)
screenWi = root.winfo_screenwidth()
screenHe = root.winfo_screenheight()
# now that widgets are created, find the widht and the height
root.update()
guiWi = root.winfo_width()
guiHe = root.winfo_height()
# position of the window
x = screenWi / 2 - guiWi / 2
y = screenHe / 2 - guiHe / 2
root.geometry("%dx%d+%d+%d" % (guiWi, guiHe, x, y))
So I create the main window (without any size) I insert widgets inside, then I define the size of the result, and place it in the middle of the screen.
The number of widget in the window may vary, so the resulting size!
So far, so good, it works ! My only problem is that the window first appear in the left top corner of the screen, then repositioned to the center. Not a big deal, but not really professional neither.
So my idea was to hide the main window during the widgets creation time and then make it appearing after having defined the geometry.
So after the first line, I added :
root.withdraw()
then at the end :
root.update()
root.deiconify()
but when the window reappear, it wasn't re-sized by the widget and have a size of 1x1 !!
I tried to replace root.withdraw() by root.iconify(), the window is correctly re-sized but, surprisingly, isn't deiconified at the end !!!
I'm a little bit lost on this ...
Using root.winfo_reqwidth instead of root.winfo_width may help in your case.
Finally with the input of kalgasnik, I have a working code
# main window
root = tk.Tk()
# hide the main window during time we insert widgets
root.withdraw()
root.title('My application')
# create the objects in the main window with .grid()
w = buildWidgetClass(root)
# size of the screen (monitor resolution)
screenWi = root.winfo_screenwidth()
screenHe = root.winfo_screenheight()
# now that widgets are created, find the width and the height
root.update()
# retrieve the requested size which is different as the current size
guiWi = root.winfo_reqwidth()
guiHe = root.winfo_reqheight()
# position of the window
x = (screenWi - guiWi) / 2
y = (screenHe - guiHe) / 2
root.geometry("%dx%d+%d+%d" % (guiWi, guiHe, x, y))
# restore the window
root.deiconify()
Thanks a lot to both of you for your time and your help

Categories

Resources