update_table 中的错误第 44 行

编程


大家好,为什么这段代码在第 44 行返回错误,因为我认为是正确的 o_O

import tkinter as tk
from tkinter import ttk
import socket
import threading

def cell_selected(event):
    selected_item = tree.selection()[0]
    item_values = tree.item(selected_item, 'values')
    print("Selected item:", item_values)

def connect_action():
    threading.Thread(target=receive_data).start()

def exit_program():
    root.quit()

def receive_data():
    host = "127.0.0.1"
    port = 23456
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((host, port))
        s.listen()
        print(f"In ascolto su {host}:{port}")
        
        try:
            conn, addr = s.accept()	
            with conn:
                print(f"Connesso da {addr}")
                
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    data_str = data.decode("utf-8")
                    data_list = data_str.split(",")
                    
                    root.event_generate("<<DataReceived>>", data=data_list)
                    
        except socket.error as e:
            print("Errore nella connessione:", e)

def update_table(event):
    data_list = event.data
    if data_list:
        tree.item(tree.get_children()[1], values=data_list)

root = tk.Tk()
root.title("Spreadsheet App")

# Creazione del widget Notebook (schede)
notebook = ttk.Notebook(root)
notebook.pack(fill="both", expand=True)

# Primo tab con il primo Treeview
tab1 = ttk.Frame(notebook)
notebook.add(tab1, text="Terminal")

columns = ("Order","TimeOp","Type","Size","Symbol","Price","S/L","T/P",
           "Price","Com.","Swap","Profit","Comment","Close")

tree = ttk.Treeview(tab1, columns=columns, show="headings")
for col in columns:
    tree.heading(col, text=col)
    
tree.bind("<ButtonRelease-1>", cell_selected)
tree.pack(padx=10, pady=10)

# Pulsante "Connetti" a destra
connect_button = tk.Button(root, text="Connetti", command=connect_action)
connect_button.pack(side="right", padx=10, pady=5)

# Secondo tab con il secondo Treeview
tab2 = ttk.Frame(notebook)
notebook.add(tab2, text="Storico")

tree2 = ttk.Treeview(tab2, columns=("Symbol","Price","S/L"), show="headings")
# ... Aggiungi colonne e dati al secondo Treeview ...

tree2.bind("<ButtonRelease-1>", cell_selected)
tree2.pack(padx=10, pady=10)

exit_button = tk.Button(root, text="Esci", command=exit_program)
exit_button.pack(side="right", pady=5)

class CustomEvent:
    def __init__(self, widget, data):
        self.widget = widget
        self.data = data

def generate_custom_event(widget, data):
    event = CustomEvent(widget, data)
    widget.event_generate("<<DataReceived>>", when="tail", data=event)

root.bind("<<DataReceived>>", update_table)  # Bind custom event

root.mainloop()

第 44 行是

data_list = event.data

错误转储:

In ascolto su 127.0.0.1:23456
Connesso da ('127.0.0.1', 64976)
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\pct\Desktop\python\tabella.py", line 44, in update_table
    data_list = event.data
                ^^^^^^^^^^ 

我尝试过的:

目前没什么特别的

解决方案4

我怀疑问题出在 receive_data 功能。 当它生成 <<DataReceived>> event 事件数据可能为“None”。 你需要检查一下 data_list 在将其传递给事件处理程序之前包含一些实际数据。

[edit]

运行进一步测试,似乎自定义事件不包含 data 属性。 看 tkinter — Tcl/Tk 的 Python 接口 — Python 3.11.4 文档[^] 了解详情。

但 tkinter 文档有点稀疏。

[/edit]

解决方案5

您的错误与您访问自定义事件对象的数据的方式有关。 在您的代码中,您创建了一个名为“CustomEvent”的自定义事件类来处理自定义数据,但您尝试直接访问事件对象的数据属性,这导致了错误。

您需要修改生成自定义事件的方式 –

Python
def generate_custom_event(widget, data):
    event = CustomEvent(widget, data)
    widget.event_generate("<<DataReceived>>", when="tail", data=event)

您需要修改“receive_data”函数以使用“generate_custom_event”函数将接收到的数据作为自定义事件发送 –

Python
def receive_data():
    host = "127.0.0.1"
    port = 23456
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((host, port))
        s.listen()
        print(f"In ascolto su {host}:{port}")
        
        try:
            conn, addr = s.accept()	
            with conn:
                print(f"Connesso da {addr}")
                
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    data_str = data.decode("utf-8")
                    data_list = data_str.split(",")
                    
                    #Send the received data as a custom event
                    generate_custom_event(root, data_list)
                    
        except socket.error as e:
            print("Errore nella connessione:", e)

在“update_table”函数中,您需要访问自定义事件对象的数据属性 –

Python
def update_table(event):
    custom_event = event.data  #Access your custom event object
    data_list = custom_event.data
    if data_list:
        tree.item(tree.get_children()[1], values=data_list)

[EDIT]

如果注释中显示以下错误,则意味着您正在尝试在“Tkinter”应用程序中处理线程。 “Tkinter”不是线程安全的,这意味着您无法直接从非主线程更新 GUI。 您需要确保 GUI 更新是从主线程执行的。 您需要使用“root.after()”方法来安排主线程中的更新。 您可以通过以下方式了解更多信息—— 如何使用 Tkinter after() 方法安排操作[^]

Python
#All your previous code...

#Function to handle received data inside the the main thread
def handle_received_data(data_list):
    if data_list:
        tree.item(tree.get_children()[1], values=data_list)

#I have modified receive_data function here...
def receive_data():
    host = "127.0.0.1"
    port = 23456
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((host, port))
        s.listen()
        print(f"In ascolto su {host}:{port}")
        
        try:
            conn, addr = s.accept()	
            with conn:
                print(f"Connesso da {addr}")
                
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    data_str = data.decode("utf-8")
                    data_list = data_str.split(",")
                    
                    #Schedule GUI update in the main thread here...
                    root.after(0, handle_received_data, data_list)
                    
        except socket.error as e:
            print("Errore nella connessione:", e)

#The rest of your code...

解决方案6

注释中显示了下面的错误,这意味着您正在尝试在“Tkinter”应用程序中处理线程。

https://projectfreetv.onl/
https://waplus.win/

解决方案1

由于已经过去 5 个多小时了,而您仍然没有告诉我们您收到的错误消息是什么,我们能做的就是为您提供通用语法错误消息帮助: 如何编写代码来解决问题,初学者指南第 2 部分:语法错误[^]

我也会把它放在那里: 提出问题是一种技巧[^] – 我建议你好好阅读这两本书,它们应该会对你将来有所帮助。

コメント

タイトルとURLをコピーしました