Reputation: 257
Could anyone advise me what's wrong go with the following code? I try to build a tkinker.listbox with dimensions can be changed with .config command, yet failed. Instead, it produce the error of "AttributeError: 'MovListbox' object has no attribute 'tk'" The code is attached below for your reference.
Many thanks.
import tkinter
def test():
root = tkinter.Tk()
list = [' 1','2',' 3','4','5',' 6','7','8',' 9','10']
a = MovListbox(root, list)
a._setup_style(200, 200, EXTENDED)
class MovListbox(tkinter.Listbox):
def __init__(self, master=None, inputlist=None):
# super(MovListbox, self).__init__()
global NewsClassify_catList
NewsClassify_catList = tkinter.Listbox(master)
NewsClassify_catList.grid(row = 0 , column = 0, columnspan=2, sticky=N)
'''populate the news category onto the listbox'''
for i in range (0, inputlist.__len__()):
NewsClassify_catList.insert(END, inputlist[i])
master.mainloop()
def _setup_style(self, height=100, width=100, mode=EXTENDED):
self.config(height=height, width=width, selectmode=mode)
if __name__ == '__main__':
test()
Upvotes: 0
Views: 3490
Reputation: 55469
I've made a few modifications to your code; it's probably not exactly what you want, but you should find it helpful.
The Listbox width and height options are not pixel measurements; they specify dimensions in terms of characters, so height=12
makes the Listbox 12 text lines high, and width=40
makes the Listbox 40 characters wide.
import tkinter as tk
def test():
root = tk.Tk()
lst = [' 1', '2', ' 3', '4', '5', ' 6', '7', '8', ' 9', '10']
a = MovListbox(root, lst)
a.grid(row=0, column=0, columnspan=2, sticky=tk.N)
a.setup_style(12, 40, tk.EXTENDED)
root.mainloop()
class MovListbox(tk.Listbox):
def __init__(self, master=None, inputlist=None):
super(MovListbox, self).__init__(master=master)
# Populate the news category onto the listbox
for item in inputlist:
self.insert(tk.END, item)
def setup_style(self, height=10, width=20, mode=tk.EXTENDED):
self.config(height=height, width=width, selectmode=mode)
if __name__ == '__main__':
test()
If you like, you can remove the a.setup_style(12, 40, tk.EXTENDED)
call in test()
and instead do
self.setup_style(12, 40, tk.EXTENDED)
at the end of the MovListbox.__init__()
method.
I've changed your list
variable to lst
. list
is not a good choice for a variable name as that shadows the built-in list
type, which can be confusing, and it can also lead to mysterious bugs.
The super
built-in function is used to access methods of the parent class. From the docs:
super([type[, object-or-type]])
Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is the same as that used by getattr() except that the type itself is skipped.
Thus
super(MovListbox, self).__init__(master=master)
says to call the __init__
method of the parent class of the MovListbox class, in other words, the tk.Listbox.__init__
method. We need to do this because MovListbox is derived from tk.Listbox and we need all the usual Listbox stuff to be set up for our MovListbox instance before we start doing extra stuff with it, like inserting the strings from inputlist
.
If a derived class doesn't define its own __init__
method then the __init__
method from the parent is called automatically when you create an instance of the derived class. But because we've defined an __init__
method for MovListbox that new __init__
gets called instead. So to get the usual Listbox initialization performed for MovListbox we need to manually call Listbox's __init__
, and the customary way to do that gracefully is to use super
.
Actually, in Python 3, that super
call can be simplified:
super().__init__(master)
The form I used earlier is necessary in Python 2. However, super
only works on new-style classes (the only kind of class that Python 3 supports), but unfortunately Python 2 Tkinter uses the ancient old-style classes for its widgets, and calling super
on such classes raises a TypeError
exception. :( When working with old-style classes we have to do the call by explicitly specifying the parent class, like this:
tk.Listbox.__init__(self, master)
That syntax is also valid in Python 3, but it's generally preferred to use super
when it's available.
Upvotes: 2