如何并排使用Tkinter和Socket

时间:2016-09-10 04:14:00

标签: python-2.7 sockets loops tkinter

所以我编写了一个程序,其目的是从Tkinter GUI接收值,然后从socket发送到另一台计算机。

问题是Tkinter占用了所有循环。我已经尝试过使用root.after()但是套接字的东西依赖于.get()函数,所以当由于GUI还没有出现而被调用时,我正在尝试发送的内容没有任何值

这是一个更简单的代码示例,说明我正在尝试做什么(我的更大,大约10个不同的变量更大)

HOST= 'ip address'
PORT = 8000
s= socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1) #I'm aiming for this to eventually be 24.
conn, addr = s.accept

def data():
    Value = str(value.get())
    conn.sendall(str(Value))

root = Tk()
value = Scale(root, from_=255, to=0)
value.set(60)
value.pack() #not using pack but grid. Pack is just easier for simple example.

root.after(500, data())
root.mainloop()

那么如何让这一切在循环中运行?所以它在发生变化时发送数据? (希望每一秒,都是我的目标)。我理解在root.mainloop之前使用root.after的问题,但是否则不会起作用。请注意,无论如何它都不起作用。

我认为线程和队列可能是唯一的解决方案,但我一直在努力使用这些模块。

我需要它不断循环两个程序组件,以便在GUI幻灯片更改时不断发送数据。

1 个答案:

答案 0 :(得分:0)

您的根本问题是root.after(500, data())计划调用调用data的结果,即None。您应该改为传递函数:root.after(500, data)。要定期发送,请在data电话后将同一行添加到conn.sendall的末尾。要仅在值发生变化时发送,您需要存储“旧”字样。价值和比较。这些变化包含在以下内容中。

from tkinter import *

oldvalue = 60
interval = 500

def data():
    global oldvalue
    newvalue = str(value.get())
    if newvalue != oldvalue:
        print(newvalue)
        oldvalue = newvalue
    root.after(interval, data)

root = Tk()
value = Scale(root, from_=255, to=0)
value.set(oldvalue)
value.pack() #not using pack but grid. Pack is just easier for simple example.

root.after(1, data)
root.mainloop()

请注意,使用print作为send的替身,可以更轻松地尝试使用GUI。这样做表明在移动滑块时将发送中间值。如果这不是您想要的,您将尝试更多。而不是使用after,绑定'<ButtonRelease-1>' to数据。或轮询,仅在获得相同值两次时发送。或者其他什么。