I am writing a GUI to display images (essentially a slideshow). I would like to add a scroll bar so the user can cycle through multiple images at a faster rate then clicking a button. An example of what I would like is below.
Currently, I have implemented the scale widget which when moved with cycle through every 25 images. However, this only works in one direction. Is there a way to bind the scale widget with two commands, one to go forward and backwards? I already have left and right arrow buttons that will cycle through images one by one, but it does not "sync" with the scale widget.
scale = tk.Scale(master=self.root
, orient=tk.HORIZONTAL, from_=self.imgIndex + 1, to=int(len(self.img_lst)), resolution=25,
length=250, width =25,
showvalue=False, command=self.next_25)
# scale.pack(side=BOTTOM, fill=X)
scale.place(x=550,y=650, anchor=tk.CENTER)
Any help/ideas would be greatly appreciated.
Related
What is the point of setting a size for a frame on Tkinter, if it will resize every time I add a new widget.
`
frame1 = Frame(self.MainWindow,width=600,height=100,bg='Blue')
frame1.grid(row=0,column=0)
#frame1.pack()
#Title
self.mainTitle = Label(frame1,text='Welcome')
self.mainTitle.grid(row=0,column=1,padx=60,pady=5)
#Back button
backButton = Button(frame1,text='Home',command=None)
backButton.grid(row=0,column=0,padx=60,pady=5)
nexButton = Button(frame1,text='Next',command=None)
nexButton.grid(row=0,column=2,padx=60,pady=5)
`
I do not know if there is any way to work with frames like divs in html.
What is the point of setting a size for a frame on Tkinter, if it will resize every time I add a new widget.
The vast majority of the time there is no advantage for setting a size on a frame. It can be useful in those cases when you have very strict requirements, but more often than not it's better to let tkinter size frames for you. It's very good at making responsive GUIs when you let it do all of the work of calculating sizes.
In Tkinter, resizing a canvas and/or frame can be done using
canvas.pack(fill="both", expand=True)
This way I can drag the tkinter window with the mouse and the canvas and frames within will adapt to the new size.
However I have not found a solution for applying this to images within the canvas. Only solutions so far are to independently change the size of the images through event actions.
Is there any way to make images within a canvas to resize dynamically, just like the canvas does with the one-liner above?
Is there any way to make images within a canvas to resize dynamically, just like the canvas does with the one-liner above?
No, there is no way to do what you want. Images aren't like widgets which can automatically grow and shrink. You will need to set up a binding on the <Configure> event of the containing widget, and in the bound function you will have to convert the image to the desired size.
I'm creating an instrument panel in Tkinter (Python 3.7) and have been attempting to place an image on top of other widgets to augment their appearance. The problem is, every time I place an image it ends up in the background. Ideally I would like to put an image with transparency over all the widgets in my panel, but I would settle for simply being able to put non-transparent images over parts of my display.
I've been using place() to position my widgets since I never want the widgets to move and only need it to work for a specific screen resolution.
So far I've tried using the PIL package and tried placing the image inside a label and a canvas, but both seem to have the same result. Even if I place my widgets inside the canvas with the image, the widgets will show up in front.
Here's a simple example:
import tkinter as tk
import PIL.Image
import PIL.ImageTk
root = tk.Tk()
image = PIL.Image.open('esis/decals_green.gif')
photo = PIL.ImageTk.PhotoImage(image)
label = tk.Label(root, image=photo)
label.image = photo #keep reference
sampleWidget = tk.Button(root, text='Test')
sampleWidget.place(x=0, y=0, height=100, width=100)
label.place(x=0, y=0, height=200, width=200)
root.mainloop()
Even though I'm placing the image label last, it shows up underneath the button.
When tkinter widgets overlap, tkinter will use the stacking order (sometimes referred to as a z-index) to determine which widget overlays the other.
The stacking order defaults to the order in which the widgets are created (widgets created earlier are lower in the order than widgets created later). You can change this ordering with the lower and lift methods. Because you created the button widget last, it will have a higher place in the stacking order and thus it will appear on top of the image.
If you wait to create the label with the image until after all of the other widgets have been created, it will be highest in the stacking order and thus appear on top of all other widgets. You could also leave the code as-is and add label.lift() near the end of the code to raise it to the top of the stacking order.
What is the primary difference between these two functions?
I'm currently working on a program that contains a canvas and a label, the latter is behaving as a button. Now the canvas was placed using .pack() while I used .place() for the label. Additionally the program reads and uses the location of mouse clicks to perform certain actions.
There is currently a bug that causes the program to trigger an unexpected action upon clicking the label, to my surprise upon clicking the label the x and y coordinate of the mouse click are not in reference to the window (as I expected it to be) but rather to the top-left coordinates of the label.
Is there a way to set it so that the label does not modify the x and y coordinate of the mouse click within it?
I'm relatively new to python and this is the first projects I've made using tkinter. If needed I can provide the code upon request.
EDIT: Entire program can be found here. Labels are added starting at line 87:
newgame_Label = Label(parent, anchor=NW, font="Calibri",
text="New Game")
newgame_Label.bind("<Button 1>", self.newgame_Click)
newgame_Label.place(x=450, y=300)
reset_Label = Label(parent, anchor=NW, font="Calibri",
text="Reset Board")
reset_Label.bind("<Button 1>", self.reset_Click)
reset_Label.place(x=450, y=400)
The function initBoard calls the .pack() method on the canvas. The program is a clone of Light's Out, thought it would be a good way of learning python and tkinter.
Alternately I can just not use a label and simply use the create_text method available to a canvas widget, but this would require some workaround to determine if it has been clicked. Mostly interested in finding out why is it that .place() for a Label Widget behaves the way it does event though they share the same frame.
The primary difference is that place lets you specify absolute coordinates, and pack uses a box model which allows you to place widgets along the sides of the box.
place is not used that often in real world applications. It's great for a very small class of problems, but pack and grid are more useful. Place requires that you spend a lot more effort making the GUI resize properly.
You can use pack() and place() together :
r = Tk()
label = Label(r, text = any text)
label.pack()
label.place(x = x, y = y)
Remember !
You must use pack before place
I have a simple pygtk/glade window with a menu and a 3x3 grid. Each row of the grid consists on: two labels and a button.
When the Window is resized, the labels holds the same font size, but the buttons get resized, and they could become HUGE if the windows gets very big.
How could I manage to keep my buttons with the same size always (the "standar" size of a button, just like they are when the interface is just opened) no matter if the Window is resized?
You just have to set the fill and expand parameters of the Buttons to False (uncheck them in the Glade interface).
You would also want to put each button at the center of a 3x3 GtkTable, so it will appear centered and not aligned at the top of the cell