Is there a way to use tkinter's Tk() frame with a canvas in a way that it covers the entire screen but doesnt get bigger than the screen.
I mean it shall be similar to fullscreen.
If this is a part of my code:
class X:
def __init__(self):
self.tk = Tk()
self.canvas = Canvas(self.tk, width=500, height=500, highlightthickness=0)
self.canvas.pack()
How would I achieve this? I think it is something with:
self.canvas.attributes(width=x)
Also: How would I now how big the canvas currently is (considering I don't save it in a variable)? Is there some kind of method or attribute of Canvas I could access?
edit the self.canvas.pack() to self.canvas.pack(fill='both', expand=True)
then the canvas will fill the entire window.
Related
I was trying to add a files view in my text editor. Is there any way to resize tkinter frame by either x-axis or y-axis?
example:
like this resizing the files view.
Is there any way to do the same in a tkinter frame?
If you mean, you want a splitter widget, you can make use of PanedWindow.
Here is a minimal example:
import tkinter as tk
root = tk.Tk()
splitter = tk.PanedWindow(root, handlesize=2, orient=tk.HORIZONTAL)
splitter.pack(fill='both', expand=True)
leftFrame = tk.Frame(splitter, bg='red')
rightFrame = tk.Frame(splitter, bg='blue')
splitter.add(leftFrame, width=100)
splitter.add(rightFrame)
root.mainloop()
you can now expand the frame by using the handle.
I've had this problem before and I solved it here, the thing is that for another program I used the same method canvas.create_image() and I couldn't see my image. My idea is, that the garbage collector destroy it before I see it on my canvas, but I don't know how to stop this. I saw this, but I didn't know how to apply to my program.
But if I write canvas.create_rectangle(50, 50, 70, 70), I works very well, so I don't understand. I also tried to add my image to a Label instead of putting it in my canvas, and I had the same problem of seeing anything. But I've never got an execution error.
this is my code :
from tkinter import *
root = Tk()
canvas = Canvas(root, bg="yellow")
dino = canvas.create_image(600, 200, image=PhotoImage(file='running_1.png'))
canvas.pack(fill="both", expand=True)
root.mainloop()
Try this -
from tkinter import *
root = Tk()
canvas = Canvas(root, bg="yellow")
running =PhotoImage(file='running_1.png')
dino = canvas.create_image(600, 200, image=running)
canvas.pack(fill="both", expand=True)
root.mainloop()
Your code doesn't work because you are referencing the PhotoImage inside the canvas.create_image. You should assign a variable for it and then use image=variable
I am currently trying to make a scrollable list of entries using tkinter in Python 3. While looking for some documentation, I found this: Adding a scrollbar to a group of widgets in Tkinter. It is really great and works really fine with Labels, but it doesn't seem to work with Entries. You'll find right here my code which creates a 2x25 list of entries through which I would like to be able to scroll:
import tkinter as tk
class MainPage(tk.Frame):
def __init__(self, racine):
super().__init__(master=racine)
self.grid()
self.entriesCanvas = tk.Canvas(self, borderwidth=0, background="white")
self.entriesFrame = tk.Frame(self.entriesCanvas, background="white")
self.scrollbar = tk.Scrollbar(self, command=self.entriesCanvas.yview)
self.entriesCanvas.configure(yscrollcommand=self.scrollbar.set)
self.entriesCanvas.grid(column=0, row=2, columnspan=2)
self.scrollbar.grid(column=3, row=2, sticky='ns')
# self.entriesFrame.grid()
self.entriesCanvas.create_window((0, 0), window=self.entriesFrame,
anchor='nw', tags='self.entriesFrame')
# self.entriesFrame.grid()
self.entriesCanvas.bind('<Configure>', self.onFrameConfigure)
self.entries = []
for i in range(50):
self.entries.append(tk.Entry(self.entriesFrame, font=('arial', 30)))
self.entries[i].grid(column=i % 2, row=i//2)
def onFrameConfigure(self, event):
self.entriesCanvas.configure(scrollregion=self.entriesCanvas.bbox("all"))
if __name__ == "__main__":
root = tk.Tk()
mainPage = MainPage(root)
root.mainloop()
Notice I commented two lines out. If you "activate" the first line, there will be a scrollbar and one can scroll through the entries, but it is strangely zoomed. On the other hand, if you "activate" the second line, the GUI will be as I would like it to be, but without the possibility to scroll, and it seems to show all entries (even if there are 1000 entries, therefore making a window which is 20 times the size of your screen).
Do you know where my mistake is?
Okay, so I found a way to have my program doing what I want. I just changed the method
def onFrameConfigure(self, event):
self.entriesCanvas.configure(scrollregion=self.entriesCanvas.bbox("all"))
by
def onFrameConfigure(self, event):
self.entriesCanvas.configure(scrollregion=self.entriesCanvas.bbox("all"), width=self.entriesFrame.winfo_width())
(I basically only added a parameter to ask the canvas to be the width of the frame.)
I don't know if it is perfect (as I still use .grid() istead of .pack()), but it works.
Thank you for giving me the source Tkinter: How to get frame in canvas window to expand to the size of the canvas?, it really helped me find where my mistake was.
I truely apologise for my English, I know I make a lot of mistakes.
I have a piece of tkinter code running on python 3.4 that is a large frame placed in a canvas with a vertical scrollbar, however the scrollbar is grayed out and doesn't seem to be linked to the size of the frame. The code I'm using is essentially:
class EntryWindow:
def __init__(self, master):
self.master = master
self.master.minsize(750, 800)
self.master.maxsize(1000, 800)
self.canvas = tk.Canvas(self.master, borderwidth=0, bg='#ffffff')
self.vsb = tk.Scrollbar(self.master)
self.master_frame = tk.Frame(self.canvas)
self.vsb.pack(side="right", fill='y')
self.canvas.pack(side='left', fill='both', expand=True)
self.canvas.create_window((0,0), window=self.master_frame, anchor='nw', tags='self.master_frame')
self.canvas.config(yscrollcommand=self.vsb.set)
self.master_frame.grid()
###build widgets and place into master_frame
...
The master_frame is filled with about 36 widgets placed using the grid geometry manager and reaches a vertical height of about 2000 pixels, but the scrollbar doesn't work.
I saw a post about using ttk scrollbar, but when I imported that I couldn't get it to work. The input statement I used was:
import tkinter as tk
import tkinter.ttk as ttk
and then replaced the line self.vsb = tk.Scrollbar(self.master) with self.vsb = ttk.Scrollbar(self.master) but that didn't fix it either. I also tried removing the min/max sizing on master (those aren't the final values, I've been playing with it).
Is there something I'm doing wrong? I feel like it might be in the line where I set the canvas.config() but I read the documentation and it seems to be right. Tomorrow I plan on trying to load the frame into the canvas after I've built the frame.
But in the meantime, and in case that doesn't work, any help would be great! Thanks!
You must do three things when configuring a scrolling canvas:
have the canvas notify the scrollbar when it scrolls, by configuring the yscrollcommand attribute of the canvas to point to the scrollbar
have the scrollbar control the canvas when it is dragged, by configuring the command attribute of the scrollbar
tell the canvas what part of the virtual canvas should be scrollable by configuring the scrollregion attribute of the canvas
You are neglecting to do #3. After adding the widgets to master_frame you should do this:
self.canvas.configure(scrollregion=self.canvas.bbox("all")
The above will tell the canvas and scrollbar that the area of the canvas that is scrollable is the area that encompasses all of the objects on the canvas.
Finally, you need to remove the following line of code, because you are already adding the frame to the canvas with create_window. Frames added to a canvas with pack, place or grid won't scroll:
# remove this line
self.master_frame.grid()
For a working example of a scrollable frame, see Adding a scrollbar to a group of widgets in Tkinter
With this code, the window is 500 by 500, which is what I'm going for:
from tkinter import *
root = Tk()
frame = Frame(root, width=500, height=500)
frame.pack()
root.mainloop()
When I add a text box to the frame, though, it shrinks to just the size of the text box:
from tkinter import *
root = Tk()
frame = Frame(root, width=500, height=500)
text = Text(frame, width=10, height=2) # THESE TWO
text.pack() # LINES HERE
frame.pack()
root.mainloop()
Why does this happen, and how can I prevent it from happening?
The frame by default has "pack propagation" turned on. That means the packer "computes how large a master must be to just exactly meet the needs of its slaves, and it sets the requested width and height of the master to these dimensions" (quoting from the official tcl/tk man pages [1]).
For the vast majority of cases this is the exact right behavior. For the times that you don't want this you can call pack_propagate on the master and set the value to false. I think in close to 20 years of tk programing I've only needed to do this a half dozen times or so, if that.
Another choice you have is to use wm_geometry to set the size of the toplevel after you've created all the widgets. This does effectively the same thing as if the user had manually resized the window. This only works for toplevel windows though, you can't use wm_geometry on a frame.