Object of Class inheriting LabelFrame doesnt show up (tkinter) - python

Basically I have a class that inherits from LabelFrame, I want it to show up on the window itself, but I don't see it at all, it doesn't even show up on the window no matter what I do
from tkinter import *
root = Tk()
root['bg'] = 'white'
root.state('zoomed')
class CharacterFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
default_char_frame = CharacterFrame(master=root, desc='Default Character.', requirement=0, skin_img='')
default_char_frame.grid(row=0, column=0, sticky='nse')
root.mainloop()
ok, so i was stupid for not implementing the actual code itself, but ill do it now (This isnt actual source code, just the important code, still has same error as actual code):
from tkinter import *
root = Tk()
root['background'] = 'white'
root.state('zoomed')
class SkinFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
self.desc.pack()
def show_chars():
button_grid.grid_forget()
skin_lib.grid(row=1, column=0, sticky='nws')
button_skin0 = Button(skin_lib, text="Skin1", relief="flat", width=15, fg="white", bg="darkgrey", command=lambda: show_char_frame(prev, default_char_frame), font=("Arial", 29, "italic"))
button_skin0.grid(row=0, column=0, pady=(0,10))
back = Button(skin_lib, text="Back", width=15, relief="flat", fg="white", bg="maroon", font=("Arial",29,"italic"),
command=lambda: [skin_lib.grid_forget(), button_grid.grid(row=1, column=0, sticky='nws')])
back.grid(row=100, column=0)
def show_char_frame(prev, char_frame):
skin_lib.grid_forget()
default_char_frame.grid(row=1, column=1, sticky='nse')
default_char_frame = SkinFrame(master=root, desc='Default Skin.', requirement=0, skin_img='')
Label(root, text="Game Title", width=68, relief="flat", bg="white", fg="grey", font=("Arial",26,"italic")).grid(row=0, column=0, sticky='n')
button_grid = LabelFrame(root, bg='grey29', relief="groove", pady=10, padx=10)
button_grid.grid(row=1, column=0, sticky='nws')
skin_lib = LabelFrame(root, bg='grey29', relief="groove", pady=10, padx=10)
skins = Button(button_grid, text="Skins", width=15, relief="flat", fg="white", bg="navy", command=show_chars, font=("Arial", 29, "italic"))
skins.grid(row=2, column=0, pady=(0,10))
previous_skinframe
root.mainloop()

you missed to pack() label to add in control
self.desc.pack()
this is complete code
from tkinter import *
root = Tk()
root['bg'] = 'white'
root.state('zoomed')
class CharacterFrame(LabelFrame):
def __init__(self, master, skin_img, requirement, desc):
super().__init__(master=master, bg='grey29')
self.desc = Label(self, text=desc)
self.desc.pack()
default_char_frame = CharacterFrame(master=root, desc='Default Character.', requirement=0, skin_img='')
default_char_frame.grid(row=0, column=0, sticky='nse')
root.mainloop()
in this code what I add self.desc.pack() to show
this is output

Related

How to call onto the class that is in the tkinter mainloop?

