1

Good evening all,

Hope you are doing fine. I have an issue and I hope you could shed some light.

ERROR:

Exception in Tkinter callback

Traceback (most recent call last):

File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)

File "", line 69, in <lambda> self.mini_refresh.config(command=lambda: LaunchSiteFunction._launch_mini(self))

File "", line 42, in _launch_mini
    self.mac_mini_search_bar.send_keys(lambda:TmobileGUI._mac_mini_name_entry(self))

File "C:\Users\\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\remote\webelement.py", line 478, in send_keys
    {'text': "".join(keys_to_typing(value)),

File "C:\Users\\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\common\utils.py", line 150, in keys_to_typing
    for i in range(len(val)):
 
TypeError: object of type 'function' has no len()

Problem:

The problem occurred after changing Tkinter GUI code and Selenium code into a class. (I'm new to python, but I am trying to become familiar with classes).

Before:

  • I would type something in "mini_entry"
  • Hit refresh and Selenium would launch a website
  • Take the input from "mini_entry" (for example: W85FGSD9385)
  • Input that into the websites search bar
  • The website would return any info on W85FGSD9385

After:

  • I can type something into "mini_entry"
  • Hit refresh but Selenium now launches the website
  • Doesn't do anything.

Thanks in advance!


class LaunchSiteFunction:

    def _launch_mini(self):

        self.mini_site = webdriver.Chrome()
        self.mini_site.get('https://jamf-tools.apps.px-npe01.cf.t-mobile.com/mini_health/')
        self.mini_site.implicitly_wait(10)
        self.mac_mini_search_bar = self.mini_site.find_element_by_id('myInput')
        self.mac_mini_search_bar.clear()                                         
        self.mac_mini_search_bar.send_keys(lambda: GUI._mac_mini_name_entry(self)))
        self.mac_mini_search_bar.send_keys(Keys.RETURN)

class GUI:

    def run_program(self):
        root.title("Network GUI") 
        self._mac_mini_name_label()
        self._mac_mini_name_entry()
        self._mac_mini_refresh_button()
        self._mac_mini_output_label()

    # Lines mac mini section:
    def _mac_mini_name_label(self): 
        self.mini_label = tk.Label(program_frame, text='Mac Mini', bg='#ffffff', fg='#ea0a8e', font=('Calibre', 10))
        self.mini_label.place(relwidth=0.11, relheight=.1)

    def _mac_mini_name_entry(self):
        self.mini_entry = tk.Entry(program_frame, bg='#000000', fg='#ffffff', font=('Calibre', 10))
        self.mini_entry.place(relx=0.12, relheight=.1, relwidth=0.18)

    def _mac_mini_refresh_button(self):
        self.mini_refresh = tk.Button(program_frame, text='Refresh', bg='#000000', fg='#ea0a8e', font=('Calibre', 10))
        self.mini_refresh.place(relx=0.31, relheight=.1, relwidth=0.1)
        self.mini_refresh.config(command=lambda: LaunchSiteFunction._launch_mini(self))

    def _mac_mini_output_label(self):
        self.mini_output = tk.Label(program_frame, bg='#ffffff', bd='10')
        self.mini_output.place(relx=0.42, relheight=.1, relwidth=0.15)

if "__main__" == __name__:
run = GUI()
run.run_program()
root.mainloop()
1
  • @BryanOakley - noted, ty. Commented Aug 19, 2020 at 1:36

1 Answer 1

0

I don't have selenium to test this, but as long as your launch site overall logic was correct, this should fix it. All I did was reformat most of what you wrote and change 2 parts.

first part
This was wrong: lambda: GUI._mac_mini_name_entry(self)
This is right: self.mini_entry.get()

second part
All of this was wrong or strange.

if "__main__" == __name__:
run = GUI()
run.run_program()
root.mainloop()

In the example I gave you, App is the root. It extends root so, everything you do to it is being done directly to the root. That being said, the initialization becomes a lot cleaner.

if "__main__" == __name__:
    app = App()
    app.title("Network GUI")
    app.mainloop()

You will have to add in your selenium imports. You didn't post them, and I can't guess them. You will notice that all of your methods are gone and your LaunchSiteFunction class has been converted to a method on the root(App). In doing it this way, you don't have to juggle a bunch of remote data. Everything is a part of self and everything has access to self. You weren't doing anything that would qualify for a new class (like extending webdriver or something) so it all goes in App.

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        
        self.mini_label = tk.Label(self, text='Mac Mini', bg='#ffffff', fg='#ea0a8e', font=('Calibre', 10))
        self.mini_label.place(relwidth=0.11, relheight=.1)
        
        self.mini_entry = tk.Entry(self, bg='#000000', fg='#ffffff', font=('Calibre', 10))
        self.mini_entry.place(relx=0.12, relheight=.1, relwidth=0.18)
        
        self.mini_refresh = tk.Button(self, text='Refresh', bg='#000000', fg='#ea0a8e', font=('Calibre', 10))
        self.mini_refresh.place(relx=0.31, relheight=.1, relwidth=0.1)
        self.mini_refresh.config(command=self.launch_site)
        
        self.mini_output = tk.Label(self, bg='#ffffff', bd='10')
        self.mini_output.place(relx=0.42, relheight=.1, relwidth=0.15)
        
    def launch_site(self):
        self.mini_site = webdriver.Chrome()
        self.mini_site.get('https://jamf-tools.apps.px-npe01.cf.t-mobile.com/mini_health/')
        self.mini_site.implicitly_wait(10)
        self.mac_mini_search_bar = self.mini_site.find_element_by_id('myInput')
        self.mac_mini_search_bar.clear()                                         
        self.mac_mini_search_bar.send_keys(self.mini_entry.get())
        self.mac_mini_search_bar.send_keys(Keys.RETURN)


if "__main__" == __name__:
    app = App()
    app.title("Network GUI")
    app.mainloop()

ProTip:
Learn how to use pack() or grid(). You aren't doing yourself any favors with all that place().

Sign up to request clarification or add additional context in comments.

5 Comments

OMG, Michael thank you VERY MUCH! I appreciate this more than you know. I wanted to use place() because it felt more modular. (However, I am willing to learn to use pack() and grid() once I finalize this project). The goal later down the road is to add more websites too the GUI (Part of my job revolves around accessing different sites and having to verify systems if they are up, which is why I am trying to learn selenium to web scrap the information and then add the information in a nice GUI framework, versus having 10 tabs of chrome open). Making the edits tomorrow, again tyvm!
@WhatsTheIP ~ You're welcome. I have some odd fascination with fixing things that I cannot test. This one was pretty easy, but I still had fun. My recommendation would be to learn grid. I find it to be more straight-forward than pack. Others may disagree.
@ Michael Guidry -- I made the edits using your suggestion and everything works fine! I was wondering though--just so I can continue to learn--how come you integrated the class "launch mini site" and made it a function within the class "GUI"? Before asking I found this article: - stackoverflow.com/questions/23831504/… Would you create a function when it's to "do something" vs "being something" which makes sense why you moved the launch site class and remade it into a function instead.
@WhatsTheIP - the launcher was not a something. One way to evidence this is the class wasn't extending anything. Not all classes have to extend something, but your class was just using a couple of methods from a module ~ therefore it just "did a thing" instead of "is a thing".
@WhatsTheIP - maybe this would be easier to understand if I just say ~ what you perceive as a "launcher" is nothing but a ""send" method. Actually, you should even rename it send, because that's all it's doing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.