Python canvas bigger size than screen - python

I´m trying to figure out how to set the size of my tkinter canvas to bigger then actually my screen is. My screen is 1920x1280, if I set in the following code any higher numbers, the size never gets above this (and I want to do it due to huge drawing there).
Code:
from tkinter import *
class Draw:
def __init__(self, min, max):
self.min = min
self.max = max
def draw(self):
master = Tk()
w = Canvas(master, width=2500, height=2500)
#...
I also tried master.geometry("2500x2500") but that didn´t work either.

You can't make windows larger than the physical screen. However, if your goal is to create a large drawing, you can do that without making the canvas physically large. The canvas widget is just a viewport into a much larger virtual drawing area.
For example, you can create a canvas that is only 400x400 pixels, yet draw an image that is 4000x4000. You can define the size of the virtual window by setting the scrollregion attribute to whatever size you want (up to a limit which I think is maybe around 64000x64000)

This happens because of your screen constraint, you cannot run 2500px * 2500px window on your 1920px * 1280px screen, if you try to run a window 1920px * 1280px on your screen, it would work.
This happens because your limits (2500px * 2500px) is too big for your monitor. The window tries to make 7250000 pixel on you 2457600 pixel screen!
So you would have to get a better screen possibly a 3k or 4k screen to run this.

Related

Tkinter window resize to fit content without touching

I have created an application that required to use the place() manager. I tried using pack() and grid() but after many tries and lots of effort it did not work for my goals. Since I use relx= and rely= almost all the time and I want to put my app on multiple OS's I need to have the window resize to fit all the widgets without them touching.
Is there a way to do this? Since many OS's and their updates change rendering the sizes of widgets changes greatly and I don't want the user to have to resize the window all the time. I want it to just fit as tightly as possible or get the minimum width and height to I can add some buffers. Is this possible? If not, is there a way to fix my app without having to rewrite everything?
Note:
I found something similar: Get tkinter widget size in pixels, but I couldn't properly get it to work.
I figured it out. You can use the widget.winfo_height()/widget.winfo_width() functions to get the minimum pixel sizes. Since the window.geometry() function requires pixel sizes you can make two lists: one for width, and one for height. By adding the minimum amount of widgets you can get the desired size.
Code:
height_widget_list = [main_label, main_notebook, the_terminal, quit_button, settings_button]
width_height_list = [commands_label, main_notebook, quit_button]
widget_list = [main_label, main_notebook, the_terminal, quit_button, settings_button, commands_label]
# Widgets must be updated for height and width to be taken
for widget in widget_list:
widget.update()
height_required_list = []
width_required_list = []
# Collects data
for widget in height_widget_list:
height_required_list.append(int(widget.winfo_height()))
for widget in width_height_list:
width_required_list.append(int(widget.winfo_width()))
# Get height requirement
minimum_height = 0
for height in height_required_list:
minimum_height += height
# Get width requirement
minimum_width = 0
for width in width_required_list:
minimum_width += width
# Make window correct size make window require the correct sizing
window.geometry("{}x{}".format(minimum_width, minimum_height))
window.resizable(False, False)

How can I set default screen tkinter not full screen?

I want to set default tkinter screen and not full screen in tkinter.Thank you
root.geometry("500x100") #Width x Height
Use this code to change your Tkinter screen size. Here root is the main window, geometry() is the function used to change screen size. 500 is the width and 100 is the height
its very easy you just need to set the with and heigth of the window by
root.geometry("400x900") # this .geometry() takes a string in the form of width x heigth
You have various arguments for your Tkinter window :
window.attributes("-fullscreen", True)
Changing it to False will disable fullscreen mode, True will activate it
window.geometry("1400x700")
You can set the default size of your GUI with this, but the user will be able to resize it classically
window.minsize(200, 200)
This one will set the minimum size of your GUI, past it, the user will not be able to reduce the window any further. If you set it to the size of your window, you disable the resizing.

