2015-04-16 171 views
-1

我试图使用Python和scapy编写数据包嗅探器,并使用Tkinter实现GUI。除了“退出”按钮,一切看起来都很好。我使用的代码:Tkinter按钮不起作用

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和我相信我做了这是造成这个问题的一些主要的概念上的错误。

+0

你在哪个平台上运行这个平台? –

+0

Linux 立即在Ubuntu上运行此操作。 另外我对Python很新,所以我的代码很混乱。但如果你愿意的话,如果你能帮助我,我可以给你看。 –

+0

请阅读http://stackoverflow.com/help/mcve –

回答

1

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

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

我刚试过这个。没有工作。我认为问题在于按钮不可点击。 通常,当你将鼠标放在Tkinter按钮上时,它会有点沮丧。这在我的程序中没有发生。我无法鼠标移动或点击它。 –

+0

好的,从您的问题中我并不清楚,因为您使用lambda的方式确实会导致您单击按钮时不发生任何事情。然后,你必须发布一个示例代码来演示这个问题,因为从你发布的代码中没有任何东西会导致这种行为。请阅读Bryan Oakley发布的关于如何做出正确例子的链接。 – fhdrsdg

+0

所以我减少了与这个问题无关的额外代码,并将其降低到这个程度。 希望这是一个更好的例子。 –