I am relatively new to OOP and I have a problem with my code. In an attempt to arrange my code, I would like to save functions in separate files (here menu.py) and then initialize them through def __init__(self): in class (file name app.py) (better than trying to understand my weird description is to look directly on my code ☻). It returns AttributeError and I have no clue how to repair it. Can anyone help me please? (P.S. if you understand what I am trying to do and you know better way how to do that, please tell me ☻)
app.py
import tkinter
from tkinter import *
from menu import Menu
class App(Menu):
def __init__(self):
self.root = tkinter.Tk()
...
self.Menu_Bar()
...
self.root.mainloop()
menu.py
import tkinter
from tkinter import *
class Menu():
def Menu_Bar(self):
self.menuBar = Menu(self.root)
self.menuBar.add_cascade(label="File", menu = self.fileMenu)
...
self.root.config(menu = self.menuBar)
AttributeError: 'App' object has no attribute 'Menu_Bar'
Related
I have created a simple tKinter Gui with PAGE builder and I am able to click a button and execute the corresponding command function within it. But when I try to get a value of a specific text box within the function I get various errors mostly no such property found. I have tried adding self and the class name into the property and even passing the property from the class as well as making it a function within that class but I still can't seem to access the values of the textbox 'Username'. I would really appreciate any help on how to get those text box values within the function as I have been researching for hours but still cannot make it work. Also if anyone knows of any good tutorial on this topic would help tremendously. Thank you.
The project has 2 files: (I've tried to remove the non essential code)
MacUpdaterPageDesign.py
import sys
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.constants import *
import os.path
_script = sys.argv[0]
_location = os.path.dirname(_script)
import MacUpdaterPageDesign_support
class Toplevel1:
def __init__(self, top=None):
top.title("Mac Updater")
top.configure(background="#d9d9d9")
self.top = top
self.MainFrame = tk.Frame(self.top)
self.MainFrame.place(relx=0.0, rely=0.18, relheight=0.811
, relwidth=1.099)
self.Username = tk.Text(self.MainFrame)
self.Username.place(relx=0.15, rely=0.081, relheight=0.048
, relwidth=0.279)
#this button calls the CopyMACfunc on the support page
self.CopyMAC = tk.Button(self.MainFrame)
self.CopyMAC.place(relx=0.143, rely=0.846, height=34, width=117)
self.CopyMAC.configure(command=MacUpdaterPageDesign_support.CopyMACfunc)
self.CopyMAC.configure(text='Copy MAC')
MacUpdaterPageDesign_support.py
import sys
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.constants import *
import MacUpdaterPageDesign
def main(*args):
'''Main entry point for the application.'''
global root
root = tk.Tk()
root.protocol( 'WM_DELETE_WINDOW' , root.destroy)
# Creates a toplevel widget.
global _top1, _w1
_top1 = root
_w1 = MacUpdaterPageDesign.Toplevel1(_top1)
root.mainloop()
def CopyMACfunc(*args):
#this part must retrieve the value in from Username
#tried many variations of below but throws error
username = MacUpdaterPageDesign.Username.get("1.0",END)
print(username)
if __name__ == '__main__':
MacUpdaterPageDesign.start_up()
Actually while writing this question I finally got it to work:
username = _w1.Username.get("1.0",END)
it did work with the following but not sure if this would be the right way to do it per say. Maybe their are better ways if anyone knows. Also would appreciate any recommendation for a good tutorial or where to learn all of this type of info. Thanks
When I run my Tkinter code the results end up giving me two Tkinter windows. One has the widgets/items my code says but one is a completely blank window.
file 1-
from tkinter import*
class Screen:
def __init__(self, items):
self.Tk = Tk()
self.items = items
self.Tk.mainloop()
file 2-
from tkinter import*
from Screen import*
class Module1:
def __init__(self):
Test_button = Button(text="Test")
Test_button.pack()
items = Module1()
Mainscreen = Screen(items)
I just want to make a modular Tkinter screen so my code is not that messy 😅
-Just want one/common Tkinter window
I think the trouble is you're going about things backwards a bit. You'll want to import your modules into the Python file containting your "root" window class (aka Screen), rather than the other way around.
The typical way to handle a "root" window class in tkinter usually looks like this, where the class inherits directly from Tk()
# this is the first file...
import tkinter as tk # avoid star imports!
from file2 import Module1 # import your widget classes here
# note that depending on your project structure you may need to do
# 'from .file2 import Module1' instead (this is called a 'relative import')
class Screen(tk.Tk): # the 'Screen' class inherits from 'tk.Tk'
def __init__(self):
super().__init__() # initialize tkinter.Tk()
# instance your module widgets by calling the class like so
# (you'll need to update Module1 as shown below here)
self.mod1 = Module1(self) # 'self' refers to 'Screen', the main window
You'll need to update the Module1 class so it can be bound to your parent Screen
# this is the second file...
import tkinter as tk # again, star imports bad...
class Module1:
def __init__(self, parent): # add the parent parameter
# whenever you instance your 'Module1' class, it will expect a 'parent';
# above, we used self (i.e. 'Screen') - this is where your 'button' is going!
self.parent = parent
test_button = tk.Button(self.parent, text="Test")
test_button.pack()
And you'll run the mainloop() method on an instance of your Screen class at the end of your main Python file like so
# this is the first file again...
if __name__ == '__main__': # if this script is being run at the top level...
app = Screen() # get an instance of your Screen class
app.mainloop() # run the GUI loop
I am writing a Tkinter application that requires parts of the user display to exist in two different class, both imported from another file. I need to take a piece of user input and pass it from one class to another. In the toy example below, the user is supposed to type something into my_entry_input which later the class PullVariable is supposed to access.
Code is below. I had a few thoughts, such as somehow using globals or creating a function within the original class to get the variables and then pass them back. In all cases, I get:
AttributeError: type object 'Application' has no attribute 'my_entry'
The best solution I can think of is to create a function that responds to the binding, then pass the .get() to the other class from that function. My feeling is that tkinter doesn't like .get() in between classes.
Thanks to the community for your help.
MAIN
from import_test1 import *
root=Tk()
ui = Application(root)
ui.hello_world()
ui.entry()
pv = PullVariable()
if __name__ == '__main__':
root.mainloop()
IMPORTED CODE
from tkinter import *
from tkinter import ttk
class Application(Frame):
def __init__(self, parent, *args, **kwargs):
print('Application init')
Frame.__init__(self, parent, *args, **kwargs)
self.parent=parent
self.parent.grid()
def entry(self):
self.my_entry = StringVar(self.parent)
my_entry_input = Entry(self.parent, textvariable=self.my_entry,
width=16)
my_entry_input.bind('<FocusOut>', self.show_entry)
my_entry_input.grid(column=0, row=1)
self.show_label = Label(self.parent, text = '')
self.show_label.grid(column=0, row=2)
def hello_world(self):
print('hello world')
self.hw = Label(self.parent, text='Hello World!')
self.hw.grid(column=0, row=0)
def show_entry(self, event):
PullVariable(Application).find_entry()
class PullVariable:
def __init__(self, app):
self.app = app
print('Pull initiated')
def find_entry(self, event=None):
self.pulled_entry = self.app.my_entry.get()
self.app.show_label['text'] = self.pulled_entry
my_entry is not a attribute of Application class, so you can't do Application.my_entry, by it is an attribute of instance of Application class, so you can do Application().my_entry. You can probably add either instance of Application or my_entry to the __init__ method of PullVariable. I'll use the former.
# ...
class PullVariable:
def __init__(self, app): # add app here
self.pulled_entry = app.my_entry.get() # use app here
print(self.pulled_entry)
# and then
root=Tk()
ui = Application(root)
ui.hello_world()
ui.entry()
pv = PullVariable(ui) # supply PullVariable with instance of Application
I am currently stuck on a problem with Python and Tkinter.
I want to create a simple application with its UI made on Tkinter. To do so, I created a class to define my application and I want to create my GUI layout in a separate class function.
However, when I call it, it has no effect on my Tk window (in this particular example, the title is not modified)
Here is the code
from Tkinter import *
fen =Tk()
class test_Tk_class:
def __init__(self):
self.make_title
def make_title(self):
fen.title("Test")
a = test_Tk_class()
fen.mainloop()
Thanks for any help !
You're missing () after self.make_title:
from Tkinter import *
fen =Tk()
class test_Tk_class:
def __init__(self):
self.make_title() # <------------
def make_title(self):
fen.title("Test")
a = test_Tk_class()
fen.mainloop()
I learned the book "programming python' these days. When I run the examples, I met the problem. The shell showed me the error:
AttributeError: 'NoneType' object has no attribute 'pack'
However, I copy the exactly code from the book. I'm a freshman of Python. I try to fix it by myself, but I failed. So I hope anyone could kindly help me.
Thanks !!!!!!
CODE:
#File test.py
from tkinter import *
from tkinter.messagebox import showinfo
def MyGui(Frame):
def __init__(self, parent = None):
Frame.__init__(self, parent)
button = Button(self, text='press', command=reply)
button.pack()
def reply(self):
showinfo(title = 'popup',message ='Button pressed!')
if __name__ == '__main__':
window = MyGui()
window.pack()
window.mainloop()
#File test2.py
from tkinter import *
from test import MyGui
mainwin = Tk()
Label(mainwin,text = __name__).pack()
popup = Toplevel()
Label(popup,text = 'Attach').pack(side = LEFT)
MyGui(popup).pack(side=RIGHT)
mainwin.mainloop()
You can fix this with the following code:
#File test.py
from tkinter import *
from tkinter.messagebox import showinfo
class MyGui(Frame):
def __init__(self, parent = None):
Frame.__init__(self, parent)
button = Button(self, text='press', command=self.reply)
button.pack()
def reply(self):
showinfo(title = 'popup',message ='Button pressed!')
if __name__ == '__main__':
window = MyGui()
window.pack()
window.mainloop()
Basically two small syntax errors. First you were trying to make a class of MyGui, but you used keyword def which made a function instead (that returned None, hence the error you received.) It is syntaxically correct in python to define functions inside of functions so it was a little harder to catch. You have to use the keyword class to define a class.
Secondly when referencing the function reply you must use self.reply within the class itself.