Tkinter does not update while withdrawn

I have a program that will show an image on screen when a hotkey is pressed on my keyboard. Depending on which key was pressed a different image will be shown.
After 3 seconds of no input my root Tk gets withdraw()n so there is nothing on screen.
Now, whenever I want to show an image I call this function:
def drawOverlay(self, index):
self.canvas.itemconfig(self.overlayWidget, image=self.overlayImages[index])
self.deiconify()
The problem is that I see the old image for a few milliseconds before it is replaced.
I tried to find out why there is the delay eventhough I deiconify() only after i switched the image and came across this answer which suggested to call deiconify() using the root's after(). I tried that and when it still didn't work I played around with the call and found out that calling
self.after(1000, self.deiconify())
causes the old image to appear for exactly 1 second after which it is replaced with the new one.
This leads me to believe that the Tk or the Canvas is unable to update while it is withdraw()n. Is there any way around this? I'd rather have a short delay before the image is displayed than the old image flashing on the screen for a few frames but I have no idea how to accomplish this.
Edit: So I'm an idiot for actually calling deiconify instead of just passing it to after because of the parantheses.
That does fix the old image appearing for the duration but does not fix the flashing.
Edit2: I managed to reproduce this problem with the following code.
Pressing any key on the keyboard will make a green rectagle appear. Waiting for it to vanish and then pressing another key will make a red rectangle appear.
Only sometimes can you see the flashes happening so try for a couple times. I did not manage to reproduce when -transparentcolor isnt set but I can't tell if this is due to the option being the problem or due to the reduced rendering times making the problem almost imperceptable. It is also a bit easier to see then overrideredirect is set.
Edit3: I have worked the code down further by using actual images. Even without the keypress or additional event callbacks this code produces a black flash before displaing the image. -transparentcolor and overrideredirect(True) seem to be vital to reproducing this. Manually calling update() before reduces the frequency of this ocurring but still causes flashing consistently on larger images. This points to rendering time being one of the factors.
overlay.png
overlayRaw.png
from tkinter import Tk, Canvas
from PIL import ImageTk, Image
TRANSCOLOR = "blue"
IMAGE_SMALL = "overlay.png"
IMAGE_LARGE = "overlayRaw.png"
class Overlay(Tk):
def __init__(self):
Tk.__init__(self)
self.rawImage = Image.open(IMAGE_SMALL)
self.image = ImageTk.PhotoImage(self.rawImage)
self.canvas = Canvas(self, width = self.rawImage.size[0], height = self.rawImage.size[1])
self.canvas.pack()
self.wm_attributes('-transparentcolor', TRANSCOLOR) # If disabled stops the flashes from ocurring even on large images.
self.overrideredirect(True) # If disabled the Windows animation for opening windows plays. Stops the flashing from ocurring
self.withdraw()
self.overlayWidget = self.canvas.create_image(0, 0, image = self.image, anchor = "nw")
self.deiconify() # Flashes Clearly Everytime
## self.update_idletasks()
## self.deiconify() # Only Flashes Sometimes. Always flashes on large images
## self.update()
## self.deiconify() # Only Flashes Sometimes. Always flashes on large images
## self.after(0, self.deiconify) # Flashes Clearly everytime
## self.after(200, self.deiconify) # Only Flashes Sometimes. Always flashes on large images
## self.update()
## self.after(200, self.deiconify) # Flashes Clearly Everytime
o = Overlay()
o.mainloop()
I don't see much that could cause a flicker. My recommendation would be to add an explicit call to self.update before the call to deiconify happens. That should instruct tkinter to redraw everything on the canvas. However, that won't help if tkinter on your platform defers drawing until the window is mapped.
Try replacing this:
self.after(0,self.deiconify)
self.after(2000, self.hideOverlay)
with this:
self.update()
self.deiconify()

