I am writing my own Library, so I can use some functions later faster and easier. At the moment, I am working with python's GUI Library Tkinter. (from tkinter include *)
def guiFrameNew(title, width, height):
guitmp = Tk();
return guitmp;
def guiTextboxReadonlyNew(frame, width, text):
guitmp = Entry(Frame, state="readonly", textvariable=text, width=width);
guitmp.pack();
return guitmp;
def guiFrameRun(frame):
frame.mainloop();
This all is in one file (file_one.py).
In an other file (file_two.py) i included this file:
include file_one as f
Code in file_two is:
main = f.guiFrameNew("Test", 0, 0);
main_tbro = f.guiTextboxReadonlyNew(main, 20, "Some Text");
f.guiFrameRun(main);
Yes, I know that I don't need the values Title, width, height in def guiFrameNew because the function does not create a frame.
After I started the file_two.py the python Interpreter says:
> File "file_two", line 5, in <module>
> main_tbro = f.guiTextboxReadonlyNew(main, 20, "Some Text"); File "/Users/MyUsername/Documents/py/file_two.py", line 190, in
> guiTextboxReadonlyNew
> guitmp = Entry(Frame, state="readonly", textvariable=text, width=width); File
> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py",
> line 2447, in __init__
> Widget.__init__(self, master, 'entry', cnf, kw) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py",
> line 2027, in __init__
> BaseWidget._setup(self, master, cnf) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py",
> line 2005, in _setup
> self.tk = master.tk AttributeError: class Frame has no attribute 'tk'
I don't know why, because the function def guiTextboxReadonlyNew(...) is similar to the function
def guiTextboxNew(frame, width):
guitmp = Entry(frame, width=width);
guitmp.pack();
return guitmp;
and def guiTextboxNew(...) works!
What is wrong in my file?
Assumming by include you mean import (which is really the case, since you are able to import the module file_one).
The Entry() takes a frame object as the first argument, not the Frame class. You should do -
def guiTextboxReadonlyNew(frame, width, text):
guitmp = Entry(frame, state="readonly", textvariable=text, width=width)
guitmp.pack()
return guitmp
Also, there is not really any need for ; (semi-colon) in python after statements.
Related
I want to create a class of Listbox object so that it can be used anywhere it is needed but it throws TypeError error, here is my code:
import tkinter as tk
class cls_list(tk.Listbox):
def __init__(self, master, callfrom):
tk.Listbox.__init__(self, master, callfrom)
callfrom.bind("<KeyRelease>", self.show_list)
def show_list(self, event):
x = callfrom.winfo_x()
y = callfrom.winfo_y()
h = callfrom.winfo_height()
self.place(x = x, y = y+h)
self.insert('end',*('Banana','Orange','Apple','Mango'))
if __name__ == '__main__':
root = tk.Tk()
ent = tk.Entry(root, font = (None, 20))
lst = cls_list(root, ent)
ent.pack()
root.mainloop()
Can someone correct me what I am doing wrong?
Here is complete Exception occurred:
File "/home/waheed/env_pinpoint/lib/python3.9/site-packages/test_listbox.py", line 5, in __init__
tk.Listbox.__init__(self, master, callfrom)
File "/usr/lib/python3.9/tkinter/__init__.py", line 3162, in __init__
Widget.__init__(self, master, 'listbox', cnf, kw)
File "/usr/lib/python3.9/tkinter/__init__.py", line 2566, in __init__
BaseWidget._setup(self, master, cnf)
File "/usr/lib/python3.9/tkinter/__init__.py", line 2537, in _setup
if 'name' in cnf:
File "/usr/lib/python3.9/tkinter/__init__.py", line 1652, in cget
return self.tk.call(self._w, 'cget', '-' + key)
TypeError: can only concatenate str (not "int") to str
This is what I have achieved so far.
import tkinter as tk
if __name__ == '__main__':
root = tk.Tk()
root.geometry('400x400')
ent = tk.Entry(root, font = (None, 20))
lst = tk.Listbox(root, font = (None, 20))
ent.pack()
ent.focus_set()
def hide_list(event):
index = int(lst.curselection()[0])
val = lst.get(index)
ent.delete(0,'end')
ent.insert(0,val)
lst.place_forget()
def show_list(event):
ent.update_idletasks()
x = ent.winfo_x()
y = ent.winfo_y()
h = ent.winfo_height()
lst.place(x = x, y = y+h)
items = ['Banana','Orange','Apple','Mango']
searchkey = ent.get()
lst.delete(0, "end")
for item in items:
if searchkey.lower() in item.lower():
lst.insert("end", item)
n = lst.size()
if n < 15:
lst.config(height = 0)
else:
lst.config(height = 15)
ent.bind("<KeyRelease>", show_list)
lst.bind("<<ListboxSelect>>", hide_list)
root.mainloop()
And now I want to make it an object (separate class) for using in multiple scripts.
I hope now I have explained my question properly.
The specific error you're asking about is caused because you're passing callfrom here: tk.Listbox.__init__(self, master, callfrom).
The listbox widget doesn't know what to do with callfrom, it expects the second positional argument to be a dictionary.
The proper way to initialize the class is without callfrom. You will need to save callfrom as an instance attribute if you need to use it outside of the __init__.
def __init__(self, master, callfrom):
tk.Listbox.__init__(self, master)
self.callfrom = callfrom
...
def show_list(self, event):
x = self.callfrom.winfo_x()
y = self.callfrom.winfo_y()
h = self.callfrom.winfo_height()
...
Hi I am pretty new to Tkinter. I am trying to create a listbox with a scroll bar and a couple buttons but I am getting an Attribute error. It seems somewhere I have overwritten master. Please help:
class advancedListBox:
def __init__(self, master, listBoxList, label, callbackFunction = None):
self.listBoxList = listBoxList
self.label = label
self.callbackFunction = callbackFunction
self.entryVar = tk.StringVar()
self.entryVar.set("Search")
self.entry = tk.Entry(master)
self.entry.config(textvariable = self.entryVar)
self.entry.grid(row = 0,sticky= "E"+"W")
self.entry.bind('<KeyPress>', self.listBox_On_keypress)
self.entry.bind('<KeyRelease>', self.listBox_On_keyrelease)
self.entryLabel = tk.Label(self.label)
self.entryLabel.grid(row = 1, column = 0, padx =(0,18))
self.listBox = tk.Listbox(master)
self.listBox.grid(row = 2, rowspan = 3, column = 0, sticky= "N"+"E"+"S"+"W")
self.listBox.bind('<<ListboxSelect>>', on_select)
self.listbox_update(self.listBoxList)
self.scrollbar = tk.Scrollbar(master, orient="vertical")
self.scrollbar.config(command=self.listBox.yview)
self.scrollbar.grid(row = 2, column = 1,rowspan = 3, sticky= "N"+"S")
self.listBox.config(yscrollcommand=scrollbar.set)
self.deleteButton = tk.Button(self.master, text="Delete",
command=lambda lb=architecturesListBox: deleteFromListBox(lb,tk.ANCHOR))
self.deleteButton.grid(row =5,sticky= "E"+"W"
)
Traceback (most recent call last):
File "c:/Users/Jerwin/Desktop/Jadon's Stuff/Jadon's Python Programs/List Boxes with delete and scrollbar.py", line 110, in
architecturesListBox = advancedListBox(root, architectures,"Name -- Pictures")
File "c:/Users/Jerwin/Desktop/Jadon's Stuff/Jadon's Python Programs/List Boxes with delete and scrollbar.py", line 22, in init
self.entryLabel = tk.Label(self.label)
File "C:\Users\Jerwin\AppData\Local\Programs\Python\Python37\lib\tkinter__init__.py", line 2766, in init
Widget.init(self, master, 'label', cnf, kw)
File "C:\Users\Jerwin\AppData\Local\Programs\Python\Python37\lib\tkinter__init__.py", line 2292, in init
BaseWidget._setup(self, master, cnf)
File "C:\Users\Jerwin\AppData\Local\Programs\Python\Python37\lib\tkinter__init__.py", line 2262, in _setup
self.tk = master.tk
AttributeError: 'str' object has no attribute 'tk'
self.label is a string. You're using it as the parent for a label when you do self.entryLabel = tk.Label(self.label). A string can't be the parent of a widget.
The first positional argument when creating a widget must be another widget, except in the case of creating the initial root window.
I actually have a big problem.
I already have a tkinter window and I want to open an other.
import Tkinter
from Tkinter import *
import threading, time
from PIL import Image, ImageTk
from record_pd import *
class Gui_Record(Tkinter.Tk):
def __init__(self, tkroot):
self.root = Tk()
self.root.title("Enregistreur")
#self.root.geometry()
self.root.geometry("%dx%d+%d+%d" % (500, 70, 400, 300))
self.root.c = Canvas(tkroot, bg='black')
self.root.c.pack(fill=BOTH, expand=YES)
self.initialize()
self.recorder = RecordPd(tkroot)
self.recorder.init_recorder()
def initialize(self):
#self.root.grid()
self.root.resizable(False, False)
self.Imgtmp = PhotoImage(file="img/record.png")
self.imgclear = PhotoImage(file="img/clear.png")
self.root.title = Tkinter.Label(self.root, text="Enregistreur Orgue Sensoriel", bg="black", fg="white", font=("Helvetica", 16))
self.root.title.pack()
self.root.button = Tkinter.Button(self, command=self.OnButtonClick, bg="black", bd=0)
self.root.button.config(highlightthickness=0)
self.root.button.config(activebackground="black")
self.root.button.config(image=self.Imgtmp)
self.root.button.pack()
self.root.bind("<Destroy>", self._onDestroy)
self.resume = True
self.activate = False
def setTkroot(self, tkroot):
self.tkroot = tkroot
def _onDestroy(self, e):
self.resume = False
self.recorder.stop_recording()
def OnButtonClick(self):
if (self.activate == False):
self.resume = True
self.recorder.open_wav()
self.recorder.start_recording()
thread = threading.Thread(target=self.threadClignoter)
thread.start()
self.activate = True
print("In recording..")
else:
self.stopThread()
self.recorder.stop_recording()
self.activate = False
def threadClignoter(self):
isVisible = True
while self.resume:
if isVisible:
clr = self.imgclear
else:
clr = self.Imgtmp
self.root.button.config(image=clr)
isVisible = not isVisible
time.sleep(0.5)
def stopThread(self):
print("Record done.")
self.resume = False
self.root.button.config(image=self.Imgtmp)
When I call my object I do:
rec = Gui_Record(self.tkroot)
rec.mainloop()
When I launch a single window it's okay. But when i add my new window to my parent window it happened that:
traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
return self.func(*args)
File "/home/naqued/Documents/assembla/backup/naqued-s-space/stido/gui_stido.py", line 139, in launch_recorder
app = Gui_Record(self.tkroot)
File "/home/naqued/Documents/assembla/backup/naqued-s-space/stido/record_gui.py", line 18, in __init__
self.initialize()
File "/home/naqued/Documents/assembla/backup/naqued-s-space/stido/record_gui.py", line 35, in initialize
self.root.button = Tkinter.Button(self, command=self.OnButtonClick, bg="black", bd=0)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2128, in __init__
Widget.__init__(self, master, 'button', cnf, kw)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2049, in __init__
BaseWidget._setup(self, master, cnf)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2022, in _setup
if not master:
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
return getattr(self.tk, attr
.... ... ... ... .. .. ...
return getattr(self.tk, attr)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
return getattr(self.tk, attr)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
return getattr(self.tk, attr)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
return getattr(self.tk, attr)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
return getattr(self.tk, attr)
RuntimeError: maximum recursion depth exceeded while calling a Python object
I don't do recursion on my code.
I don't know what happened and didn't find anything in the web.
You are creating a class that inherits from Tk, but it also creates a new instance of Tk, and even though you don't show it you're also creating another root at some point (the object being passed in as tkroot) I'm not sure if that's the only problem, but it's definitely a problem.
Since this is a secondary window, you shouldn't be inheriting from Tkinter.Tk. Instead, inherit from Tkinter.Toplevel
You also have the problem that even though this creates a new window as a child of tkroot, some of the internal widgets are being created as children of tkroot so they won't appear in this window.
You also need to fix your imports -- you shouldn't be doing a global import from Tk and also importing Tk as a module.
You're likely going to have other problems. Tkinter doesn't work well with threads. I've heard that it sometimes works on linux, but in general you should never call any GUI function from any thread other than the one in which the widget was created.
I am a newbie to python,I tried a Gui Application,but its resulting in error like:
Errors:
Traceback (most recent call last):
File "C:\Python27\aqw.py", line 22, in <module>
app = myproject(None,None)
File "C:\Python27\aqw.py", line 8, in __init__
self.button()
File "C:\Python27\aqw.py", line 13, in button
button = Tkinter.Button(self,text=u"Succedd !")
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2106, in __init__
Widget.__init__(self, master, 'button', cnf, kw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2027, in __init__
BaseWidget._setup(self, master, cnf)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2000, in _setup
if not master:
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1826, in __getattr__
return getattr(self.tk, attr)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1826, in __getattr__
return getattr(self.tk, attr)
Please help me to fix my code!
My code:
import Tkinter
from Tkinter import *
class myproject(Tkinter.Tk):
def __init__(self,parent, master):
self.button()
self.checkbox()
self.radiobutton()
def button(self):
#add quit button
button = Tkinter.Button(self,text=u"Succedd !")
button.grid(column=3,row=1)
def checkbox(self):
checkbox = Checkbutton(self, text = "Music", variable = CheckVar2)
checkbox.grid(column=3,row=1)
def radiobutton(self):
radiobutton = Tkinter.Radiobutton(self, text="Option 2", variable=var, value=2)
app = myproject(None,None)
app.mainloop()
Please help!Answers will be appreciated!
You need to call super class' __init__ method:
class myproject(Tkinter.Tk):
def __init__(self, parent, master):
Tkinter.Tk.__init__(self) # <----
self.button()
self.checkbox()
self.radiobutton()
...
In addition to that, there's undefined variables CheckVar2, var.
I'm new to python. I'm trying to open a dialog box to get a value from within a widget that does a list of other staff allready.
But getting errors and can't figure out what to do.
Here's my code:
import Tkinter,Tkconstants,tkFileDialog
from Tkinter import *
import csv
import numpy
import math
import numpy.random as nrnd
import matplotlib.pyplot as plt
import shutil
import tkMessageBox
global filesavepath
class App:
def __init__(self,master):
self.mymaster=master
frame=Frame(master)
frame.pack()
self.importbutton=Button(frame,text='Import Data',command=self.importdata)
self.importbutton.pack()
self.executebutton=Button(frame,text='Execute',command=self.popup)
self.executebutton.pack()
self.distribution_rep=Button(frame,text='Repeat Purchase Score Distribution',command=self.distrepbutton)
self.distribution_rep.pack()
self.distribution_churn=Button(frame,text='Churn Probability Distribution',command=self.distchurnbutton)
self.distribution_churn.pack()
self.exitbutton=Button(frame,text='Exit',command=self.exitapp)
self.exitbutton.pack()
self.file_opt=options={}
options['defaultextension']=''
options['filetypes']=[('allfiles','.*'),('textfiles','.txt')]
options['initialdir']='C:\\'
options['initialfile']='myfile.txt'
options['parent']=root
options['title']='Thisisatitle'
def importdata(self):
filename=tkFileDialog.askopenfilename(**self.file_opt)
filesavepath="C:/input_full.csv"
shutil.copy2(filename,filesavepath)
if filename:
return open(filename,'r')
def popup(self):
top = self.top = Tkinter.Toplevel(self)
myLabel = Tkinter.Label(top, text='Enter your username below')
myLabel.pack()
self.myEntryBox = Tkinter.Entry(top)
self.myEntryBox.pack()
mySubmitButton = Tkinter.Button(top, text='Done', command=self.execbutton)
mySubmitButton.pack()
def execbutton(self):
if self.myEntryBox.get() != "":
self.timevalue = self.myEntryBox.get()
self.top.destroy()
execfile("Repeat Purchase Algo in python v6")
tkMessageBox.showinfo("Job Done", "Probability Computation completed")
def send(self):
global timevalue
timevalue=self.myEntryBox.get()
self.top.destroy()
def distrepbutton(self):
plt.hist(prob,bins=10,normed=TRUE)
plt.xlabel('Probability')
plt.title('Histogram of Repeat Purchase Probability')
plt.show()
def distchurnbutton(self):
plt.hist(churn_prob,bins=10,normed=TRUE)
plt.ylabel('Probability')
plt.title('Histogram of Churn Probability')
plt.show()
def exitapp(self):
self.mymaster.destroy()
root=Tk()
root.title('Repeat Puchase Widget')
app=App(root)
root.mainloop()
So as may be apparent to you, I'm importing dataset with an Import button, executing some analysis in another code through a button called Execute, and then showing some graphs.
What I wanted was to open a pop up kind of window on click of "Execute" button that will input a value. But I'm getting the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:/Python27/widget_repeat_purchase_v4", line 42, in popup
top = self.top = Tkinter.Toplevel(self)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2017, in __init__
BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1965, in __init__
BaseWidget._setup(self, master, cnf)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1943, in _setup
self.tk = master.tk
AttributeError: App instance has no attribute 'tk'
I've no idea what to do. Please help.
When you create the toplevel widget, you are passing self as the first argument. Tkinter requires that this be a parent widget. However, in your code self does not represent a widget.
In your specific case you want to pass in self.mymaster rather than self:
top = self.top = Tkinter.Toplevel(self.mymaster)
Use Tkinter.Toplevel() instead of Tkinter.Toplevel(self)