Small problem here, my code seem to be clean but the tkinter GUI doesn't appear ? Can seem to figure it out. The GUI / Code is for a report form type.
Thanks for your help in advance
from tkinter import *
class FicheDeSignalement(Frame):
def __init__(self):
Frame.__init__(self)
programme = Frame()
programme.pack(side="top", fill="both", expand=True)
programme.grid_rowconfigure(0, weight=5)
programme.grid_columnconfigure(0, weight=5)
self.pages = {}
for onePage in (StartProgram, InformationsPage):
start_page = onePage(programme, self)
self.pages[onePage] = start_page
start_page.grid(row=0, column=0, sticky="nsew")
self.show_pages(StartProgram)
def show_pages(self, cont):
see_start_page = self.pages[cont]
see_start_page.tkraise()
class StartProgram(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent, controller)
label = Label(self, text="Fiche de Signalement", font=LARGE_FONT)
label.pack(padx=10, pady=10)
start_button = Button(self, text="Commencer", command=lambda: controller.see_page(InformationsPage))
start_button.pack()
class InformationsPage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent, controller)
label = Label(self, text="Informations sur le suspect", font=LARGE_FONT)
label.pack(side="top", fill="both", expand=True, padx=10, pady=10)
person_suspected = Label(self, text="Prenom")
person_suspected.grid(row=0, column=0, padx=10, pady=10)
first_name = Entry(self)
first_name.grid(row=0, column=1, padx=10, pady=10)
person_suspected_2 = Label(self, text="Nom")
person_suspected_2.grid(row=0, column=2, padx=10, pady=10)
last_name = Entry(self)
last_name.grid(row=0, column=3, padx=10, pady=10)
person_height = Label(self, text="Grandeur")
person_height.grid(row=1, column=0, padx=10, pady=10)
size_height = Entry(self)
size_height.grid(row=1, column=1, padx=10, pady=10)
person_weight = Label(self, text="Poids")
person_weight.grid(row=1, column=2, padx=10, pady=10)
size_weight = Entry(self)
size_weight.grid(row=1, column=3, padx=10, pady=10)
app = FicheDeSignalement()
app.mainloop()
In addition to indentation errors and missing import statements and missing definition of LARGE_FONT, you have this problem:
label = Label(self, text="Informations sur le suspect")
label.pack(side="top", fill="both", expand=True, padx=10, pady=10)
person_suspected = Label(self, text="Prenom")
person_suspected.grid(row=0, column=0, padx=10, pady=10)
Both label and person_suspected share the same parent (self), but one uses pack and one uses grid. You can't use both of them with widgets that share a common parent. You must use only grid or only pack.
Related
This is my first encounter with listboxes and I want to know how to insert the name of each team member into the corresponding listbox.
I have a dictionary called teams, and it's store data like that:
{'Team1': {'Aleks', Richard}, 'Team2': {'Louis'}, 'Team3': set(), 'Team4': set()}
I need to put set of names in particular listbox (ex. 'Team1' set should appear in the team1Members listbox).
I was trying to use .insert method to insert specific items from my dictionary, but I receive an error:
_tkinter.TclError: bad listbox index ".!frame.!listcheckpage": must be active, anchor, end, #x,y, or a number
My code:
from tkinter import *
from tkinter import messagebox
import tkinter.ttk as ttk
import time
class CollegeApp(Tk):
def __init__(self):
Tk.__init__(self)
container = ttk.Frame(self)
container.pack(side="top", fill="both", expand=True)
self.frames = {}
for F in (StartPage, TeamsPage, successfullAddTeam, selectionPage, listCheckPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
self.lift()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.startMenu()
def startMenu(self):
heading = Label(self, text="College Tournament Points\n Count Software",
font=('Arial', 25))
heading.grid(row=0, column=0, columnspan=2, padx=240, pady=40)
start_Btn = Button(self, text="START", font="Arial 16", width=8,
command=lambda: self.controller.show_frame(selectionPage))
start_Btn.grid(row=1, column=0, columnspan=2, padx=30, pady=5)
exit_Btn = Button(self, text="EXIT", font="Arial 16", width=8,
command=self.controller.destroy)
exit_Btn.grid(row=2, column=0, columnspan=2, padx=30, pady=5)
def starting_Program(self):
pass
class selectionPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.teamSelect()
def teamSelect(self):
heading = Label(self, text="Select one of two options",
font=('Arial', 25))
heading.grid(row=0, column=0, columnspan=2, padx=250, pady=40)
teams = Button(self, text="Teams", font="Arial 24", width=15,
command=lambda: self.controller.show_frame(TeamsPage))
teams.grid(row=1, column=0, padx=270, pady=5)
class TeamsPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.userEntry()
def userEntry(self):
headingTest = Label(self, text="Enter your UserName:", font="Arial 20")
headingTest.grid(row=0, column=0, pady=5, padx=5)
self.usernameEnter = Entry(self, width=40)
self.usernameEnter.grid(row=0, column=1, padx=5, pady=5)
self.TeamName = StringVar(self)
self.TeamName.set("Team1")
AdditionalText = Label(self, text="Please select a team:", font="Arial 18")
AdditionalText.grid(row=1, column=0, sticky=W, pady=15, padx=5)
self.team_names = list(teams.keys())[:-1]
self.teamSelection = OptionMenu(self, self.TeamName, *self.team_names)
self.teamSelection.grid(row=1, column=1, sticky=W)
backBtn = Button(self, text="BACK", font="Arial 16",
command=lambda: self.controller.show_frame(StartPage))
backBtn.config(height=4, width=12)
backBtn.grid(sticky=W, row=2, column=0, pady=5, padx=5)
confirmBtn = Button(self, text="Confirm User", font="Arial 16",
command=self.confirm)
confirmBtn.config(height=4, width=12)
confirmBtn.grid(row=2, column=2, sticky=E, padx=45, pady=300)
def confirm(self):
if self.add_to_team():
time.sleep(0.2)
self.controller.show_frame(successfullAddTeam)
def add_to_team(self):
user = self.usernameEnter.get()
if len(user) == 0:
messagebox.showwarning(title='No user', message='Please enter a username!')
return
if self.usernameEnter.get():
time.sleep(0.1)
self.controller.show_frame(successfullAddTeam)
team_name = self.TeamName.get()
team = teams[team_name]
if user in team:
messagebox.showwarning(title='In team', message=f'{user} is already a member of {team_name}!')
team.add(user)
print(teams)
class successfullAddTeam(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.userEntry()
def userEntry(self):
successText = Label(self, text="You have successfully joined to a team!", font="Arial 25")
successText.grid(row=0, column=0, columnspan=2, padx=180, pady=35)
newUser = Button(self, text="Add another user", font="Arial 16",
command=lambda: self.controller.show_frame(selectionPage))
newUser.config(height=3, width=12)
newUser.grid(row=1, column=0, columnspan=2, padx=200, pady=10)
checkList = Button(self, text="Check the lists", font="Arial 16",
command=lambda: self.controller.show_frame(listCheckPage))
checkList.config(height=3, width=12)
checkList.grid(row=2, column=0, columnspan=2, padx=200, pady=0)
#####################################Problem here###############################################
class listCheckPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.userEntry()
def userEntry(self):
team1Members = Listbox(self)
team1Members.insert(self, teams['Team1'])
team1Members.config(height=13, width=20)
team1Members.grid(row=0, column=0, padx=10, pady=5, sticky=W)
team2Members = Listbox(self)
team2Members.insert(self, teams['Team2'])
team2Members.config(height=13, width=20)
team2Members.grid(row=0, column=1, padx=7, pady=5, sticky=W)
team3Members = Listbox(self)
team3Members.insert(self, teams['Team3'])
team3Members.config(height=13, width=20)
team3Members.grid(row=0, column=3, padx=7, pady=5, sticky=W)
team4Members = Listbox(self)
team4Members.insert(self, teams['Team4'])
team4Members.config(height=13, width=20)
team4Members.grid(row=0, column=4, padx=7, pady=5, sticky=W)
addUserBtn = Button(self, text="Add User", font="Arial 16",
command=lambda: self.controller.show_frame(selectionPage))
addUserBtn.config(height=3, width=18)
addUserBtn.grid(row=1, column=4, sticky=S)
if __name__ == '__main__':
teams = {}
for team in range(1, 5):
teams[f'Team{team}'] = set()
app = CollegeApp()
app.geometry("800x500")
app.title('Points Counter')
app.mainloop()
It is obvious that I am doing something wrong, and I would like to know how this issue can be properly resolved.
I'm sure i'm missing something with the class/inheritence understanding.
when i hit the submit button i get this error:
I tried many variations like changing the command in the button, changing masters, defining self.controller.
how can I make the submit button to work?
import tkinter as tk
import os
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.geometry("650x500")
self.title("Gil Shwartz GUI Project")
menu = tk.Frame(self, height=250, width=10, bg="black")
menu.pack(side=tk.LEFT, fill="both", anchor="w")
container = tk.Frame(self, height=250, width=270, relief="flat")
container.pack(side=tk.TOP, fill="both", expand=True)
output = tk.LabelFrame(self, text="Output", height=150, padx=5, pady=5)
output.pack(side=tk.BOTTOM, fill="both", anchor="s")
menu.grid_columnconfigure(0, weight=0)
menu.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(1, weight=1)
self.frames = ["StartPage", "MainWelcome", "testPing", "PageOne", "PageTwo"]
self.frames[0] = Menu(parent=menu, controller=self)
self.frames[1] = MainWelcome(parent=container, controller=self)
self.frames[2] = testPing(parent=container, controller=self)
self.frames[3] = PageOne(parent=container, controller=self)
self.frames[4] = PageTwo(parent=container, controller=self)
self.frames[0].grid(row=0, column=0, sticky="nsew")
self.frames[1].grid(row=0, column=0, sticky="nsew")
self.frames[2].grid(row=0, column=0, sticky="nsew")
self.frames[3].grid(row=0, column=0, sticky="nsew")
self.frames[4].grid(row=0, column=0, sticky="nsew")
self.show_frame(1)
def show_frame(self, page_name):
frame = self.frames[page_name]
print(frame)
frame.tkraise()
class Menu(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.menu = controller
button1 = tk.Button(self, text="Ping Test",
command=lambda: controller.show_frame(2))
button2 = tk.Button(self, text="Page Two",
command=lambda: controller.show_frame(4))
button3 = tk.Button(self, text="Quit",
command=lambda: Menu.terminate(self))
button1.pack(fill="both", expand=True)
button2.pack(fill="both", expand=True)
button3.pack(fill="both", expand=True)
button1.grid_columnconfigure(0, weight=1)
button2.grid_columnconfigure(0, weight=0)
button3.grid_rowconfigure(0, weight=0)
def terminate(self):
exit()
class MainWelcome(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.menu = controller
label = tk.Label(self, text="Text 1", bg="yellow")
label.pack(fill="x", expand=True)
label = tk.Label(self, text="Text 2", bg="yellow")
label.pack(fill="x")
class testPing(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.urlLabel = controller
urlLabel = tk.Label(self, text="Enter URL : ", padx=5, pady=5)
urlLabel.pack(anchor="w")
urlInputBox = tk.Entry(self)
urlInputBox.pack()
urlInputBox.grid_columnconfigure(0, weight=0)
clearLabel = tk.Label(self, text="Clear File?", padx=5, pady=5)
clearLabel.pack(anchor="w")
clearFile = tk.BooleanVar()
clearFile.set(False)
clearFileRadioYes = tk.Radiobutton(self, text="yes", value=True, var=clearFile,
command=lambda: testPing.callback(clearFile.get()))
clearFileRadioYes.pack(anchor="w")
clearFileRadioNo = tk.Radiobutton(self, text="no", value=False, var=clearFile,
command=lambda: testPing.callback((clearFile.get())))
clearFileRadioNo.pack(anchor="w")
urlSubmitButton = tk.Button(self, text="Submit",
command=lambda: testPing.pingURL(urlInputBox.get(),
testPing(clearFile.get())))
urlSubmitButton.pack(side=tk.RIGHT, anchor="e")
def callback(clearFile):
print(clearFile) # Debugging Mode - check Radio box Var.
def pingURL(self, host, clearFile):
outputFrameLabel = tk.LabelFrame(self, text="Output", height=35, width=150,
padx=5, pady=5, relief="solid")
outputFrameLabel.place(x=0, y=150)
file = fr'c:/users/{os.getlogin()}/Desktop/ping.txt'
label = tk.Label(outputLabel, text=f'Pinging {host} ...')
label.grid(row=0, column=0)
label.update()
if clearFile == True:
with open(file, 'w+') as output:
output.truncate(0)
sub.call(['ping', f'{host}'], stdout=output)
else:
with open(file, 'a') as output:
sub.call(['ping', f'{host}'], stdout=output)
output.close()
label.configure(text=f'Ping to {host} complete!')
# testPing.changeLabel(host)
# def changeLabel(self, host):
# myLabel = tk.Label.config(text=f"Ping to {host} Complete!")
# myLabel.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", bg="red")
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to page 2",
command=lambda: controller.show_frame(2))
button.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 2", bg="blue")
label.pack(side="top", fill="x", pady=10)
# button = tk.Button(self, text="Go to the start page",
# command=lambda: controller.show_frame(0))
# button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
here's a pic of the main window so you'll get a visual idea as well.
I think the error lies in the testPing class; in particular in these lines:
class testPing(tk.Frame):
...
clearFileRadioYes = tk.Radiobutton(self, text="yes", value=True, var=clearFile,
command=lambda: testPing.callback(clearFile.get()))
clearFileRadioYes.pack(anchor="w")
clearFileRadioNo = tk.Radiobutton(self, text="no", value=False, var=clearFile,
command=lambda: testPing.callback((clearFile.get())))
clearFileRadioNo.pack(anchor="w")
urlSubmitButton = tk.Button(self, text="Submit",
command=lambda: testPing.pingURL(urlInputBox.get(),
testPing(clearFile.get())))
You're inside testPing, so you should use self instead of using testPing explicitly. So, your code should be:
class testPing(tk.Frame):
...
clearFileRadioYes = tk.Radiobutton(self, text="yes", value=True, var=clearFile,
command=lambda: self.callback(clearFile.get()))
clearFileRadioYes.pack(anchor="w")
clearFileRadioNo = tk.Radiobutton(self, text="no", value=False, var=clearFile,
command=lambda: self.callback((clearFile.get())))
clearFileRadioNo.pack(anchor="w")
urlSubmitButton = tk.Button(self, text="Submit",
command=lambda: self.pingURL(urlInputBox.get(),
clearFile.get()))
Notice using self instead of testPing
Hi Guys I have Problem after add background in my project, I don't see anything but after resize I see background: I don't want to use ttk in my object.
This is my code:
from tkinter import (Button, Label, Frame)
class HomeFrame(Frame): # Inherit Frame class
"""Application main interface"""
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.root = parent # Define internal variable root
self.root.configure(background='green')
self.home_page()
def home_page(self):
"""Load control"""
Label(self, text="First name").grid(row=0, column=0, padx=20, pady=20)
Full_name = Button(self, text="Get Full name")
Full_name.grid(row=0, column=1, columnspan=2, padx=20, pady=20)
Label(self, text="Last name").grid(row=1, column=0, padx=20, pady=20)
hello = Button(self, text="hello")
hello.grid(row=3, column=2, columnspan=2, padx=20, pady=20)
This is Result:
Interface without resize
After Resize:
Interface After Resize
from tkinter import (Button, Label, Frame)
class HomeFrame(Frame): # Inherit Frame class
"""Application main interface"""
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.root = parent # Define internal variable root
self.root.configure(background='green')
self.config(background='green')
self.home_page()
def home_page(self):
"""Load control"""
Label(self, text="First name").grid(row=0, column=0, padx=20, pady=20)
Full_name = Button(self, text="Get Full name")
Full_name.grid(row=0, column=1, columnspan=2, padx=20, pady=20)
Label(self, text="Last name").grid(row=1, column=0, padx=20, pady=20)
hello = Button(self, text="hello")
hello.grid(row=3, column=2, columnspan=2, padx=20, pady=20)
I have packaged a group a widgets into a single widget as follows:
class RunOptions(tk.Frame):
def __init__(self, master=None):
super().__init__(master, bg='green')
self.label = tk.Label(self, text='Options:')
self.folder_button_label = tk.Label(self, text='Select a Folder', bg='white')
self.folder_button = tk.Button(self, text='Select Image Folder')
self.template_button = tk.Button(self, text='Select Template')
self.template_frame = ImageCanvas(self, height=64, width=64)
self.label.grid(row=0, sticky='W')
self.folder_button.grid(row=1, column=1, sticky='W')
self.folder_button_label.grid(row=1, column=0, sticky='W')
self.template_button.grid(row=2, column=1, sticky='W')
self.template_frame.grid(row=2, column=0, sticky='W')
and
class DetectionCanvas(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.xml_var = tk.IntVar()
self.detectframe = ImageCanvas(self, label='Detection:', height=175, width=175)
self.x_out = tk.Label(self, bg='white', text='X:', anchor='w')
self.y_out = tk.Label(self, bg='white', text='Y:', anchor='w')
self.w_out = tk.Label(self, bg='white', text='W:', anchor='w')
self.h_out = tk.Label(self, bg='white', text='H:', anchor='w')
self.xml_check = tk.Checkbutton(self, text=' Save XML File',variable=self.xml_var)
self.detectframe.grid(row=0, column=0, rowspan=4)
self.x_out.grid(row=0, column=1)
self.y_out.grid(row=1, column=1)
self.w_out.grid(row=2, column=1)
self.h_out.grid(row=3, column=1)
self.xml_check.grid(row=4, column=0, sticky='w')
def display_out(self, *args):
pass
both of these widgets are all arranged in a large empty canvas (purple) using grid, but that doesn't matter here because the issue is in the individual widgets themselves:
I want the buttons in the options to anchor to the left, filling in the gap between the label. For the detection widget I want the labels to anchor left towards the canvas. I've tried anchoring and using sticky but nothing in the second column seems to move.
I've already did a cool little CLI To-Do app in python, and now I'm trying to build a basic GUI around it. The main buttons, field in place, and yesterday I've figured out how to redirect the return string from my Todo class to the text area.
My problem now is how to clear the text area? Currently if I press the 'View button' it's continously redirecting the text without deleting the previous output. I've tried to create a function with
self.text.delete('1.0','end') + the function with the string output, but it's not working. Can you suggest me something? Thanks in advance!
import tkinter as tk
from tkinter import messagebox as mbox
from todo_app import ToDo, arguments
import sys
class ToDoGui:
def __init__(self, root):
self.t = ToDo()
self.root = root
self.mainframe = tk.Frame(self.root, bg="white")
self.mainframe.pack(fill=tk.BOTH, expand=True)
self.build_grid()
self.build_banner()
self.build_text_area()
self.build_buttons()
sys.stderr = TextRedirector(self.text, "stderr")
self.entry()
def build_grid(self):
self.mainframe.columnconfigure(0, weight=1)
self.mainframe.rowconfigure(0, weight=0)
self.mainframe.rowconfigure(1, weight=1)
self.mainframe.rowconfigure(0, weight=0)
def build_banner(self):
banner = tk.Label(
self.mainframe,
bg="orange",
text="PyKeep",
fg="green",
font=('Helvetica', 24)
)
banner.grid(
row=0, column=0,
sticky='ew',
padx=10, pady=10
)
def build_buttons(self):
buttons_frame = tk.Frame(self.mainframe)
buttons_frame.grid(row=3, column=0, sticky='nsew',
padx=10, pady=10)
buttons_frame.columnconfigure(0, weight=1)
buttons_frame.columnconfigure(1, weight=1)
buttons_frame.columnconfigure(2, weight=1)
buttons_frame.columnconfigure(3, weight=1)
buttons_frame.columnconfigure(4, weight=1)
self.clear_button = tk.Button(
buttons_frame,
text='Clear',
command=self.text.delete('0.0', tk.END)
)
self.view_button= tk.Button(
buttons_frame,
text='View list',
command=self.t.list_view
)
self.add_button = tk.Button(
buttons_frame,
text='Add task',
command=None
)
self.remove_button = tk.Button(
buttons_frame,
text='Remove task',
command=None
)
self.complete_button = tk.Button(
buttons_frame,
text='Complete task',
command=None
)
self.clear_button.grid(row=0, column=0, sticky='ew')
self.view_button.grid(row=0, column=1, sticky='ew')
self.add_button.grid(row=0, column=2, sticky='ew')
self.remove_button.grid(row=0, column=3, sticky='ew')
self.complete_button.grid(row=0, column=4, sticky='ew')
def entry(self):
entry_field = tk.Entry(self.mainframe, bd=2)
entry_field.grid(row=1, column=0, sticky='nwse', padx=10, pady=10)
entry_field.insert(0, 'Enter task OR number of a task')
entry_field.focus()
def build_text_area(self):
text_frame = tk.Text(self.mainframe, wrap="word")
text_frame.grid(row=2, column=0, sticky='nsew',
padx=10, pady=10)
text_frame.columnconfigure(0, weight=1)
text_frame.config(state=tk.DISABLED)
text_frame.tag_configure("stderr", foreground="#b22222")
self.text = text_frame
return self.text
class TextRedirector(object):
def __init__(self, widget, tag="stderr"):
self.widget = widget
self.tag = tag
def write(self, str):
self.widget.configure(state="normal")
self.widget.insert("end", str, (self.tag,))
self.widget.configure(state="disabled")
if __name__ == '__main__':
root = tk.Tk()
ToDoGui(root)
root.mainloop()
The contents you are trying to delete is not Text's contents. It's your Entry widget.
def entry(self):
entry_field = tk.Entry(self.mainframe, bd=2)
entry_field.grid(row=1, column=0, sticky='nwse', padx=10, pady=10)
entry_field.insert(0, 'Enter task OR number of a task')
entry_field.focus()
self.entry_field= entry_field #make entry widget class' object
#since there is only one row in common Entry, you need to only specify starting index
self.clear_button = tk.Button(..., command=lambda: self.entry_field.delete(0, tk.END)