2015-04-16 172 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

所以我減少了與這個問題無關的額外代碼,並將其降低到這個程度。 希望這是一個更好的例子。 –