【问题标题】:Selenium--Python Not Taking Input From Tkinter Entry Widget--TypeError: object of type 'function' has no len()Selenium--Python 不从 Tkinter 条目小部件中获取输入--TypeError:“函数”类型的对象没有 len()
【发布时间】:2020-08-19 00:35:48
【问题描述】:

大家晚上好,

希望你一切都好。我有一个问题,希望你能解释一下。

错误:

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()

问题:

将 Tkinter GUI 代码和 Selenium 代码更改为类后出现问题。 (我是 python 新手,但我正在努力熟悉类)。

之前:

  • 我会在“mini_entry”中输入一些内容
  • 点击刷新,Selenium 将启动一个网站
  • 从“mini_entry”获取输入(例如:W85FGSD9385)
  • 将其输入网站搜索栏
  • 该网站将返回有关 W85FGSD9385 的任何信息

之后:

  • 我可以在“mini_entry”中输入一些内容
  • 点击刷新,但 Selenium 现在启动网站
  • 什么都不做。

提前致谢!


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()

【问题讨论】:

  • @BryanOakley - 注意到,ty。

标签: python selenium selenium-webdriver tkinter


【解决方案1】:

我没有selenium 来测试这个,但只要你的launch site 整体逻辑是正确的,这应该可以解决它。我所做的只是重新格式化您编写的大部分内容并更改 2 个部分。

第一部分
这是错误的:lambda: GUI._mac_mini_name_entry(self)
没错:self.mini_entry.get()

第二部分
所有这些都是错误或奇怪的。

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

在我给你的例子中,Approot。它扩展了root,因此,您对它所做的一切都直接在root 上完成。话虽如此,初始化变得更加清晰。

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

您必须添加 selenium 导入。你没有发布它们,我猜不出来。你会注意到你所有的方法都消失了,你的LaunchSiteFunction 类已经转换为root(App) 上的一个方法。通过这种方式,您不必处理一堆远程数据。一切都是self 的一部分,一切都可以访问self。你没有做任何有资格获得新课程的事情(比如扩展 webdriver 或其他东西),所以这一切都在 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()

专业提示:
了解如何使用 pack()grid()place() 对你没有任何好处。

【讨论】:

  • 天啊,迈克尔,非常感谢你!我比你知道的更感激这一点。我想使用 place() 因为它感觉更加模块化。 (但是,一旦我完成了这个项目,我愿意学习使用 pack() 和 grid())。以后的目标是在 GUI 上添加更多网站(我的部分工作围绕访问不同的网站并必须验证系统是否启动,这就是为什么我试图学习 selenium 以网络废弃信息然后在一个漂亮的 GUI 框架中添加信息,而不是打开 10 个 chrome 选项卡)。明天再编辑,tyvm!
  • @WhatsTheIP ~ 不客气。我对修复我无法测试的东西有一些奇怪的迷恋。这个很简单,但我还是玩得很开心。我的建议是学习grid。我发现它比pack 更直接。其他人可能不同意。
  • @Michael Guidry -- 我根据您的建议进行了编辑,一切正常!不过我想知道——只是为了继续学习——你是如何集成“启动迷你站点”类并使其成为“GUI”类中的一个功能的?在询问之前,我发现了这篇文章:-stackoverflow.com/questions/23831504/… 你会在“做某事”与“做某事”时创建一个函数吗?这很有意义,为什么你移动了启动站点类并将其重新制作成一个函数。
  • @WhatsTheIP - 启动器不是什么东西。证明这一点的一种方法是该类没有扩展任何东西。并非所有类都必须扩展某些东西,但您的类只是使用模块中的几个方法〜因此它只是“做了一件事”而不是“是一件事”。
  • @WhatsTheIP - 如果我只是说〜你认为“启动器”只不过是一种“发送”方法,也许这会更容易理解。实际上,你甚至应该重命名它@987654345 @,因为这就是它所做的一切。
猜你喜欢
  • 2014-07-01
  • 2015-01-21
  • 2021-10-21
  • 2021-03-03
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多