不同的导入导致不同的错误
Different Imports Results in Different Errors
我正在使用 Tkinter 创建一个可以请求和接收消息的简单 GUI。
尝试在标签内显示消息,我试过这个:
from tkinter import *
from tkinter import ttk
from reqrep_server import *
root = Tk()
root.title("Server")
request = Button(root, text="Request")
request.grid(row=0, sticky=E)
request.bind("<Button-1>", main)
LabelRep = Label.config(root, text=response)
LabelRep.grid(row=1, sticky=E)
root.mainloop()
结果为:NameError: name 'response' is not defined
当我尝试时:
from tkinter import *
from tkinter import ttk
import reqrep_server
root = Tk()
root.title("Server")
request = Button(root, text="Request")
request.grid(row=0, sticky=E)
request.bind("<Button-1>", reqrep_server.main)
LabelRep = Label.config(root, text=reqrep_server.response)
LabelRep.grid(row=1, sticky=E)
root.mainloop()
发生这种情况:AttributeError: module 'reqrep_server' has no attribute 'response'
这只发生在 response
变量上,但不会发生在 main
函数上,因为它工作正常.
响应变量在 for 循环内:
reqrep_server
for request in range(1, 3):
print("Sending request ", request,"...")
socket.send_string("Sensor Data")
msg_json = socket.recv()
ds = json.loads(msg_json)
response = "Sensor: %s :: Data: %s :: Client: %s" % (ds['sensor'], ds['data'], ds['client'])
print("Received reply ", request, "[", response, "]")
time.sleep(1)
在main
方法中。
如何解决错误并使其正常工作?
编辑:
对于那些需要回溯的人:
Traceback (most recent call last):
File "C:\Users\tobiw\Documents\Python\Raspberry Pi\zmq\serverTTK.py", line 12, in <module>
LabelRep = Label.config(root, text=reqrep_server.response)
AttributeError: module 'reqrep_server' has no attribute 'response'
[Finished in 0.3s with exit code 1]
两个错误都有相似的回溯和文件路径,只是错误类型不同。
要从另一个模块中的函数获取变量,它必须是全局变量
(reqrep_server.py)
import time
response = 'start value' # <-- it is global variable
def main():
global response # <-- inform function to use global variable inside function
# (instead of local one)
for x in range(10):
response = str(x)
print(response)
time.sleep(1)
然后它将运行没有错误
(main.py)
import tkinter as tk
import reqrep_server
root = tk.Tk()
root.title("Server")
label_rep = tk.Label(root, text=reqrep_server.response)
label_rep.pack()
request = tk.Button(root, text="Request", command=reqrep_server.main)
request.pack()
root.mainloop()
但它不会像您预期的那样工作。
您会在开始时在 Label
中看到 'start value'
,因为 text=reqrep_server.response
仅将值从 reqrep_server.response
复制到 text
一次 - 在开始时 - 稍后不会自动复制这个。
当您单击按钮时,它会冻结 GUI,因为它会阻止 mainloop
从系统获取 key/mouse 事件、将事件发送到小部件、更新小部件、重绘小部件等。
你必须在 main 中进行两次思考
- 使用
root.update()
强制mainloop
执行一个循环。
- 使用
label_rep['text'] = response
更新标签中的文本
所以按钮应该使用 lambda
使用两个参数 root
和 label_rep
执行 main
command=lambda:reqrep_server.main(root, label_rep)
您将获得代码
(main.py)
import tkinter as tk
import reqrep_server
root = tk.Tk()
root.title("Server")
label_rep = tk.Label(root) # doesn't need text at start, text=reqrep_server.response)
label_rep.pack()
request = tk.Button(root, text="Request", command=lambda:reqrep_server.main(root, label_rep))
request.pack()
root.mainloop()
和main
必须使用它们
(reqrep_server.py)
import time
# doesn't need this: response = 'start value'
def main(master, label):
# doesn't need this: global response
for x in range(10):
response = str(x)
print(response)
label['text'] = response # <-- update label
master.update() # <-- run mainloop once
time.sleep(1)
如果 main()
需要更多时间来工作,而 master.update()
执行频率较低,那么它会再次冻结 - 然后也许你应该 运行 main()
分离 thread
.
我正在使用 Tkinter 创建一个可以请求和接收消息的简单 GUI。
尝试在标签内显示消息,我试过这个:
from tkinter import *
from tkinter import ttk
from reqrep_server import *
root = Tk()
root.title("Server")
request = Button(root, text="Request")
request.grid(row=0, sticky=E)
request.bind("<Button-1>", main)
LabelRep = Label.config(root, text=response)
LabelRep.grid(row=1, sticky=E)
root.mainloop()
结果为:NameError: name 'response' is not defined
当我尝试时:
from tkinter import *
from tkinter import ttk
import reqrep_server
root = Tk()
root.title("Server")
request = Button(root, text="Request")
request.grid(row=0, sticky=E)
request.bind("<Button-1>", reqrep_server.main)
LabelRep = Label.config(root, text=reqrep_server.response)
LabelRep.grid(row=1, sticky=E)
root.mainloop()
发生这种情况:AttributeError: module 'reqrep_server' has no attribute 'response'
这只发生在 response
变量上,但不会发生在 main
函数上,因为它工作正常.
响应变量在 for 循环内:
reqrep_server
for request in range(1, 3):
print("Sending request ", request,"...")
socket.send_string("Sensor Data")
msg_json = socket.recv()
ds = json.loads(msg_json)
response = "Sensor: %s :: Data: %s :: Client: %s" % (ds['sensor'], ds['data'], ds['client'])
print("Received reply ", request, "[", response, "]")
time.sleep(1)
在main
方法中。
如何解决错误并使其正常工作?
编辑:
对于那些需要回溯的人:
Traceback (most recent call last):
File "C:\Users\tobiw\Documents\Python\Raspberry Pi\zmq\serverTTK.py", line 12, in <module>
LabelRep = Label.config(root, text=reqrep_server.response)
AttributeError: module 'reqrep_server' has no attribute 'response'
[Finished in 0.3s with exit code 1]
两个错误都有相似的回溯和文件路径,只是错误类型不同。
要从另一个模块中的函数获取变量,它必须是全局变量
(reqrep_server.py)
import time
response = 'start value' # <-- it is global variable
def main():
global response # <-- inform function to use global variable inside function
# (instead of local one)
for x in range(10):
response = str(x)
print(response)
time.sleep(1)
然后它将运行没有错误
(main.py)
import tkinter as tk
import reqrep_server
root = tk.Tk()
root.title("Server")
label_rep = tk.Label(root, text=reqrep_server.response)
label_rep.pack()
request = tk.Button(root, text="Request", command=reqrep_server.main)
request.pack()
root.mainloop()
但它不会像您预期的那样工作。
您会在开始时在 Label
中看到 'start value'
,因为 text=reqrep_server.response
仅将值从 reqrep_server.response
复制到 text
一次 - 在开始时 - 稍后不会自动复制这个。
当您单击按钮时,它会冻结 GUI,因为它会阻止 mainloop
从系统获取 key/mouse 事件、将事件发送到小部件、更新小部件、重绘小部件等。
你必须在 main 中进行两次思考
- 使用
root.update()
强制mainloop
执行一个循环。 - 使用
label_rep['text'] = response
更新标签中的文本
所以按钮应该使用 lambda
root
和 label_rep
执行 main
command=lambda:reqrep_server.main(root, label_rep)
您将获得代码
(main.py)
import tkinter as tk
import reqrep_server
root = tk.Tk()
root.title("Server")
label_rep = tk.Label(root) # doesn't need text at start, text=reqrep_server.response)
label_rep.pack()
request = tk.Button(root, text="Request", command=lambda:reqrep_server.main(root, label_rep))
request.pack()
root.mainloop()
和main
必须使用它们
(reqrep_server.py)
import time
# doesn't need this: response = 'start value'
def main(master, label):
# doesn't need this: global response
for x in range(10):
response = str(x)
print(response)
label['text'] = response # <-- update label
master.update() # <-- run mainloop once
time.sleep(1)
如果 main()
需要更多时间来工作,而 master.update()
执行频率较低,那么它会再次冻结 - 然后也许你应该 运行 main()
分离 thread
.