Py学习  »  Python

python 3:tkinter gui中的udp包发送/接收

Justin • 5 年前 • 1567 次点击  

所以,我可以很容易地编写一个小脚本来监听某个IP/端口上的UDP数据包,但我正在努力将其实现到Tkinter图形用户界面中。

每当我尝试使用由按钮触发的无限while true:循环时,gui应用程序就会崩溃。我做了进一步的研究,读了一些关于使用延迟的文章,但是我无法让它正常工作。我试过将while循环放入调用startreceiveing函数的代理函数中,但它也会使gui崩溃。下面的代码将启动一个gui并运行我当前的问题。

最终的问题是:如何让按钮触发事件开始发送数据包,同时仍然能够接受按钮事件来开始和停止接收数据包?

import socket
import tkinter as tk
import tkinter.font as tkFont

UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = b"Hello, world"

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((UDP_IP, UDP_PORT))

def startsending(run=True):
    while run is True:
        print("Sending Message.")
        sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

def startreceiving(run=True):
    while run is True:
        try:
            data, addr = sock.recvfrom(1024)
            print("received message:", data)
            print("from: ", addr)
        except OSError:
            break

class App(tk.Frame):
    STRIDE = 8
    DELAY = 100

    variables = []
    for i in range(10):
        variables.append(i)

    sensors = []
    for i in range(3):
        sensors.append(i)

    fields = []
    for i in range(len(sensors) * len(variables)):
        fields.append(i)

    def __init__(self, master=None):
        tk.Frame.__init__(self,master)
        self.grid()
        self.create_widgets()
        self.after(self.DELAY, self.update, self.DELAY)

    #---- Create the GUI Layout ----
    def create_widgets(self):
        self.btn_font = tkFont.Font(family="Helvetica", size=12, weight='bold')
        self.gui_buttons = []
        self.send_button = tk.Button(self,
                                     text = format("Begin Sending."),
                                     font = self.btn_font,
                                     relief = tk.RIDGE,
                                     pady = 4,
                                     command = self.send_message)
        self.send_button.grid(column=2, row=11)
        self.start_button = tk.Button(self,
                                 text = format("Begin Receiving."),
                                 font = self.btn_font,
                                 relief = tk.RIDGE,
                                 pady = 4,
                                 command = self.start_receiving)
        self.start_button.grid(column=3, row=11)
        self.stop_button = tk.Button(self,
                                     text = format("Stop Receiving."),
                                     font = self.btn_font,
                                     relief = tk.RIDGE,
                                     pady = 4,
                                     padx = 6,
                                     state='disabled',
                                     command = self.stop_receiving)

        self.stop_button.grid(column=3, row=12)
        x = 0
        y = 1
        for i, label in enumerate(self.variables):
            label = tk.Label(self,
                                text = format("Variable " + str(i)),
                                font = self.btn_font,
                                padx = 10)
            label.grid(column=x, row=y)
            y += 1

        x = 1
        y = 0
        for i, label in enumerate(self.sensors):
            sensor = tk.Label(self,
                                text = format("Sensor " + str(i)),
                                font = self.btn_font,
                                padx = 20,
                                relief = tk.RIDGE)
            sensor.grid(column=x, row=y)
            x += 1

        x = 1
        y = 1
        for i, field in enumerate(self.fields):
            field = tk.Entry(self,
                             width=10,
                             text=format("field val " + str(i)),
                             font=self.btn_font,
                             state='disabled')
            field.grid(column=x, row=y)
            y += 1
            if y > len(self.variables):
                y = 1
                x += 1

    #----Proxy to call the start receiving method using a delay and set the corresponding buttons to normal/disabled.
    def start_receiving(self):
        self.start_button.config(state='disabled')
        self.stop_button.config(state='normal')

        self.after(self.DELAY, startreceiving, self.DELAY)

    #----Proxy to call the stop receiving method using a delay and set the corresponding buttons to normal/disabled.
    def stop_receiving(self):
        self.stop_button.config(state='disabled')
        self.start_button.config(state='normal')

        self.after(self.DELAY, startreceiving(False), self.DELAY)
        self.after(self.DELAY, startsending(False), self.DELAY)

    #----Proxy to call the start sending method using a delay.
    def send_message(self):
        self.after(self.DELAY, startsending, self.DELAY)

app = App()
app.master.title('ESDR')
app.master.geometry('640x480')
app.mainloop()
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43381
 
1567 次点击  
文章 [ 2 ]  |  最新文章 5 年前