Tkinter按钮不起作用

时间:2015-04-16 09:45:35

标签: python python-2.7 tkinter tk

我尝试使用Python和scapy编写数据包嗅探器,并使用Tkinter实现GUI。除了" Quit"以外,一切似乎都运转良好。按钮。我使用的代码是:

quitButton = Button(main_win,text="Quit", command=lambda:exitClick)
quitButton.pack(side="bottom")

函数exitClick()定义为:

def exitClick(main_win):
    main_win.destroy()
    main_win.quit()
    sys.exit()

然而,当我点击退出按钮时,没有任何反应。我没有按钮动画,也没有关闭程序。我需要改变什么?

代码的删节版本如下:

import fcntl, easygui, logging
from Tkinter import *
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *

inc_txt_str = ""
out_txt_str = ""

def exitClick(main_win):
    main_win.quit()
    sys.exit()

main_win = Tk()
main_win.withdraw()
frame_incoming = Frame(main_win)
t = Text(frame_incoming, width=45, bg="black", fg="white")
t.pack(fill=BOTH, expand=YES, side="left")
s = Scrollbar(frame_incoming)
s.pack(side="right", fill="y")
s.config(command=t.yview)
t.config(yscrollcommand=s.set)
frame_incoming.pack(side="left")

frame_outgoing = Frame(main_win)
t1 = Text(frame_outgoing, width=45, bg="white", fg="black")
t1.pack(side="left", fill="both", expand=YES)
s1 = Scrollbar(frame_outgoing)
s1.pack(side="right", fill="y")
s1.config(command=t1.yview)
t1.config(yscrollcommand=s1.set)
frame_outgoing.pack(side="left")

border_buttons = Frame(main_win)
border_buttons.pack(side="bottom")

quitButton = Button(main_win,text="Quit", command=lambda:exitClick(main_win))
quitButton.pack(side="bottom")

parseButton = Button(main_win, text='Parse IP')
parseButton.pack(side="bottom")



def eth_addr(a):
    b = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" % (ord(a[0]), ord(a[1]), ord(a[2]), ord(a[3]), ord(a[4]), ord(a[5]))
    return b


class sniffPacket:

    def processIPFrame(self, pkt_type, ip_header, payload):
        fields = struct.unpack("!BBHHHBBHII", ip_header)
        dummy_hdrlen = fields[0] & 0xf
        iplen = fields[2]
        ip_src = payload[12:16]
        ip_dst = payload[16:20]
        ip_frame = payload[0:iplen]
        if pkt_type == socket.PACKET_OUTGOING:
            if self.outgoingIP is not None:
                self.outgoingIP(ip_src, ip_dst, ip_frame)
        else:
            if self.incomingIP is not None:
                self.incomingIP(ip_src, ip_dst, ip_frame)

    def __init__(self, interface_name, incomingIP, outgoingIP):

        self.interface_name = interface_name
        self.incomingIP = incomingIP
        self.outgoingIP = outgoingIP
        self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
        self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2 ** 30)
        self.ins.bind((self.interface_name, ETH_P_ALL))
        pkt, sa_ll = self.ins.recvfrom(MTU)
        eth_header = struct.unpack("!6s6sH", pkt[0:14])
        dummy_eth_protocol = socket.ntohs(eth_header[2])
        ip_header = pkt[14:34]
        payload = pkt[14:]
        self.processIPFrame(sa_ll[2], ip_header, payload)

    def getPacket(self):
        pkt, sa_ll = self.ins.recvfrom(MTU)
        eth_header = struct.unpack("!6s6sH", pkt[0:14])
        dummy_eth_protocol = socket.ntohs(eth_header[2])
        ip_header = pkt[14:34]
        payload = pkt[14:]
        self.processIPFrame(sa_ll[2], ip_header, payload)
        main_win.after(500,getPacket())


    def all_interfaces():
        max_possible = 128
        bytes = max_possible * 32
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        names = array.array('B', '\0' * bytes)
        outbytes = struct.unpack('iL', fcntl.ioctl(
            s.fileno(),
            0x8912,  # SIOCGIFCONF
            struct.pack('iL', bytes, names.buffer_info()[0])))[0]
        namestr = names.tostring()
        lst = []
        for i in range(0, outbytes, 40):
            name = namestr[i:i + 16].split('\0', 1)[0]
            ip = namestr[i + 20:i + 24]
            lst.append((name, ip))
        return lst


    def format_ip(addr):
        return str(ord(addr[0])) + '.' + \
               str(ord(addr[1])) + '.' + \
               str(ord(addr[2])) + '.' + \
               str(ord(addr[3]))


    def get_ip_address(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15]))[20:24])

def incoming_packet_callback(src, dst, frame_incoming):
    global inc_txt_str
    main_win.deiconify()
    inc_txt_str += "Incoming from "
    inc_txt_str += str(socket.inet_ntoa(src))
    inc_txt_str += "\n"
    t.insert(END, inc_txt_str)
    t.see(END)
    t.update_idletasks()

def outgoing_packet_callback(src, dst, frame_incoming):
    global out_txt_str
    main_win.deiconify()
    out_txt_str += "Outgoing to "
    out_txt_str += str(socket.inet_ntoa(dst))
    out_txt_str += "\n"
    t1.insert(END, out_txt_str)
    t1.see(END)
    t1.update_idletasks()

interface = "wlan0"
ip_s = sniffPacket(interface, incoming_packet_callback, outgoing_packet_callback)
#main_win.after(500,ip_s.getPacket)
main_win.mainloop()

我对Python非常陌生,我相信我已经犯了一些重大的概念错误,导致了这个问题。

1 个答案:

答案 0 :(得分:1)

你使用lambda能够将main_win变量传递给你的函数,但是你只引用函数而不是让lambda实际调用它。
使用:

Button(..., command=lambda: exitClick(main_win))