How do I stop flickering in my transparent Splash screen in Tkinter?

Using a bit of modified code I found on the web for creating a generic Tkinter splash screen, I tried to to create a transparent splash screen kind of thing with a .png. I know this code will only work with Windows and I am fine with that.
However, I notice there is flickering (Canvas area is black before it draws the picture) with the image when it draws on the screen. I don't know very much about it but I suspect it has to do something with the buffering of the image after googling and reading. I also read that canvas supports double buffering so the flickering shouldn't be happening so maybe it's the Top Level widget or something.
In any case is there any fix to this? I'd really like to continue using Tkinter for this and it would be a huge letdown not to be able to get rid of the flickering. Here is the code I am using below.
from Tkinter import *
import ttk
from PIL import Image, ImageTk
import time
class Splash:
def __init__(self, root, filename, wait):
self.__root = root
#To use .pngs or .jpgs instead of just .bmps and .gifs, PIL is needed
self.__file = ImageTk.PhotoImage(Image.open(filename))
self.__wait = wait + time.clock()
def __enter__(self):
# Hide the root while it is built.
self.__root.withdraw()
# Create components of splash screen.
window = Toplevel(self.__root)
#Set splash window bg to transparent
window.attributes('-transparent', '#FFFFFE')
#Set canvas bg to transparent
canvas = Canvas(window,bg="#FFFFFE")
splash = self.__file
# Get the screen's width and height.
scrW = window.winfo_screenwidth()
scrH = window.winfo_screenheight()
# Get the images's width and height.
imgW = splash.width()
imgH = splash.height()
# Compute positioning for splash screen.
Xpos = (scrW - imgW) // 2
Ypos = (scrH - imgH) // 2
# Configure the window showing the logo.
window.overrideredirect(True)
window.geometry('+{}+{}'.format(Xpos, Ypos))
# Setup canvas on which image is drawn.
canvas.configure(width=imgW, height=imgH, highlightthickness=0)
canvas.pack()
# Show the splash screen on the monitor.
canvas.create_image(imgW // 2, imgH // 2, image=splash)
window.update()
# Save the variables for later cleanup.
self.__window = window
self.__canvas = canvas
self.__splash = splash
def __exit__(self, exc_type, exc_val, exc_tb):
# Ensure that required time has passed.
now = time.clock()
if now < self.__wait:
time.sleep(self.__wait - now)
# Free used resources in reverse order.
del self.__splash
self.__canvas.destroy()
self.__window.destroy()
# Give control back to the root program.
self.__root.update_idletasks()
self.__root.deiconify()
if __name__ == '__main__':
#thread2 = myLazyDoStuffThread()
root = Tk()
with Splash(root,'splash.png',3):
myprog = ApplyGUIAndOtherThings(root)#,thread2)
root.mainloop()
A rule of thumb you should follow is to never put a call to sleep in a GUI. It does exactly what it says, it causes your whole application to sleep. This means that the GUI is not able to redraw itself, and is likely the cause of your flicker.
If you want a window to be destroyed after a period of time, use the after method. For example:
delta = (self.__wait - now) * 1000
self.after(delta, self.close)
You'll need to define self.close to destroy the window.
This gives you an opportunity to add a little "fade away" effect if you like. You do this by checking to see if the alpha of the splash screen is below some threshold (say, 10%) and destroy it. If it's not, reduce the alpha by 10% and call the function again in 100 ms.

Python imaging, resize Turtle Graphics window

My image is too large for the turtle window. I had to enlarge the image because the text I need at each spot overlaps.
How do I Resize the window in python?
It sounds like you have drawn an image, but it has gone outside the borders of the window, so therefore you need to make the window larger to see the entire image.
To resize the window:
setup( width = 200, height = 200, startx = None, starty = None)
This will make your output window 200X200 (which may be too small for you so you'll need to make those numbers larger.)
Here is the URL where I found this information.
TurtleDocs

Categories