How to fix to the left a button in tkinter with columnspan - python

Description
What I'm trying to do is an app with a navbar on top that depending on which one is shows different things on the body of the app (below the navbar). I'm using the grid so I'm iterating through a list and adding a button to the body of the app and they have columnspan but they position in the middle of the columnspan
This is how it looks right now.
Desired Layout
This is a little sketch of the layout (the right bar below the navbar is a scrollbar which isn't implemented yet because I don't know yet how to do it)
Code
import modules.configManager as configManager
import tkinter as tk
from tkinter import messagebox
import tkinter.font as font
from os.path import dirname, abspath
from PIL import Image, ImageTk
imgDirectory = dirname(dirname(abspath(__file__))) + '\img'
logo = imgDirectory + '\logo2.jpg'
root = tk.Tk()
def linkMenu():
links = configManager.readConfig()['linksList']
i = 0
for link in links:
i = i+1
linkB = tk.Button(root,text=link['link'],font=font.Font(font='Helvetica',size=8),width=30,relief='flat')
linkB.grid(column=0,row=i,columnspan=4)
def navbar():
buttonWidth = 18
buttonHeight = 1
myfont = font.Font(font='Helvetica',size=10,weight="bold")
homeButton = tk.Button(root, text="Home",height=buttonHeight,width=buttonWidth,font=myfont)
homeButton.grid(column=0,row=0)
linkButton = tk.Button(root, text="Links",width=buttonWidth,font=myfont,command=linkMenu)
linkButton.grid(column=1,row=0)
groupsButton = tk.Button(root, text="Groups",width=buttonWidth,font=myfont)
groupsButton.grid(column=2,row=0)
resetButton = tk.Button(root, text="Reset",width=buttonWidth,font=myfont)
resetButton.grid(column=3,row=0)
exitButton = tk.Button(root,text="Exit",width=buttonWidth,font=myfont,command=exit)
exitButton.grid(column=4,row=0)
def interface():
navbar()
root.title("LinkManager")
root.geometry("1040x500")
root.mainloop()
Thanks in advance and if it isn't clear tell me please :D

Related

TkinterVideoPlayer stops resizing the video when it's put inside a frame. How can I stop this?

I'm trying to make a video player that play's a video full screen. The user is also able to toggle onto another frame that I want to take up the full GUI and to be able to toggle in between them.. I have written some code and It works fine when I pack the video player to root but then when I put it inside a frame it shrinks down to a much smaller size than the GUI. Why is this happening and how can I fix it?
This is the code that has the video playing and resizing to the GUI size dynamically
import datetime
import tkinter as tk
from tkinter import *
from turtle import width
from tkVideoPlayer import TkinterVideo
#changing the visible frame on the screen
def showFrame (frame):
frame.tkraise()
root = tk.Tk()
root.title("Hology")
width1, height1= int(root.winfo_screenwidth()), int(root.winfo_screenheight())
root.geometry(str(width1-200) + "x" + str(height1-200))
vid_player = TkinterVideo(master=root, scaled=True)
# vid_player.set_size((width1-200, height1-200))
vid_player.pack(expand=True, fill=BOTH)
progress_value = tk.IntVar(root)
vid_player.bind("<<SecondChanged>>", loopVid)
load_file= "hol.mp4"
vid_player.load(load_file)
vid_player.play()
# vid_player.pack(expand=True, fill="both")
holo.tkraise()
root.mainloop()
This is where it is placed inside a frame
import datetime
import tkinter as tk
from tkinter import *
from turtle import width
from tkVideoPlayer import TkinterVideo
global vidVal
vidVal = 0
#changing the visible frame on the screen
def showFrame (frame):
frame.tkraise()
root = tk.Tk()
root.title("Hology")
width1, height1= int(root.winfo_screenwidth()), int(root.winfo_screenheight())
root.geometry(str(width1-200) + "x" + str(height1-200))
holo = Frame(root)
timeline = Frame(root)
holo.grid(row=0,column=0)
timeline.grid(row=0,column=0)
# root.attributes('-fullscreen',True)
# for frame in (holo, timeline):
# frame.master.geometry(str(width1-200) + "x" + str(height1-200))
# # frame.grid(row=1, column=1, columnspan=10, rowspan=8, sticky=tk.EW)
# # frame.pack_propagate(False)
# frame.pack()
vid_player = TkinterVideo(master=holo, scaled=True)
# vid_player.set_size((width1-200, height1-200))
vid_player.pack(expand=True, fill=BOTH)
load_file= "hol.mp4"
vid_player.load(load_file)
vid_player.play()
# vid_player.pack(expand=True, fill="both")
holo.tkraise()
root.mainloop()
Any help enabling me to keep the video at full size when inside a frame would be greatly appreciated. I have spent some time looking through the documentation and I know it will be a simple fix or something silly, I'm just stuck! :(
Thank you