I've been trying to call the class that is in my mainloop, but whenever I properly call it makes it that the program doesn't even launch anymore. I've been attempting to call it in order to get a method, which would return the current frame. I am aware that my code uses controller and parent to communicate between classes, but I haven't managed to fully grasp an understanding of these. If I call the mainlooped class, with "test = Database_project()", then the program won't run anymore. Can someone explain this to me? I'm trying to get the scrollbar feature to work on specific frames, and I haven't managed to figure out just yet. I'm trying to call the mainlooped class in the "CreatePage" class. Thank you in advance!
from tkinter import *
import tkinter as tk
class Database_Project(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
stack_frame_container = tk.Frame(self)
stack_frame_container.grid_columnconfigure(0, weight=1)
stack_frame_container.grid_rowconfigure(0, weight=1)
stack_frame_container.pack(side="top", fill="both", expand=True)
self.frameslist = {}
for frame in (MainPage, CreatePage):
frame_occurrence = frame.__name__
active_frame = frame(parent=stack_frame_container, controller=self)
self.frameslist[frame_occurrence] = active_frame
active_frame.grid(row=0, column=0, sticky="snew")
#self.frameslist["CreatePage"].dbproject = self.frameslist["Datanase_Project"]
self.current_frame("MainPage")
print(self.frameslist)
def current_frame(self, frame_occurrence):
active_frame = self.frameslist[frame_occurrence]
active_frame.tkraise()
def get_current_frame(self, frame_occurrence):
active_frame = self.frameslist[frame_occurrence]
return active_frame
class MainPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label_create = tk.Label(self, text="Create and insert data").grid(row=0, column=0, padx=50, pady=(50,0))
create_button = tk.Button(self, text="CREATE", command=lambda: controller.current_frame("CreatePage")).grid(row=1, column=0)
label_read = tk.Label(self, text="Query over data").grid(row=0, column=1, padx=50, pady=(50,0))
read_button = tk.Button(self, text="READ").grid(row=1, column=1)
label_update = tk.Label(self, text="Modify existing data").grid(row=2, column=0, padx=50, pady=(50,0))
update_button = tk.Button(self, text="UPDATE").grid(row=3, column=0, pady=(0,50))
label_delete = tk.Label(self, text="Remove data").grid(row=2, column=1, padx=50, pady=(50,0))
delete_button = tk.Button(self, text="DELETE").grid(row=3, column=1, pady=(0,50))
class CreatePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.inputlist = []
self.newinputlist = []
Test = Database_Project()
#active_frame = Test.get_current_frame("CreatePage")
#scrollbar = tk.Scrollbar(active_frame, orient="vertical")
#scrollbar.grid(row=0, column=2, stick="ns", columnspan=10)
#text["yscrollcommand"] =
labels = [tk.Label(self, text="Enter unique field"), tk.Label(self, text="Enter corresponding the value/s")]
self.inputlist.append(labels[:])
for toplabels in range(1):
self.inputlist[toplabels][0].grid(row=toplabels, column=0, padx=10, pady=5)
self.inputlist[toplabels][1].grid(row=toplabels, column=1, padx=10, pady=5)
first_entries = [tk.Entry(self, borderwidth=5), tk.Text(self, borderwidth=5, height= 5, width=20)]
self.newinputlist.append(first_entries[:])
self.inputlist.append(first_entries[:])
for x in range(0, len(self.newinputlist) + 1):
self.newinputlist[0][x].grid(row=1, column=x, padx=10, pady=5)
button_input_1 = [tk.Button(self, text="ADD FIELD/VALUE", command=self.add_insert), tk.Button(self, text="BACK", command=lambda: controller.current_frame("MainPage"))]
self.inputlist.append(button_input_1[:])
button_input_2 = [tk.Button(self, text="IMPORT FILE"), tk.Button(self, text="SUBMIT DATA", command=self.submit_data)]
self.inputlist.append(button_input_2[:])
for button in range(len(self.inputlist) - 2, len(self.inputlist)):
self.inputlist[button][0].grid(row=button, column=0, padx=10, pady=5)
self.inputlist[button][1].grid(row=button, column=1, padx=10, pady=5)
def add_insert(self):
add_input = [tk.Entry(self, borderwidth=5), tk.Text(self, borderwidth=5, height= 5, width=20)]
self.inputlist.insert(-2, add_input)
self.newinputlist.append(add_input)
for widget in self.children.values():
widget.grid_forget()
for index, widgets in enumerate(self.inputlist):
print(widgets)
widget_one = widgets[0]
widget_two = widgets[1]
print(str(index), widget_one, widget_two)
widget_one.grid(row=index, column=0, padx=10, pady=5)
widget_two.grid(row=index, column=1, padx=10)
def submit_data(self):
for index, entries in enumerate(self.newinputlist):
my_label = Label(self, text=str(entries[0].get()) + str(entries[1].get("1.0", END)))
my_label.grid(row=len(self.inputlist) + index, column=0)
if __name__ == "__main__":
NoSQL_Project = Database_Project()
NoSQL_Project.title("NoSQL Database Project")
NoSQL_Project.maxsize(500, 500)
NoSQL_Project.mainloop()

Changing a Variablestring in a Class in Python

I have a small piece of code, which was working fine, until I decided to create a class and put things into that class. Now my problem is, I cannot change stringvariable anymore.
Here is my code:
import tkinter as tk
import tkinter.ttk as ttk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
frame1 = ttk.LabelFrame(root, text="PANEL A", borderwidth=5)
frame1.grid(row=0, column=0, padx=5, pady=5)
frame2 = ttk.LabelFrame(frame1, text="PANEL B", width = 500, height = 1000)
frame2.grid(row=0, column=0, padx=5, pady=5, sticky='NSWE')
strVarMeasurement = tk.StringVar()
frame3 = ttk.LabelFrame(frame2, text="PANEL C")
frame3.grid(row=0, column=0, padx=5, pady=5)
lbl_01 = ttk.Label(frame3, width=20, anchor = tk.E, text="Measurement: ").grid(row=0, column=0)
e_01 = ttk.Entry (frame3, width=8, textvariable=strVarMeasurement).grid(row=0, column=1)
def setString():
strVarMeasurement.set(1234)
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root)
MainApplication.setString()
root.mainloop()
This is the error I get:
NameError: name 'strVarMeasurement' is not defined
How can I change that string of the class?
Isn't that variable created during MainApplication(root)?
Do you think it is better to define such a string inside or outside the class?
Add self and and Object, this may fix this error.
import tkinter as tk
import tkinter.ttk as ttk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
frame1 = ttk.LabelFrame(root, text="PANEL A", borderwidth=5)
frame1.grid(row=0, column=0, padx=5, pady=5)
frame2 = ttk.LabelFrame(frame1, text="PANEL B", width = 500, height = 1000)
frame2.grid(row=0, column=0, padx=5, pady=5, sticky='NSWE')
self.strVarMeasurement = tk.StringVar()
frame3 = ttk.LabelFrame(frame2, text="PANEL C")
frame3.grid(row=0, column=0, padx=5, pady=5)
lbl_01 = ttk.Label(frame3, width=20, anchor = tk.E, text="Measurement: ").grid(row=0, column=0)
e_01 = ttk.Entry (frame3, width=8, textvariable= self.strVarMeasurement).grid(row=0, column=1)
def setString(self):
self.strVarMeasurement.set(1234)
if __name__ == "__main__":
root = tk.Tk()
app = MainApplication(root)
app.setString()
root.mainloop()

