Python 向tkinter表动态添加数据

Python 向tkinter表动态添加数据,python,tkinter,Python,Tkinter,我想创建一个如下所示的表 行中的数据是连续生成的。我希望以动态创建行的方式创建表。我写了下面的代码(非常新的修补程序,可能只有6个小时的新),但没有插入数据 from scapy.all import * from scapy.layers.http import HTTPRequest,HTTPResponse,HTTP # import HTTP packet from tkinter import ttk import tkinter as tk def generateDat

我想创建一个如下所示的表

行中的数据是连续生成的。我希望以动态创建行的方式创建表。我写了下面的代码(非常新的修补程序,可能只有6个小时的新),但没有插入数据

from scapy.all import *
from scapy.layers.http import HTTPRequest,HTTPResponse,HTTP # import HTTP packet

from tkinter import ttk 
import tkinter as tk 


def generateData():
    sniff_packets()
    
    
def sniff_packets():
    window.mainloop() # <<---The window loop 
    window.after(300, process_packet)
    sniff(filter="port 80", prn=process_packet, iface="utun2", store=False)
    
    
def process_packet(packet):
    print("Called to process_packet() ")
    
    http_packet = str(packet)
    if packet.haslayer(HTTP):
        #if "www.xyz.com" in http_packet:
        #    print(http_packet)
        if 'XYZ' in http_packet:
            
            if HTTPRequest in packet:
                http_request = packet[HTTPRequest]
                insertDataDynamic((arrangePacket(str(http_request)))
                
               
                
            if HTTPResponse in packet:   
                http_response = packet[HTTPResponse]
                insertDataDynamic((arrangePacket(str(http_request)))
                
    
    
    
             
        
 
def insertDataDynamic(api_data):
        print("Called to insertDataDynamic() ")
        treev.insert("", 'end', text ="L1",  
             values =("DATA ", api_data, "HTTP"))        



    

def arrangePacket(httpLayer):
    
    ret = "***************************************GET PACKET****************************************************\n"
    ret += "\n".join(httpLayer.split(r"\r\n"))
    ret += "\n *****************************************************************************************************\n"
    return ret


if __name__ == "__main__":
    window = tk.Tk() 
    window.resizable(width = 1, height = 1) 
    treev = ttk.Treeview(window, selectmode ='browse') 
    treev.pack(side ='right') 
  
    # Constructing vertical scrollbar 
    # with treeview 
    verscrlbar = ttk.Scrollbar(window,  
                               orient ="vertical",  
                               command = treev.yview) 
      
    # Calling pack method w.r.to verical  
    # scrollbar 
    verscrlbar.pack(side ='right', fill ='x') 
      
    # Configuring treeview 
    treev.configure(xscrollcommand = verscrlbar.set) 
      
    # Defining number of columns 
    treev["columns"] = ("1","2","3") 
      
    # Defining heading 
    treev['show'] = 'headings'
      
    # Assigning the width and anchor to  the 
    # respective columns 
    treev.column("1", width = 500, anchor ='c') 
    treev.column("2", width = 500, anchor ='se') 
    treev.column("3", width = 500, anchor ='se')  
      
    # Assigning the heading names to the  
    # respective columns 
    treev.heading("1", text ="Name") 
    treev.heading("2", text ="Sex") 
    treev.heading("3", text ="Age")

    generateData()
从scapy.all导入*
从scapy.layers.http导入HTTPRequest、HTTPResponse、http#导入http数据包
从tkinter导入ttk
将tkinter作为tk导入
def generateData():
嗅探数据包()
def嗅探_数据包():
window.mainloop()#window.mainloop()在关闭窗口之前不会结束。它允许公开GUI和处理事件。
有几个问题与这个主题有关。例如:

window.mainloop()在关闭窗口之前不会结束。它允许公开GUI和处理事件。
有几个问题与这个主题有关。例如,这一个:

我将您的函数放在
main循环中,因此在生成gui时将调用它。
还要注意的是,我把这个方法放在你的函数中,所以它每300毫秒调用一次

from tkinter import ttk 
import tkinter as tk 

treev = None
window = None

def generateData(self):
        #This is my API which makes a rest call and gets data 
        api_data = restcall()
        insertDataDynamic(api_data)
        window.after(300, generateData) 

def insertDataDynamic(self,api_data):
        treev.insert("", 'end', text ="L1",  
             values =(api_data.name, api_data.gender, api_data.age))  

if __name__ == "__main__":

    
    window = tk.Tk() 
    window.resizable(width = 1, height = 1) 
    treev = ttk.Treeview(window, selectmode ='browse') 
    treev.pack(side ='right') 
  
    # Constructing vertical scrollbar 
    # with treeview 
    verscrlbar = ttk.Scrollbar(window,  
                               orient ="vertical",  
                               command = treev.yview) 
      
    # Calling pack method w.r.to verical  
    # scrollbar 
    verscrlbar.pack(side ='right', fill ='x') 
      
    # Configuring treeview 
    treev.configure(xscrollcommand = verscrlbar.set) 
      
    # Defining number of columns 
    treev["columns"] = ("1","2","3") 
      
    # Defining heading 
    treev['show'] = 'headings'
      
    # Assigning the width and anchor to  the 
    # respective columns 
    treev.column("1", width = 500, anchor ='c') 
    treev.column("2", width = 500, anchor ='se') 
    treev.column("3", width = 500, anchor ='se')  
      
    # Assigning the heading names to the  
    # respective columns 
    treev.heading("1", text ="Name") 
    treev.heading("2", text ="Sex") 
    treev.heading("3", text ="Age")
    generateData()  
    window.mainloop()
可以在此处找到一个示例:

import tkinter as tk

def test():
    print('test')
    window.after(300, test)


window = tk.Tk()

test()
window.mainloop()

我将您的函数放在
main循环中
,以便在生成gui时调用它。 还要注意的是,我把这个方法放在你的函数中,所以它每300毫秒调用一次

from tkinter import ttk 
import tkinter as tk 

treev = None
window = None

def generateData(self):
        #This is my API which makes a rest call and gets data 
        api_data = restcall()
        insertDataDynamic(api_data)
        window.after(300, generateData) 

def insertDataDynamic(self,api_data):
        treev.insert("", 'end', text ="L1",  
             values =(api_data.name, api_data.gender, api_data.age))  

if __name__ == "__main__":

    
    window = tk.Tk() 
    window.resizable(width = 1, height = 1) 
    treev = ttk.Treeview(window, selectmode ='browse') 
    treev.pack(side ='right') 
  
    # Constructing vertical scrollbar 
    # with treeview 
    verscrlbar = ttk.Scrollbar(window,  
                               orient ="vertical",  
                               command = treev.yview) 
      
    # Calling pack method w.r.to verical  
    # scrollbar 
    verscrlbar.pack(side ='right', fill ='x') 
      
    # Configuring treeview 
    treev.configure(xscrollcommand = verscrlbar.set) 
      
    # Defining number of columns 
    treev["columns"] = ("1","2","3") 
      
    # Defining heading 
    treev['show'] = 'headings'
      
    # Assigning the width and anchor to  the 
    # respective columns 
    treev.column("1", width = 500, anchor ='c') 
    treev.column("2", width = 500, anchor ='se') 
    treev.column("3", width = 500, anchor ='se')  
      
    # Assigning the heading names to the  
    # respective columns 
    treev.heading("1", text ="Name") 
    treev.heading("2", text ="Sex") 
    treev.heading("3", text ="Age")
    generateData()  
    window.mainloop()
可以在此处找到一个示例:

import tkinter as tk

def test():
    print('test')
    window.after(300, test)


window = tk.Tk()

test()
window.mainloop()

这里什么是动态?动态意味着,行将继续添加。RESTAPI是连续调用的,因此我从generateData获得的数据将继续在tkinter树视图中插入行,那么我的答案应该适用于您。tkinter的after方法就是您要寻找的。
sniff(…)
是一个阻塞函数。所以如果你想和tkinter一起运行,你应该在一个线程中运行它。这里什么是动态的?动态的意思是,行将继续添加。RESTAPI是连续调用的,因此我从generateData获得的数据将继续在tkinter树视图中插入行,那么我的答案应该适用于您。tkinter的after方法就是您要寻找的。
sniff(…)
是一个阻塞函数。所以如果你想和tkinter一起运行,你应该在一个线程中运行它。我已经用生成数据的实际代码修改了我的代码。嗅探生成了数据包,我想向tinker行添加数据包信息。windowloop导致无法调用sniff process_数据包的prn。您确定是mainloop而不是after方法导致问题吗?因为你的程序做了它应该做的,只是不是自动的。也许你需要给你的功能更多的时间来完成。尝试1000而不是300MSB,但由于主循环,进程_packet()似乎根本没有被调用。如果我删除mainloop,那么进程_packet()将被sniff调用。不确定是不是因为两者都是连续的过程?哦,你更新了你的问题。我懂了。问题是tkinter读取代码直到调用mainloop为止。因此,mainloop应该是代码中最后读取的行,mainloop后面的所有内容都将在您中断mainloop之后执行。事情是,只要mainloop被执行,那么代码的另一部分就不会执行。processPacket是从sniff连续调用的。一旦我看到一个数据包,我就想在tkinter中显示它。我已经用生成数据的实际代码修改了我的代码。嗅探生成了数据包,我想向tinker行添加数据包信息。windowloop导致无法调用sniff process_数据包的prn。您确定是mainloop而不是after方法导致问题吗?因为你的程序做了它应该做的,只是不是自动的。也许你需要给你的功能更多的时间来完成。尝试1000而不是300MSB,但由于主循环,进程_packet()似乎根本没有被调用。如果我删除mainloop,那么进程_packet()将被sniff调用。不确定是不是因为两者都是连续的过程?哦,你更新了你的问题。我懂了。问题是tkinter读取代码直到调用mainloop为止。因此,mainloop应该是代码中最后读取的行,mainloop后面的所有内容都将在您中断mainloop之后执行。事情是,只要mainloop被执行,那么代码的另一部分就不会执行。processPacket是从sniff连续调用的。所以,一旦我看到一个包,我想在tkinter中显示它。