Posts: 20
Threads: 5
Joined: Dec 2018
This is how my app looks like in the image below
WHAT I AM TRYING TO DO:
I am trying to create a desktop app using tkinter where I have a Entry (Textbox) to enter a module name and press on a button which calls a function that does dir(given_module_name) and displays the list in a Listbox.
Questions:
1) Somehow, when I first run my program, the Listbox is automatically being populated before pressing the button. I am not sure why this is happening.
2) When I click on the button, nothing is happening. Why
I am noob in python and I am sure I am doing something wrong somewhere but not able to figure out where.
Thanks,
Om
Here is my code:
from tkinter import *
window = Tk()
window.title("Python Help")
def lib_func(lib):
print("Entered lib_func()----->")
func_list = dir(lib)
for item in func_list:
list1.insert(END, item)
#lib_name="os"
#lib_funcs(lib_name)
text_label = Label(window,text="Enter lib")
text_label.grid(row=0,column=0)
str_var=StringVar()
#print("str_val type is: ",type(str_var)) #str_val type is: <class 'tkinter.StringVar'>
# This part is confusing where the text typed in text_entry is fetched from str_val
text_entry = Entry(window,textvariable=str_var)
text_entry.grid(row=0, column=1)
list1=Listbox(window, height=30,width=35)
list1.grid(row=2,column=0,rowspan=6,columnspan=2)
enter_button = Button(window,text="Enter",command=lib_func(str_var.get()))
enter_button.grid(row=0,column=2)
window.mainloop()
Posts: 4,784
Threads: 76
Joined: Jan 2018
Use command=lambda: lib_func(str_var.get()) . The lib_func needs to be executed when you press the button, not when the button is created.
Posts: 536
Threads: 0
Joined: Feb 2018
Use partial to send args to a function from a button call. Your code calls lib_func when the button is created. from functools import partial
...
enter_button = Button(window,text="Enter",
command=partial(lib_func, str_var.get()))
Posts: 20
Threads: 5
Joined: Dec 2018
Dec-06-2018, 05:21 PM
(This post was last modified: Dec-06-2018, 05:40 PM by omm.)
(Dec-06-2018, 11:01 AM)Gribouillis Wrote: Use command=lambda: lib_func(str_var.get()) . The lib_func needs to be executed when you press the button, not when the button is created.
Thanks for your help. Using Lambda helped in executing the function only when the button is pressed. But, somehow dir() is not outputing according to the text we provide. Instead, it is populating of what we get when we do dir("any string")
>>> dir("nonsense")
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] Irrespective of what we provide, it is inly populating the above.
I have imported os and sqlite3 module which has to work when provide in the textbox and when the button is pressed (but is not working). I can at least see that the value being passed to the textbox is printed when executing the function. Thanks.
Here is my updated code:
from tkinter import *
from functools import partial
import os,sqlite3
window = Tk()
window.title("Python Help")
def lib_func(lib):
print("Entered lib_func()----->")
print("dir(",lib,") is ")
func_list = dir(lib)
for item in func_list:
list1.insert(END, item)
#print(item)
#list1.insert(END, func_list)
#print("func_type type is: ",type(func_list))
#print("Lib is: ",lib)
#print(func_list)
#return func_list
#lib_name="os"
#lib_funcs(lib_name)
text_label = Label(window,text="Enter lib")
text_label.grid(row=0,column=0)
str_var=StringVar()
#print("str_val type is: ",type(str_var)) #str_val type is: <class 'tkinter.StringVar'>
# This part is confusing where the text typed in text_entry is fetched from str_val
text_entry = Entry(window,textvariable=str_var)
text_entry.grid(row=0, column=1)
list1=Listbox(window, height=30,width=35)
list1.grid(row=2,column=0,rowspan=6,columnspan=2)
enter_button = Button(window,text="Enter",command=lambda:lib_func(str_var.get()))
#enter_button = Button(window,text="Enter",
# command=partial(lib_func, str_var.get()))
enter_button.grid(row=0,column=2)
window.mainloop()
(Dec-06-2018, 11:01 AM)woooee Wrote: Use partial to send args to a function from a button call. Your code calls lib_func when the button is created.from functools import partial
...
enter_button = Button(window,text="Enter",
command=partial(lib_func, str_var.get()))
Thanks for the help. Now the function gets executed only when button is pressed. I have tried the suggested code but, somehow, when the func is executed, the lib(text) is not being passed. Still trying to figure out. I see that the Listbox is being populated with the output of dir("some string") irrespective of what text we provide.
Thanks,
Om
Posts: 3,458
Threads: 101
Joined: Sep 2016
(Dec-06-2018, 05:21 PM)omm Wrote: enter_button = Button(window,text="Enter",command=lambda:lib_func(str_var.get())) If you want the StringVar, why not just pass str_var ? str_var.get() returns whatever's currently in the stringvar... as a string. Calling dir() on a string is apparently not what you want to do.
Posts: 20
Threads: 5
Joined: Dec 2018
(Dec-06-2018, 06:30 PM)nilamo Wrote: (Dec-06-2018, 05:21 PM)omm Wrote: enter_button = Button(window,text="Enter",command=lambda:lib_func(str_var.get())) If you want the StringVar, why not just pass str_var ? str_var.get() returns whatever's currently in the stringvar... as a string. Calling dir() on a string is apparently not what you want to do.
Thanks for looking into it. I have tried passing str_var instead of str_var.get() but no luck as I guess, it is of type tkinter.StringVar
Entered lib_func()----->
dir( PY_VAR0 ) is
lib type is: <class 'tkinter.StringVar'> Any other suggestions?
Posts: 8,156
Threads: 160
Joined: Sep 2016
Dec-11-2018, 12:25 PM
(This post was last modified: Dec-11-2018, 12:25 PM by buran.)
def lib_func(lib=None):
print("Entered lib_func()----->")
if not lib:
lib = str_var.get()
for item in dir(lib):
list1.insert(END, item)
# some otehr code
enter_button = Button(window,text="Enter",command=lib_func) of course you can drop lib parameter of the function altogether
Posts: 20
Threads: 5
Joined: Dec 2018
SOLUTION FOUND:
dir() accepts Object parameter butI was passing Stringtype which wasn't working. So, finally, I have changed the argument lib being passed to dir() as Object.
I have added the following line before passing the argument and is working now
lib = eval(lib)
Posts: 4,784
Threads: 76
Joined: Jan 2018
Dec-11-2018, 08:09 PM
(This post was last modified: Dec-11-2018, 08:09 PM by Gribouillis.)
If lib is a module name, you would be better off with
lib = importlib.import_module(lib) You could also catch ImportError and report it in the GUI if there is no such module.
|