I am working on a python tkinter desktop applicaiton. I need a scrollbar on the right side of the frame with a vertical orientation. I am trying to display a ttk scrollbar but it does not seem to display properly. My table disappears and the height of the scrollbar is not correct either. Also, if possible, the scrollbar needs to appear only when the TreeView overflows and when it doesnt overflow, then the scrollbar should not be displayed.
import tkinter
from turtle import color, width
import win32com.client
import sys
import subprocess
import time
from tkinter import*
from tkinter import ttk
from tkinter import messagebox
class TestingGui():
def __init__(self):
print("testing")
def registerUser(self):
userName = "tim"
userAge = "36"
userGender = "male"
userPosition = "softeware engineer"
userInfo = [userName.upper(),userAge,userGender,userPosition]
tree.column(0,anchor='center')
tree.column(1,anchor='center')
tree.column(2,anchor='center')
tree.column(3,anchor='center')
tree.insert('',0,values=userInfo)
if __name__ == '__main__':
window = Tk()
window.title('Dashboard')
window.geometry('925x500+300+200')
window.configure(bg="#fff")
window.resizable(False,False)
################### Frame (Top)[start] #####################################
frameTop = Frame(window,width=860,height=60,bg='white')
frameTop.place(x=40,y=40)
uploadExcelBtn = Button(frameTop,width=19,pady=7,text='Upload Excel',bg='#787c82',fg='white',cursor='hand2',border=0).place(x=715,y=13)
excelFileInputField = Entry(frameTop,width=58,fg='black',border=1,bg='white',font=('Microsoft YaHei UI Light',15,'bold'))
excelFileInputField.place(x=8,y=14)
################### Frame (Top)[end] #######################################
################### Table (Center)[start] #####################################
columns = ('name','age','gender','position')
frameCenter = Frame(window,width=860,height=315,bg='#f0f0f1')
frameCenter.place(x=40,y=110)
treeScroll = ttk.Scrollbar(frameCenter,orient="vertical")
treeScroll.pack(side=RIGHT,fill="y")
tree = ttk.Treeview(frameCenter,height=13,columns=columns,show="headings",selectmode='browse',yscrollcommand=treeScroll.set)
tree.heading('name',text='Name')
tree.heading('age',text='Age')
tree.heading('gender',text='Gender')
tree.heading('position',text='Position')
tree.place(x=30,y=10)
treeScroll.config(command=tree.yview)
################### Table (Center)[end] #######################################
################### Frame (Bottom)[start] #####################################
frameBottom = Frame(window,width=860,height=60,bg='white')
frameBottom.place(x=40,y=430)
addUserBtn = Button(frameBottom,width=19,pady=7,text='Add User',bg='#57a1f8',fg='white',cursor='hand2',border=0,command= lambda : TestingGui().registerUser()).place(x=30,y=15)
################### Frame (Bottom)[end] #######################################
mainloop()
The use of place can be tricky that's why you should use it only if other geometrymanager fail to achieve what you want. The benefit of the other two geometrymanagers by tkinter is that they calculate cells or parcels for you that you can use and easily recognize by just look at your layout.
I took the time to change your script and placed comments next to changed lines, that should explain what and why I think those changes are necessary.
#import only what you need and avoid wildcard imports due naming conflicts
import tkinter as tk #as tk as short for tkinter
from tkinter import ttk
class TestingGui():
def __init__(self):
print("testing")
def registerUser(self):
userName = "tim"
userAge = "36"
userGender = "male"
userPosition = "softeware engineer"
userInfo = [userName.upper(),userAge,userGender,userPosition]
tree.column(0,anchor='center')
tree.column(1,anchor='center')
tree.column(2,anchor='center')
tree.column(3,anchor='center')
tree.insert('',0,values=userInfo)
if __name__ == '__main__':
window = tk.Tk()
## bonus: leading tk. symbols you are using tk
window.title('Dashboard')
window.geometry('925x500+300+200')
window.configure(bg="#fff")
window.resizable(False,False)
#Window Content
topframe = tk.Frame(window,width=860,height=60,bg='white')
centerframe = tk.Frame(window,width=860,height=315,bg='#f0f0f1')
bottomframe = tk.Frame(window,width=860,height=60,bg='white')
topframe.pack(side=tk.TOP, padx=(40,0),pady=(40,0),fill=tk.X)
centerframe.pack(side = tk.TOP, fill= tk.BOTH, padx=(40,0))
bottomframe.pack(side=tk.BOTTOM, padx=(40,0), fill= tk.X)
## fill = stretch in master
## padx/y are offsets like x/y in place but using their parcels
## keeping content together helps for an overview of content
#frameTop Content
input_field = tk.Entry(
topframe, width=58, fg='black', border=1, bg='white',
font=('Microsoft YaHei UI Light',15,'bold'))
input_field.pack(side=tk.LEFT)
upload_button = tk.Button(
topframe, width=19, pady=7, text='Upload Excel',
bg='#787c82',fg='white',cursor='hand2',border=0)
upload_button.pack(side=tk.TOP)
## seperate the constructor from the geometry method to keep a reference
## split lines for readability compare PEP-8 Style Guide
## dont use camelcase variable names compare PEP-8 Style Guide
## the order of packing matters in this geometry manager
#centerframe Content
treeScroll = ttk.Scrollbar(centerframe,orient="vertical")
treeScroll.pack(side=tk.RIGHT,fill="y")
#tk.RIGHT = tkinter constant
columns = ('name','age','gender','position')
tree = ttk.Treeview(
centerframe, height=13, columns=columns,
show="headings",selectmode='browse',yscrollcommand=treeScroll.set)
tree.heading('name',text='Name')
tree.heading('age',text='Age')
tree.heading('gender',text='Gender')
tree.heading('position',text='Position')
tree.pack(side=tk.TOP, padx=(30,0),pady=10)
treeScroll.config(command=tree.yview)
#bottomframe Content
add_user_button = tk.Button(
bottomframe, width=19, pady=7,text='Add User',
bg='#57a1f8',fg='white',cursor='hand2', border=0)
#command= lambda : TestingGui().registerUser())#DONT DO THIS!
## Only use lambda if needed
## It makes little to no sense to initiate a class in a lambda expression
add_user_button.pack(padx=(30,0),side=tk.LEFT)
#start mainloop
tk.mainloop()#indention correcture
import tkinter
from tkinter import ttk
from tkinter import *
window = tkinter.Tk()
window.title("wasans")
window.geometry('640x400')
window.resizable(False, False)
textbook = ['국어','영어','social']
textbookselecter = ttk.Combobox(window, text="교과서 선택", values=textbook)
textbookselecter.grid(column=0, row=0)
textbookselecter.place(x=140, y=200)
textbookselecter.set("목록 선택")
textbooksuntack = ttk.Label(window, width=11, borderwidth=2, background="#8182b8")
textbooksuntack.grid(column=0, row=0)
textbooksuntack.place(x=170, y=170)
textbooksuntack.anchor = CENTER
naeyong = textbookselecter.get()
if naeyong == "social":
open("../social.py", "w")
window.mainloop()
How can I open a py file using if statement and open?
Also, please give your overall review of the code.
I am not good at English, so there may be awkward sentences using a translator. Please understand.
You basically need to check every time the ttk.Combobox is changed to check if 'social' is generated.
ttk.Combobox raises a "<<ComboboxSelected>>" virtual event when selected.
import tkinter
from tkinter import ttk
from tkinter import *
window = tkinter.Tk()
window.title("wasans")
window.geometry('640x400')
window.resizable(False, False)
def callback(eventObject):
if textbookselecter.get() == "social":
print("Opening File...")
#file=open("...../social.py","r+")
textbook = ['국어','영어','social']
textbookselecter = ttk.Combobox(window, text="교과서 선택", values=textbook)
textbookselecter.grid(column=0, row=0)
textbookselecter.place(x=140, y=200)
textbookselecter.set("목록 선택")
textbooksuntack = ttk.Label(window, width=11, borderwidth=2, background="#8182b8")
textbooksuntack.grid(column=0, row=0)
textbooksuntack.place(x=170, y=170)
textbooksuntack.anchor = CENTER
textbookselecter.bind("<<ComboboxSelected>>",callback)
window.mainloop()
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
So I want to send multiple get requests and let a tkinter label to show the progress, but I noticed the toplevel only shows up after all the requests have been done.
How can I fix this?
import tkinter as tk
import requests
window = tk.Tk()
def download():
global window
top = tk.Toplevel(window)
progress_text = tk.StringVar()
tk.Label(top, textvariable=progress_text, font=('Arial', 12))
url_list = [' http://www.yahoo.com', ' http://www.google.com', ' http://www.amazon.com']
[requests.get(c) for c in url_list]
for i in range(len(url_list)):
progress_text.set('Done: {}'.format(i/len(url_list)))
requests.get(url_list[i])
print('done')
tk.Button(window, text='download', command=download).pack()
window.mainloop()
I've searched and found a few things on parent windows in python but that is not what I was looking for. I am trying make a simple program that opens a window and another window after that when the previous one is closed. I was also trying to implement some kind of loop or sleep time to destroy the window by default if the user does not. This is what I have (I'm new please don't laugh)
from tkinter import *
import time
root = Tk()
i = 0
if i < 1:
root.title("title")
logo = PhotoImage(file="burger.gif")
w1 = Label(root, image=logo).pack()
time.sleep(3)
root.destroy()
i = i + 1
if i == 1:
root.title("title")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(root, image=photoTwo).pack()
time.sleep(3)
root.destroy()
i = i + 1
mainloop.()
Perhaps you're looking for something like this:
from tkinter import *
import time
def openNewWindow():
firstWindow.destroy()
secondWindow = Tk()
secondWindow.title("Second Window")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(secondWindow, image=photoTwo).pack()
secondWindow.mainloop()
firstWindow = Tk()
firstWindow.title("First Window")
logo = PhotoImage(file="burger.gif")
w1 = Label(firstWindow, image=logo).pack()
closeBttn = Button(firstWindow, text="Close!", command=openNewWindow)
closeBttn.pack()
firstWindow.mainloop()
This creates a button in the first window, which the user clicks. This then calls the openNewWindow function, which destroys that window, and opens the second window. I'm not sure there's a way to do this using the window exit button.
To get create a more sustainable window creation, use this:
from tkinter import *
import time
def openThirdWindow(previouswindow):
previouswindow.destroy()
thirdWindow = Tk()
thirdWindow.title("Third Window")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(thirdWindow, image=photoTwo).pack()
thirdWindow.mainloop()
def openSecondWindow(previouswindow):
previouswindow.destroy()
secondWindow = Tk()
secondWindow.title("Second Window")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(secondWindow, image=photoTwo).pack()
closeBttn = Button(secondWindow, text="Close!", command= lambda: openThirdWindow(secondWindow))
closeBttn.pack()
secondWindow.mainloop()
def openFirstWindow():
firstWindow = Tk()
firstWindow.title("First Window")
logo = PhotoImage(file="burger.gif")
w1 = Label(firstWindow, image=logo).pack()
closeBttn = Button(firstWindow, text="Close!", command= lambda: openSecondWindow(firstWindow))
closeBttn.pack()
firstWindow.mainloop()
openFirstWindow()
This places the opening of each window in a seperate function, and passes the name of the window through the button presses into the next function. Another method would be setting the window names as global, but this is messy.
The function "lambda:" calls the function, in tkinter you must type this if you want to pass something through a command.
We initiate the whole process first first called "openFirstWindow()"