Frame in Tkinter Popup Putting Content into Main Window instead of Popup

I am trying to create an app using the Tkinter Python library, and I created a preferences popup. I want to add checkboxes to it, and I want to do it in Frames via pack().
I want something like this:
Expected Result (IK it's Edited but Proof of Concept)
This is what I'm getting:
Actual Result (Look at Bottom of Image)
This is what I wrote:
# Import Libraries
from tkinter import *
from tkinter import ttk
from tkinter import simpledialog, messagebox
from tkinter.filedialog import asksaveasfile
from pygame import mixer as playsound
from datetime import datetime as date
from time import sleep
import pyttsx3
import json
import os
# Set Initial Window
window = Tk()
window.title("TTSApp")
window.geometry('500x580')
window.resizable(width=False,height=False)
playsound.init()
# Settings and Menu
preferences = {}
def preferencesHandler():
if os.path.exists('preferences.pref'):
preferences = {'AutoSave':True,'AutoSavePrompt':True,'AutoSaveAutomaticLoad':False}
with open('preferences.pref', 'w') as pref:
json.dump(preferences, pref)
else:
preferences = json.load(open('preferences.pref', 'r'))
pref.close()
sessionOptions = {'SessionName':'Untitled','VoiceSpeed':100}
def topmenucommands_file_newsession():
messagebox.showerror("New Session", "I haven't done this yet... you shouldn't even be able to see this...")
def topmenucommands_file_preferences():
preferencesWin = Toplevel(window)
preferencesWin.geometry("350x500")
preferencesWin.title("Preferences")
preferences_autosave = BooleanVar()
preferences_autosaveprompt = BooleanVar()
preferences_autosaveautomaticload = BooleanVar()
def topmenucommands_file_preferences_changed(*args):
with open('preferences.pref') as pref:
preferences['AutoSave'] = preferences_autosave.get()
preferences['AutoSavePrompt'] = preferences_autosaveprompt.get()
preferences['AutoSaveAutomaticLoad'] = preferences_autosaveautomaticload.get()
json.dump(preferences, pref)
pref.close()
Label(preferencesWin, text="Preferences", font=('helvetica', 24, 'bold')).pack()
autosave_container = Frame(preferencesWin,width=350).pack()
Label(autosave_container, text="Create Autosaves:", font=('helvetica', 12, 'bold')).pack(side=LEFT)
ttk.Checkbutton(autosave_container,command=topmenucommands_file_preferences_changed,variable=preferences_autosave,onvalue=True,offvalue=False).pack(side=RIGHT)
window.wait_window(preferencesWin)
pref.close()
def topmenucommands_session_renamesession():
topmenucommands_session_renamesession_value = simpledialog.askstring(title="Rename Session",prompt="New Session Name:")
sessionOptions['SessionName'] = topmenucommands_session_renamesession_value
topmenu = Menu(window)
topmenu_file = Menu(topmenu, tearoff=0)
#topmenu_file.add_command(label="New Session")
#topmenu_file.add_command(label="Save Session")
#topmenu_file.add_command(label="Save Session As...")
topmenu_file.add_command(label="Preferences", command=topmenucommands_file_preferences)
topmenu.add_cascade(label="File", menu=topmenu_file)
topmenu_session = Menu(topmenu, tearoff=0)
topmenu_session.add_command(label="Rename Session", command=topmenucommands_session_renamesession)
topmenu.add_cascade(label="Session", menu=topmenu_session)
# Create All of the Widgets and Buttons and Kiknacks and Whatnot
# Input Window
inputText = Text(window,height=20,width=62)
inputText.pack()
# Label for Speed Slider
speedText = Label(window, text='Voice Speed', fg='black', font=('helvetica', 8, 'bold'))
speedText.pack()
# Speed Slider
speed = Scale(window, from_=50, to=200, length=250, tickinterval=25, orient=HORIZONTAL, command=speedslidersavestate)
speed.set(100)
speed.pack()
# Dropdown for Voice Selection
voice = OptionMenu(window, voiceSelection, *voiceNames.keys())
voice.pack()
# Warning/Notice Label
warning = Label(window, text='', fg='red', font=('helvetica', 12, 'bold'))
warning.pack()
# Container for All Preview and Save (and PreviewRaw)
buttons = Frame(window)
buttons.pack()
# PreviewRaw Button; Huh... There's Nothing Here
# Preview Button
preview = Button(buttons,text='Preview',height=5,width=25,command=preview)
preview.pack(side=LEFT)
# Save Button
save = Button(buttons,text='Save to File',height=5,width=25,command=save)
save.pack(side=RIGHT)
window.config(menu=topmenu)
preferencesHandler()
window.mainloop()
Did I do something wrong or is there a better way to go about this or is this question a mess (this is my first time doing this)? Also, I clipped out all of the unnecessary content.
Edit: Added More Code
I figured it out. Apparently, I needed to pack() the Frame separately.
The answer was:
autosave_container = Frame(preferencesWin,width=350)
autosave_container.pack()
Instead of:
autosave_container = Frame(preferencesWin,width=350).pack()

How to expand entry box with window in tkinter?

I'm just creating simple window using tkinter which have entry box and search button. What is want is when i maximize window search bar also starch but it is not happening,
Here is my code
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry("500x500")
root.title("Wikipedia")
class first:
def labels(self):
search_frame = ttk.LabelFrame(root)
search_frame.pack(side = "top",fill = "both")
search_var = tk.StringVar()
search_bar = tk.Entry(search_frame,width = 40,textvariable = search_var)
search_bar.grid(row = 0,column = 0)
search_button = ttk.Button(search_frame,text = "Search")
search_button.grid(row = 1,column = 0)
boot = first()
boot.labels()
root.mainloop()
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry("500x500")
root.title("Wikipedia")
class first:
def labels(self):
search_frame = ttk.LabelFrame(root)
search_frame.pack(side="top", fill="both")
search_var = tk.StringVar()
search_bar = tk.Entry(search_frame, width=20, textvariable=search_var)
search_bar.pack(fill="x")
search_button = ttk.Button(search_frame, text="Search")
search_button.pack()
boot = first()
boot.labels()
root.mainloop()
Not sure this is what you're looking for but try it out.
Here I have used fill='x' in the .pack() geometry manager to fill the row

Tkinter and PIL error

I am trying to get a .gif animation to work next to a picture with buttons on it. but i seem to be having a issue, I am importing these modules
"import Tkinter" and "from PIL import Image, ImageTk, ImageSequence"
But, as soon as I make "import Tkinter"---"from Tkinter import *"
It says Tkinter is not defined, I have searched.. and searched.... and I cannot for the death of me find a solution.
I have to use "from Tkinter import *" because I don't know where to find the spesifics for a substetute for " * " I also need to use "Label", "bg" and "relief"
here is my code:
import Tkinter
from PIL import Image, ImageTk, ImageSequence
class App:
def __init__(self, parent):
self.parent = parent
self.canvas = Tkinter.Canvas(parent, width = 400, height = 500)
self.canvas.pack()
self.sequence = [ImageTk.PhotoImage(img)
for img in ImageSequence.Iterator(
Image.open(
r'C:\Users\Damian\Pictures\Gif folder\Originals\Bunnychan.gif'))]
self.image = self.canvas.create_image(200,200, image=self.sequence[0])
self.animating = True
self.animate(0)
def animate(self, counter):
self.canvas.itemconfig(self.image, image=self.sequence[counter])
if not self.animating:
return
self.parent.after(33, lambda: self.animate((counter+2) % len(self.sequence)))
root = Tkinter.Tk()
root.title('App')
app = App(root)
root.mainloop()
I have another piece that I am going to merge with this code:
import webbrowser
from Tkinter import *
from PIL import ImageTk,Image
Url1 = 'https://www.nedbank.co.za'
Url2 = 'https://www.facebook.com'
def openUrl1():
webbrowser.open(Url1, 2)
def openUrl2():
webbrowser.open(Url2, 2)
root = Tk()
root.title('App')
root.minsize(width = 400, height = 400)
root.maxsize(width = 400, height = 400)
image = Image.open("C:\\Users\\Damian\\Pictures\\Lores.png")
photo = ImageTk.PhotoImage(image)
label = Label(image = photo)
label.image = photo
label.place(x = 0, y = 0)
color1 = 'white'
button1 = Button(
text = color1,
bg = color1,
relief = "raised",
width = 220,
height = 85,
command = openUrl1
)
Original = Image.open("C:\\Users\\Damian\\Pictures\\NedbankLogoNew.png")
im_pm = ImageTk.PhotoImage(Original)
button1.config(image = im_pm)
button1.place(x = 0, y = 0)
root.mainloop()
The recommended way to import tkinter is this:
import Tkinter as tk
Once you do that, you use tkinter as you normally would, but you need to prepend tk. to all of the widgets and constants. You can do import Tkinter, of course, but that means you have to prefix everything with Tkinter. which is a bit too wordy IMO.
For example:
import Tkinter as tk
root = tk.Tk()
label = tk.Label(root, relief=tk.RAISED)
...
Personally I don't recommend using the constants. You can just use a string (eg: relief="raised", sticky="nsew", etc.), which gives exactly the same results.

Tkinter Image icon not working or aligning properly in a Labelframe

This question concerns Python's Tkinter.
I first produced this GUI, a simple two-column set of rows in a Labelframe, with an icon on the right:
The above behaviour was correct and expected, based on this following code:
import tkinter as tk
import tkinter.ttk as ttk
from PIL import Image, ImageTk
root = tk.Tk()
icon_colours_fp = r"D:\Dropbox\coding\python\experiments\icon_component.gif"
icon_col = tk.PhotoImage(file=icon_colours_fp)
# icon_col = ImageTk.PhotoImage(Image.open(icon_colours_fp))
tk.Label(root, text="Past").grid(row=0, column=0)
tk.Label(root, text="Today").grid(row=1, column=0)
tk.Label(root, text="Future").grid(row=2, column=0)
_b = ttk.Button(root, image=icon_col)
_b['image'] =icon_col
_b.grid(row=0, column=1)
root.mainloop()
I then re-wrote the code as a class, hoping to produce something similar within a Labelframe:
import tkinter as tk
import tkinter.ttk as ttk
from PIL import Image, ImageTk
class Options(tk.Frame):
def __init__(self, parent):
super().__init__()
main_labelframe = ttk.LabelFrame(parent, text="Test Labelframe")
main_labelframe.pack(fill=tk.BOTH, expand=1)
frame_1 = tk.Frame(main_labelframe)
frame_1_sep = ttk.Separator(main_labelframe, orient=tk.VERTICAL)
frame_2 = tk.Frame(main_labelframe)
frame_1.pack(side=tk.LEFT)
frame_1_sep.pack(side=tk.LEFT, fill=tk.BOTH)
frame_2.pack(side=tk.LEFT)
tk.Label(frame_1, text="Past").grid(row=0, column=0)
tk.Label(frame_1, text="Today").grid(row=1)
tk.Label(frame_1, text="Future").grid(row=2)
icon_colours_fp = r"D:\Dropbox\coding\python\experiments\icon_component.gif"
icon_col = tk.PhotoImage(file=icon_colours_fp)
_b = ttk.Button(frame_2, image=icon_col)
_b['image'] = icon_col
_b.grid(row=0, column=0)
class Gui(tk.Tk):
def __init__(self):
super().__init__()
options = Options(self)
options.pack()
gui = Gui()
gui.mainloop()
The code then failed, in two respects:
The icon fails to appear.
The ttk Button becomes misaligned. (It appears in the centre, whereas by the grid, it should appear at the top.)
The failed code appears as follows:
I have experimented: among others, I changed the geometry manager to .pack(), and changed the parent of ttk.Button, but without success. Would appreciate some pointers as to where I've gone wrong, especially as to the disappearing icon.
You didn't keep a reference to the image. Easiest way here is to change:
icon_col = tk.PhotoImage(file=icon_colours_fp)
b = ttk.Button(frame_2, image=icon_col)
_b['image'] = icon_col
To:
self.icon_col = tk.PhotoImage(file=icon_colours_fp)
b = ttk.Button(frame_2, image=self.icon_col)

Categories