Tkinter won't close correctly and launch new file

I made a little login screen. After I put in the credentials I want the Tkinter to be closed and open a new python file. If you execute the code below it will give me the error NameError: name ttk is not defined. In the other file I imported everything and gave it the correct name.
The file I use for the login:
from tkinter import *
import tkinter.messagebox as tm
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.photo = PhotoImage(file="sbshreg.png")
self.label_image = Label(root, image=self.photo)
self.label_image.image = self.photo
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_username.grid(row=0, sticky=E)
self.label_password.grid(row=1, sticky=E)
self.label_image.grid(row=3, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)
self.entry_username.grid(row=0, column=1, sticky=E)
self.entry_password.grid(row=1, column=1, sticky=E)
self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2, column=1, row=2, sticky=S+E+N+W)
self.grid()
def _login_btn_clicked(self):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "123" and password == "123":
tm.showinfo("SBSHREG", "Welcome 123")
#The sweet spot where all goes wrong...
self.destroy()
exec(open("./BatchFrame.py").read())
else:
tm.showerror("SBSHREG", "Incorrect username")
root = Tk()
root.title("SBSHREG")
root.geometry("235x120")
lf = LoginFrame(root)
root.mainloop()
In the other file I got this: from tkinter import ttk as ttk which should prevent the error in the other file from happening.
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk
class BatchFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.photo = PhotoImage(file="sbshreg.png")
self.label_photo = Label(root, image=self.photo)
self.label_photo.image = self.photo
self.label_photo.grid(row=0, column=2, sticky=N, padx=10, pady=10)
#Add frame starting here
frame = LabelFrame(self.master, text='Voeg batch toe')
frame.grid (row=0, column=0, padx=10)
self.label_batch = Label(frame, text="Batchnummer")
self.label_employee = Label(frame, text="Medewerker")
self.label_material = Label(frame, text="Materiaalsoort")
self.label_weight = Label(frame, text="Gewicht")
self.entry_batch = Entry(frame)
self.entry_employee = Entry(frame)
self.entry_material= Entry(frame)
self.entry_weight = Entry(frame)
self.label_batch.grid(row=0, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_material.grid(row=4, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_weight.grid(row=6, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_employee.grid(row=3, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_material.grid(row=5, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_weight.grid(row=7, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.btnadd = Button(frame, text='Voeg toe', command=self._btn_add_clicked)
self.btnadd.grid(column=0, row=8, pady=10)
#Search frame starting here
framesearch = LabelFrame(self.master, text='Zoek')
framesearch.grid(row=0, column=1, sticky=N)
self.label_batch = Label(framesearch, text="Batchnummer")
self.label_employee = Label(framesearch, text="Medewerker")
self.entry_batch = Entry(framesearch)
self.entry_employee = Entry(framesearch)
self.label_batch.grid(row=0, column=0, sticky=S, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.entry_employee.grid(row=3, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.btnbatch = Button(framesearch, text="Zoek", command=self._btn_batch_clicked)
self.btnemployee = Button(framesearch, text="Zoek", command=self._btn_employee_clicked)
self.btnbatch.grid(columnspan=1, column=2, row=1, sticky=W, padx=10)
self.btnemployee.grid(columnspan=1, column=2, row=3, sticky=W, padx=10)
#This is the viewingarea for the data
self.tree = ttk.Treeview (height=10, columns=("Batchnummer", "Medewerker", "Materiaalsoort", "Gewicht"))
self.tree.grid (row=9, columnspan=10, padx=10, pady=10)
self.tree.heading('#1', text='Batchnummer', anchor=W)
self.tree.heading('#2', text='Medewerker', anchor=W)
self.tree.heading('#3', text='Materiaalsoort', anchor=W)
self.tree.heading('#4', text='Gewicht', anchor=W)
self.tree.column('#0', stretch=NO, minwidth=0, width=0)
self.tree.column('#1', stretch=NO, minwidth=0, width=100)
self.tree.column('#2', stretch=NO, minwidth=0, width=100)
self.tree.column('#3', stretch=NO, minwidth=0, width=100)
self.tree.column('#4', stretch=NO, minwidth=0, width=100)
self.grid()
def _btn_add_clicked(self):
batch = self.entry_batch.get()
def _btn_batch_clicked(self):
batch = self.entry_batch.get()
def _btn_employee_clicked(self):
batch = self.entry_employee.get()
root = Tk()
root.title("SBSHREG")
root.geometry("432x480")
lf = BatchFrame(root)
root.mainloop()
If I change self.destroy() to root.destroy() I get the following error: _tkinter.TclError: can't invoke "label" command: application has been destroyed. In the second file the functions are not done yet because I'm still working on the file, but this shouldn't have any impact on the error.
I searched everywhere and tried a lot and I still got no clue whatsoever...
Consider initializing frames in a top level class, GUI, that handles opening of both frames where LoginFrame calls its parent's open_batch() (now lambda implemented) method. Below assumes LoginFrame.py and BatchFrame.py resides in same folder as GUI_App script.
In this way, scripts run as standalone modules on one Tk() instance.
GUIApp (calls child frames, LoginFrame, and BatchFrame)
from tkinter import *
import LoginFrame as LF
import BatchFrame as BF
class GUI():
def __init__(self):
self.root = Tk()
self.root.title("SBSHREG")
self.root.geometry("235x120")
self.root.open_batch = self.open_batch
lf = LF.LoginFrame(self.root)
self.root.mainloop()
def open_batch(self):
bf = BF.BatchFrame(self.root)
app = GUI()
LoginFrame
from tkinter import *
import tkinter.messagebox as tm
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.photo = PhotoImage(file="sbshreg.png")
self.label_image = Label(self, image=self.photo)
self.label_image.image = self.photo
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_image.grid(row=0, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)
self.label_username.grid(row=2, sticky=E)
self.label_password.grid(row=3, sticky=E)
self.entry_username.grid(row=2, column=1, sticky=E)
self.entry_password.grid(row=3, column=1, sticky=E)
self.logbtn = Button(self, text="Login", command=lambda: self._login_btn_clicked(master))
self.logbtn.grid(row=4, column=1, columnspan=2, sticky=S+E+N+W)
self.grid()
def _login_btn_clicked(self, controller):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "123" and password == "123":
tm.showinfo("SBSHREG", "Welcome 123")
self.destroy()
controller.open_batch()
else:
tm.showerror("SBSHREG", "Incorrect username")
BatchFrame
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk
class BatchFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.photo = PhotoImage(file="sbshreg.png")
self.label_photo = Label(master, image=self.photo)
self.label_photo.image = self.photo
self.label_photo.grid(row=0, column=2, sticky=N, padx=10, pady=10)
#Add frame starting here
frame = LabelFrame(master, text='Voeg batch toe')
frame.grid (row=0, column=0, padx=10)
self.label_batch = Label(frame, text="Batchnummer")
self.label_employee = Label(frame, text="Medewerker")
self.label_material = Label(frame, text="Materiaalsoort")
self.label_weight = Label(frame, text="Gewicht")
self.entry_batch = Entry(frame)
self.entry_employee = Entry(frame)
self.entry_material= Entry(frame)
self.entry_weight = Entry(frame)
self.label_batch.grid(row=0, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_material.grid(row=4, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.label_weight.grid(row=6, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_employee.grid(row=3, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_material.grid(row=5, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.entry_weight.grid(row=7, column=0, sticky=S+E+N+W, columnspan=2, padx=10)
self.btnadd = Button(frame, text='Voeg toe', command=self._btn_add_clicked)
self.btnadd.grid(column=0, row=8, pady=10)
#Search frame starting here
framesearch = LabelFrame(master, text='Zoek')
framesearch.grid(row=0, column=1, sticky=N)
self.label_batch = Label(framesearch, text="Batchnummer")
self.label_employee = Label(framesearch, text="Medewerker")
self.entry_batch = Entry(framesearch)
self.entry_employee = Entry(framesearch)
self.label_batch.grid(row=0, column=0, sticky=S, columnspan=2, padx=10)
self.label_employee.grid(row=2, column=0, sticky=S, columnspan=2, padx=10)
self.entry_batch.grid(row=1, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.entry_employee.grid(row=3, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)
self.btnbatch = Button(framesearch, text="Zoek", command=self._btn_batch_clicked)
self.btnemployee = Button(framesearch, text="Zoek", command=self._btn_employee_clicked)
self.btnbatch.grid(columnspan=1, column=2, row=1, sticky=W, padx=10)
self.btnemployee.grid(columnspan=1, column=2, row=3, sticky=W, padx=10)
#This is the viewingarea for the data
self.tree = ttk.Treeview (height=10, columns=("Batchnummer", "Medewerker", "Materiaalsoort", "Gewicht"))
self.tree.grid (row=9, columnspan=10, padx=10, pady=10)
self.tree.heading('#1', text='Batchnummer', anchor=W)
self.tree.heading('#2', text='Medewerker', anchor=W)
self.tree.heading('#3', text='Materiaalsoort', anchor=W)
self.tree.heading('#4', text='Gewicht', anchor=W)
self.tree.column('#0', stretch=NO, minwidth=0, width=0)
self.tree.column('#1', stretch=NO, minwidth=0, width=100)
self.tree.column('#2', stretch=NO, minwidth=0, width=100)
self.tree.column('#3', stretch=NO, minwidth=0, width=100)
self.tree.column('#4', stretch=NO, minwidth=0, width=100)
self.grid()
def _btn_add_clicked(self):
batch = self.entry_batch.get()
def _btn_batch_clicked(self):
batch = self.entry_batch.get()
def _btn_employee_clicked(self):
batch = self.entry_employee.get()
I do not agree with the method of how you are invoking your 2nd python file.
You really dont need to use exec here.
However if you really want to you need to add import tkinter.ttk as ttk to your first page for it to work right.
Your best option is to import the 2nd file on the 1st file and invoke it by calling the class name.
so for you imports on the first page you need to add import BatchFrame.
Then call it in your code.
Replace:
exec(open("./test2.py").read())
with:
BatchFrame.BatchFrame(root)
I do see one mistake in your BatchFrame class thought.
change this:
self.label_photo = Label(root, image=self.photo)
to this:
self.label_photo = Label(master, image=self.photo)
UPDATE:
To address your issue from the comment make these changes:
1: Add this to your BatchFrame Class:
class BatchFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.master = master # add this
self.master.title("SBSHREG") # and this
self.master.geometry("432x480") # and this
2: Remove this from your BatchFrame file:
root = Tk()
root.title("SBSHREG")
root.geometry("432x480")
lf = BatchFrame(root)
root.mainloop()
3: Add this to your LoginFrame class:
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.master = master # add this
4: In the LoginFrame class change this:
BatchFrame.BatchFrame(root)
to this:
BatchFrame.BatchFrame(self.master)
I recommend importing batchframe instead of executing it.
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk as ttk
from batchframe import BatchFrame
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.master = master
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.photo = PhotoImage(file="icon.png")
self.label_image = Label(root, image=self.photo)
self.label_image.image = self.photo
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_username.grid(row=0, sticky=E)
self.label_password.grid(row=1, sticky=E)
self.label_image.grid(row=3, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)
self.entry_username.grid(row=0, column=1, sticky=E)
self.entry_password.grid(row=1, column=1, sticky=E)
self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2, column=1, row=2, sticky=S+E+N+W)
self.grid()
def _login_btn_clicked(self):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "123" and password == "123":
tm.showinfo("SBSHREG", "Welcome 123")
#The sweet spot where all goes wrong...
self.destroy()
# Create the instance of the BatchFrame class, passing in self.master
self.batchframe = BatchFrame(self.master)
else:
tm.showerror("SBSHREG", "Incorrect username")
Then in batchframe.py change variable reference from root to master

Scrollable frame will not render all items in it Python Tkinter

I am working on a program where there is a scrollable frame that will be containing a large quantity of items. But with my app it does not render all of them. Can someone possibly tell me why? And how I can fix it?
Code:
#700x650
from Tkinter import *
import ttk
class itemLoad:
def __init__(self):
pass
def item(self):
items = "Video File,Image File,None,King King"
return items
class App(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.pack(fill=BOTH)
self.loadItem = itemLoad()
self.one = None
self.create_widgets()
self.loadItems()
def create_widgets(self):
self.mainFrame = Frame(self, width=700, height=650)
self.mainFrame.pack_propagate(False)
self.mainFrame.pack()
self.menu = Frame(self.mainFrame, width=150, height=650, bg="Gray92")
self.menu.pack_propagate(False)
self.menu.pack(side=LEFT)
self.itemMenu = Frame(self.mainFrame, width=550, height=650)
self.itemMenu.pack_propagate(False)
self.itemMenu.pack(side=LEFT)
self.vScroller = ttk.Scrollbar(self.itemMenu, orient=VERTICAL)
self.vScroller.pack(side=RIGHT, fill=Y)
self.canvas = Canvas(self.itemMenu, bd=0, width=534, highlightthickness=0, yscrollcommand=self.vScroller.set)
self.canvas.pack_propagate(False)
self.canvas.pack(side=LEFT, fill=BOTH)
self.vScroller.config(command=self.canvas.yview)
self.innerFrame = Frame(self.canvas, width=550, height=650, bg="Pink")
self.canvas.create_window(0, 0, window=self.innerFrame, anchor=NW)
def update(event):
self.canvas.config(scrollregion=self.canvas.bbox("all"))
self.innerFrame.bind("<Configure>", update)
self.spacer = Frame(self.mainFrame, bg="Gray")
self.spacer.pack(side=LEFT, fill=Y)
frame = Frame(self.menu, bg="Gray92")
frame.pack(side=TOP, fill=X)
high = Frame(frame, bg="Gray92", width=10)
high.pack(side=LEFT, fill=Y)
self.bu1 = Label(frame, font=("Calibri", 14), text=" Main Folder", width=12, anchor=W, bg="Gray92")
self.bu1.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
frame2 = Frame(self.menu, bg="Gray92")
frame2.pack(side=TOP, fill=X)
high2 = Frame(frame2, bg="Gray92", width=10)
high2.pack(side=LEFT, fill=Y)
self.bu2 = Label(frame2, font=("Calibri", 14), text=" Favorited", width=12, anchor=W, bg="Gray92")
self.bu2.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
frame3 = Frame(self.menu, bg="Gray92")
frame3.pack(side=TOP, fill=X)
high3 = Frame(frame3, bg="Gray92", width=10)
high3.pack(side=LEFT, fill=Y)
self.bu3 = Label(frame3, font=("Calibri", 14), text=" Trash Can", width=12, anchor=W, bg="Gray92")
self.bu3.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
frame4 = Frame(self.menu, bg="Gray92")
frame4.pack(side=BOTTOM, fill=X)
high4 = Frame(frame4, bg="Gray92", width=10)
high4.pack(side=LEFT, fill=Y)
self.bu4 = Label(frame4, font=("Calibri", 14), text=" Log Out", width=12, anchor=W, bg="Gray92")
self.bu4.pack(side=LEFT, fill=X, ipadx=10, ipady=10)
def hover(event):
widg = event.widget
items = widg.winfo_children()
if items[1].cget("text") == self.one:
pass
else:
items[0].config(bg="Gray85")
items[1].config(bg="Gray85")
def unHover(event):
widg = event.widget
text = None
items = widg.winfo_children()
if items[1].cget("text") == self.one:
pass
else:
items[0].config(bg="Gray92")
items[1].config(bg="Gray92")
def clicked(event):
widg = event.widget
par = widg.winfo_parent()
par = self.menu._nametowidget(par)
for item in self.menu.winfo_children():
items = item.winfo_children()
items[0].config(bg="Gray92")
for item in par.winfo_children():
try:
self.one = item.cget("text")
except:
item.config(bg="lightBlue")
frame.bind("<Enter>", hover)
frame2.bind("<Enter>", hover)
frame3.bind("<Enter>", hover)
frame4.bind("<Enter>", hover)
frame.bind("<Leave>", unHover)
frame2.bind("<Leave>", unHover)
frame3.bind("<Leave>", unHover)
frame4.bind("<Leave>", unHover)
high.bind("<Button-1>", clicked)
self.bu1.bind("<Button-1>", clicked)
high2.bind("<Button-1>", clicked)
self.bu2.bind("<Button-1>", clicked)
high3.bind("<Button-1>", clicked)
self.bu3.bind("<Button-1>", clicked)
high4.bind("<Button-1>", clicked)
self.bu4.bind("<Button-1>", clicked)
def loadItems(self):
theItems = self.loadItem.item()
for i in range(0, 500):
none = Frame(self.innerFrame, width=200, height=500, bg="red")
none.pack_propagate(False)
none.pack(side=TOP, padx=10, pady=10)
let = Label(none, text=i)
let.pack(side=TOP)
root = Tk()
root.geometry("700x650")
root.resizable(0,0)
app = App(root)
root.mainloop()
I think you're exceeding the limits of the tkinter canvas. The frame you're trying to scroll is 250,000 pixels tall. I doubt the canvas can handle that.
When I make all of your inner widgets considerably smaller your code works fine.

python tkinter combobox/button

I just started to use python and tkinter, I have created a gui with two combobox and 'run' buttons which contain two different options 'SPMI' and 'RFFE'. What I want my script to do is, when I select different options and click 'run' it should run the SPMI.py or RFFE.py file.
Help please, Thanks
My code:
import sys
from Tkinter import *
def callback1():
os.system('SPMI.py')
def callback2():
os.system('RFFE.py')
class MyOptionMenu(OptionMenu):
def __init__(self, master, status, *options):
self.var = StringVar(master)
self.var.set(status)
OptionMenu.__init__(self, master, self.var, *options)
self.config(font=('calibri',(10)),bg='white',width=12,fg='dark red')
self['menu'].config(font=('calibri',(10)),bg='white',fg='dark blue')
b1_1 = Button(Dragonfly, text = "Run", fg='blue',command=callback1)
b1_1.place(x=85,y=150)
b2_2= Button(Dragonfly, text = "Run", fg='blue',command=callback2)
b2_2.place(x=275,y=150)
Dragonfly = Tk()
Dragonfly.geometry('400x400+400+300')
Dragonfly.title('Dragonfly')
mainlabel = Label(text='Dragonfly Trigger Test',font=('calibri',(14)),fg='dark blue').pack()
mymenu1 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI','RFFE')
mymenu2 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI','RFFE')
mymenu1.place(x=40,y=100)
mymenu2.place(x=230,y=100)
m1label = Label(text='Frame Trigger',font=('calibri',(12)),fg='dark green').place(x=57,y=60)
m1labe2 = Label(text='External Trigger',font=('calibri',(12)),fg='dark green').place(x=240,y=60)
Dragonfly.mainloop()
Use self.var.get() to get the value of the combobox.
You can then use that value inside the callback to make the callback's behavior depend on the combobox's setting.
import sys
from Tkinter import *
import subprocess
class MyOptionMenu(OptionMenu):
def __init__(self, master, status, *options):
self.var = StringVar(master)
self.var.set(status)
OptionMenu.__init__(self, master, self.var, *options)
self.config(
font=('calibri', (10)), bg='white', width=12, fg='dark red')
self['menu'].config(font=('calibri', (10)), bg='white', fg='dark blue')
def callback(self):
val = '{}.py'.format(self.var.get())
print(val)
# subprocess.call([val])
Dragonfly = Tk()
Dragonfly.geometry('400x400+400+300')
Dragonfly.title('Dragonfly')
mainlabel = Label(text='Dragonfly Trigger Test', font=('calibri', (14)),
fg='dark blue').pack()
mymenu1 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
b1_1 = Button(Dragonfly, text="Run", fg='blue', command=mymenu1.callback)
b1_1.place(x=85, y=150)
mymenu2 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
b2_2 = Button(Dragonfly, text="Run", fg='blue', command=mymenu2.callback)
b2_2.place(x=275, y=150)
mymenu1.place(x=40, y=100)
mymenu2.place(x=230, y=100)
m1label = Label(text='Frame Trigger', font=('calibri', (12)),
fg='dark green').place(x=57, y=60)
m1labe2 = Label(text='External Trigger', font=('calibri', (12)),
fg='dark green').place(x=240, y=60)
Dragonfly.mainloop()
By the way, building a GUI with place is easy at first, but cumbersome in the end. For one thing, as it grows it become harder and harder to change the layout since inserting a new widget will tend to require fiddling with hard-coded coordinates all over the place. Another problem is that the widget layout fails to adjust to changes in window size.
For those reasons, people tend to use pack or grid to layout widgets:
import sys
import Tkinter as tk
import subprocess
class MyOptionMenu(tk.OptionMenu):
def __init__(self, master, status, *options):
self.var = tk.StringVar(master)
self.var.set(status)
tk.OptionMenu.__init__(self, master, self.var, *options)
self.config(
font=('calibri', (10)), bg='white', width=12, fg='dark red')
self['menu'].config(font=('calibri', (10)), bg='white', fg='dark blue')
def callback(self):
val = '{}.py'.format(self.var.get())
print(val)
# subprocess.call([val])
Dragonfly = tk.Tk()
Dragonfly.geometry('400x400+400+300')
Dragonfly.title('Dragonfly')
Dragonfly.columnconfigure(0, weight=1)
Dragonfly.columnconfigure(1, weight=1)
mainlabel = tk.Label(text='Dragonfly Trigger Test', font=('calibri', (14)),
fg='dark blue').grid(row=0, column=0, columnspan=2, pady=20)
mymenu1 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
mymenu1.grid(row=2, column=0, pady=10, padx=10,)
b1_1 = tk.Button(Dragonfly, text="Run", fg='blue', command=mymenu1.callback)
b1_1.grid(row=3, column=0, pady=10, padx=10,)
mymenu2 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
mymenu2.grid(row=2, column=1, pady=10, padx=10,)
b2_2 = tk.Button(Dragonfly, text="Run", fg='blue', command=mymenu2.callback)
b2_2.grid(row=3, column=1, pady=10, padx=10,)
m1label = tk.Label(text='Frame Trigger', font=('calibri', (12)),
fg='dark green').grid(row=1, column=0, pady=10, padx=10,)
m1labe2 = tk.Label(text='External Trigger', font=('calibri', (12)),
fg='dark green').grid(row=1, column=1, pady=10, padx=10,)
Dragonfly.mainloop()

Categories