我想将一个值从一个函数传递或存储到一个变量,然后使用该变量放入一个标签.

我try 将全局赋值赋给变量,但出现错误:未定义名称‘num’.你的意思是:‘总和’?

global num


def takeWeight():
    ser = serial.Serial('COM3', 57600, timeout=1)

    while True:
        line = ser.readline()  # read a byte
        if line:
            num = line.decode().strip()  
            print(num)
    ser.close()


weightDisplay = ttk.Label(startScan_frame, text=num)
weightDisplay.grid(column=2, row=4)
weightDisplay.grid_configure(pady=20)

推荐答案

所以你走上了正确的道路!但你对全球的看法有点错误. 您定义的任何outside a function变量都存在于全局作用域中.您可以使用关键字global inside您的函数来允许该函数修改该全局变量的值

def takeWeight():
    global num  # allow this function to modify the value of 'num'
    ser = serial.Serial('COM3', 57600, timeout=1)

    while True:
        line = ser.readline()  # read a byte
        if line:
            num = line.decode().strip()  
            print(num)
    ser.close()


num = ''  # declare 'num' as a placeholder in the global scope
weightDisplay = ttk.Label(startScan_frame, text=num)
weightDisplay.grid(column=2, row=4)
weightDisplay.grid_configure(pady=20)

也就是说,由于这是tkinter,您真正想要的是将您的Labeltextvariable属性绑定到tk.StringVar()

那么这意味着什么呢?

def takeWeight():
    ser = serial.Serial('COM3', 57600, timeout=1)

    while True:
        line = ser.readline()  # read a byte
        if line:
            num.set(line.decode().strip())  # call 'set' to update the value of 'num'
            print(num.get())  # call 'get' to retrieve the current value of 'num'
    ser.close()


num = tk.StringVar()  # create an instance of 'StringVar' to store your value
# and then bind that variable to your label - this way, whenever you update 'num'
# using 'num.set('whatever'), your label will update automatically!
weightDisplay = ttk.Label(startScan_frame, textvariable=num)
weightDisplay.grid(column=2, row=4)
weightDisplay.grid_configure(pady=20)

到目前一切尚好!不幸的是,您在这里仍然会遇到一个问题,因为While循环!阻塞操作和循环不能很好地处理tkinter,并且会导致您的图形用户界面挂起.幸运的是,这也是可以修复的!

Tkinter有一个名为after的方法,它允许您基本上将函数调用插入到图形用户界面事件循环中.这样,您可以轮询您的串口的新信息,同时保持您的图形用户界面运行.您只需修改takeWeight即可使用after

# 'ser' doesn't need to be declared *every* time 'takeWeight' is called,
# so let's move it into the global scope (this also lets us refer to 'ser'
# in the 'close' method described below!)
ser = serial.Serial('COM3', 57600, timeout=1)
# let's also declare a placeholder that will store the id of the 'after' call
serial_loop_id = None


def takeWeight():
    global serial_loop_id
    line = ser.readline()  # read a byte
    if line:
        num.set(line.decode().strip())
    # use 'after' to call this function again after 100mS
    serial_loop_id = root.after(100, takeWeight)

请注意,现在takeWeight不再调用ser.close()--您必须稍微改变一下处理方式!在本例中,您可以只定义一个close函数来停止takeWeight循环,然后调用ser.close.你准备好了就打close().

def close():
    root.after_cancel(serial_loop_id)  # stop the 'takeWeight' polling loop
    ser.close()  # close the serial port

注意:root.after()root.after_cancel()假定tk.Tk的主实例称为root.如果你做了像mainwindow = tk.Tk()这样的事情,那就用mainwindow.after()吧!

最后要注意的是,在某个地方实际调用takeWeight函数之前,takeWeight中的连续轮询不会开始.

Python-3.x相关问答推荐

根据其他数据框架的列顺序从数据框架中进行 Select

如何在Django中创建两个不同权限的用户?

我的SELECT函数搜索的是列,而不是列中的数据.我怎么才能让它搜索数据呢?

替换Pandas中组下的列值

以编程方式关闭jupyterlab内核

如何使用TensorFlow Keras子类化来构建和训练模型

将列表项的极列水平分解为新列

可以在 Python 的上下文管理器中调用 sys.exit() 吗?

为什么空列表也能起作用?

根据按不同列中的值分组的平均值划分 DataFrame

将两列合并为一列,将它们制成字典 - pandas - groupby

协议不支持地址系列在将 Scapy L3socket 与 WSL 一起使用时

SqlAlchemy - 从 oracle db 中检索长文本

正则表达式从文本文件中捕获包含制表符/空格和子字符串的部分字符串

魔术8球txt文件列表

如何准确测定cv2的结果.在BW/黑白图像中查找对象?

python 3:如何判断一个对象是否是一个函数?

如何在 Python 中计算 cohen 的 d?

如何在 jupyter notebook 5 中逐行分析 python 3.5 代码

变量类型注解NameError不一致