不同的进口导致不同的错误

时间:2017-12-27 03:32:27

标签: python python-3.x user-interface tkinter python-import

我正在使用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]

两个错误都有类似的回溯和文件路径,只是不同类型的错误。

1 个答案:

答案 0 :(得分:3)

要从另一个模块中的函数获取变量,它必须是全局的

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

但它不会像你期望的那样工作。

您在'start value'开始时会看到Label,因为text=reqrep_server.response只会将reqrep_server.response的值从text复制到mainloop一次 - 开始时 - 以后它不会自动复制。

单击按钮时,它将冻结GUI,因为它会阻止root.update()从系统获取键/鼠事件,将事件发送到窗口小部件,更新窗口小部件,重绘窗口小部件等。

你必须在主

中做两次思考
  • 使用mainloop强制label_rep['text'] = response执行一个循环。
  • 使用main更新标签
  • 中的文字

因此,按钮应使用rootlabel_rep使用lambda执行command=lambda:reqrep_server.main(root, label_rep) 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.py)

main

并且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) 必须使用它们

(reqrep_server.py)

main()

如果master.update()需要更多时间工作而main()执行频率会降低,那么它会再次冻结 - 然后您可能应该在已分段thread中运行.nav-pills{ display:flex; align-items:center; }