【问题标题】:how to get input from a tkinter text widget when its inside a function如何在函数内部时从 tkinter 文本小部件获取输入
【发布时间】:2020-08-22 09:07:27
【问题描述】:

相对较新的编码,目前我在 python 中使用 tkinter,我在函数中使用文本小部件,并希望将输入从文本框发送到另一个函数。我的全局变量在模块级别未定义,那么如果它在函数内,我怎么能在模块级别定义它?

当我按下发送电子邮件按钮时,我收到此错误消息 “NameError: name 'user_message_entry' is not defined”

有什么建议吗?非常感谢!

最小复制:

import tkinter as tk

root = tk.Tk()
root.geometry("500x500")


def send_email():
    global user_message_entry
    subject = ":)"
    body = user_message_entry.get("1.0", "end")
    message = f"subject: {subject}\n\n {body}"
    print(message)


def feedback():
    feedback_window = tk.Toplevel()
    feedback_window.geometry("690x650")

    message_frame = tk.Frame(feedback_window)
    message_frame.grid(row=0, column=0, columnspan=3)
    user_message_entry = tk.Text(message_frame, height=10, width=60)
    user_message_entry.grid(row=0, column=0)

    send_email_button = tk.Button(feedback_window, command=send_email,
                                  height=20, width=20, bg="yellow", text="send email")
    send_email_button.grid(row=1, column=0)


open_feedback_button = tk.Button(root, command=feedback, height=20, width=20, bg="yellow", text="open feedback window")
open_feedback_button.grid(row=1, column=0)

root.mainloop()

【问题讨论】:

  • 你应该把global user_message_entry这一行移到feedback()
  • @acw1668 这可行,但global user_message_entry 仍然在模块级别显示未定义。我该如何排序?
  • 那么你最好将入口值作为参数传递给send_email()
  • 抱歉,您能详细说明一下吗?
  • def send_mail() 更改为def send_mail(entry)。然后send_email_button = tk.Button(..., command=lambda: send_email(user_message_entry), ...).

标签: python python-3.x tkinter global-variables tkinter-text


【解决方案1】:

您可以使用面向对象的方法来使访问更简单,另一种选择也可以使用 globals() 来使变量全局化

一种方式

globals()['user_message_entry'] = tk.Text(message_frame, height=10, width=60)

.... 

你可以从另一个函数调用

body = globals()['user_message_entry'].get("1.0", "end")

第二种方式

面向对象的编程适用于各种类型的问题解决,所以你也可以使用类

import tkinter as tk

class CBased:
    def __init__(self, master, *args, **kwargs):
        super(CBased, self).__init__(*args, *kwargs)
        self.master = master
        master.geometry("500x500")

        self.open_feedback_button = tk.Button(master, command=self.feedback, height=20, width=20, bg="yellow", text="open feedback window")
        self.open_feedback_button.grid(row=1, column=0)

    def send_email(self):
        subject = ":)"
        body = self.user_message_entry.get("1.0", "end")
        message = f"subject: {subject}\n\n {body}"
        print(message)


    def feedback(self):
        self.feedback_window = tk.Toplevel()
        self.feedback_window.geometry("690x650")

        self.message_frame = tk.Frame(self.feedback_window)
        self.message_frame.grid(row=0, column=0, columnspan=3)
        self.user_message_entry = tk.Text(self.message_frame, height=10, width=60)
        self.user_message_entry.grid(row=0, column=0)

        self.send_email_button = tk.Button(self.feedback_window, command=send_email,
                                  height=20, width=20, bg="yellow", text="send email")
        self.send_email_button.grid(row=1, column=0)

def main():
    root        = Tk()
    myobj       = CBased(root)
    root.mainloop()

if __name__ == "__main__":main()

这样你就可以通过self.xyz调用每一个项目

【讨论】:

  • 非常感谢,非常有帮助!是的,过了一段时间,我认为最好从一开始就使用类,但现在有很多要改变的地方:P 另外要添加到窗口中,我只会有 globals()['user_message_entry'].grid(row=0, column=0) ,这是正确的吗?
  • 你可以使用,如果它可以满足你的要求。快乐编码!
  • 那么有什么办法可以缩短 globals()['user_message_entry'] ...当我们在其他地方使用它时,例如滚动条?
  • 没有办法,但你可以通过面向对象的方式在课堂上。比如 self.e1 = ...,你可以用 self.e1 千次表示无限时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多