Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
2.33/5 (3 votes)
See more:
hi guys why this code return erro in line 44 for my opinion is correct 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()


the line 44 is
data_list = event.data


error dump:
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
                ^^^^^^^^^^ 


What I have tried:

nothing special for the moment
Posted
Updated 10-Aug-23 23:45pm
v4
Comments
Dave Kreskowiak 10-Aug-23 18:34pm    
You forgot to point what which line is "line 44" and the EXACT text of the error message.
GiulioRig 10-Aug-23 18:42pm    
sorry is data_list = event.data
Dave Kreskowiak 10-Aug-23 19:29pm    
Adn the exact error message? We only get what you type to work with, and a code dump with "it's broke" doesn't qualify as an answerable question.
Patrice T 11-Aug-23 2:07am    
And you plan to tell us the error message ?

I suspect the problem is in the receive_data function. When it generates the <<DataReceived>> event it is possible that the event data is "None". You need to check that data_list contains some actual data before you pass it to the event handler.

[edit]
Running further tests it appears that custom events do not contain a data attribute. See tkinter — Python interface to Tcl/Tk — Python 3.11.4 documentation[^] for details.

But the tkinter documentation is somewhat sparse.

[/edit]
 
Share this answer
 
v2
Comments
Andre Oosthuizen 11-Aug-23 9:24am    
It is quite scarce, I found another way to run the update in the main thread, see my update.
Your error is related to the way you're accessing the data of the custom event object. In your code you have created a custom event class called 'CustomEvent' to handle the custom data, but you are trying to access the data attribute of the event object directly, which is causing the error.

You need to modify the way you generate the custom event -
Python
def generate_custom_event(widget, data):
    event = CustomEvent(widget, data)
    widget.event_generate("<<DataReceived>>", when="tail", data=event)


You need to modify the 'receive_data' function to use the 'generate_custom_event' function to send the received data as a 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)


In your 'update_table' function, you need to access the data attribute of the custom event object -
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]
If the error below in the comments is shown, it means you are trying handling threading in a 'Tkinter' application. 'Tkinter' is not thread-safe, meaning you can't update the GUI from a non-main thread directly. You need to ensure that the GUI updates are performed from the main thread. You need to use the 'root.after()' method to schedule updates in the main thread. You can learn more from - How to Schedule an Action with Tkinter after() method[^]

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...
 
Share this answer
 
v2
Comments
GiulioRig 11-Aug-23 8:03am    
i try your solution but return this error AttributeError: 'Event' object has no attribute 'data'
Exception in thread Thread-1 (receive_data):
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\threading.py", line 1038, in _bootstrap_inner
self.run()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\pct\Desktop\python\tabella.py", line 39, in receive_data
generate_custom_event(root, data_list)
File "C:\Users\pct\Desktop\python\tabella.py", line 95, in generate_custom_event
widget.event_generate("<<datareceived>>", when="tail", data=event)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\tkinter\__init__.py", line 1914, in event_generate
self.tk.call(args)
RuntimeError: main thread is not in main loop
Richard MacCutchan 11-Aug-23 8:37am    
See my answer above, you cannot add arbitrary data to an event. The framework constructs the event from specific information, and passes only those attributes to the handler. To see the list of attributes add the following line to your handler:
print(event.__dict__)
Andre Oosthuizen 11-Aug-23 9:24am    
I have updated my solution, see after 'Edit'.
GiulioRig 12-Aug-23 4:18am    
return me this In ascolto su 127.0.0.1:23456
Connesso da ('127.0.0.1', 55606)
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:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1264.0_x64__qbz5n2kfra8p0\Lib\tkinter\__init__.py", line 861, in callit
func(*args)
File "C:\Users\pct\Desktop\python\tabella.py", line 20, in handle_received_data
tree.item(tree.get_children()[1], values=data_list)
~~~~~~~~~~~~~~~~~~~^^^
IndexError: tuple index out of range
Richard MacCutchan 11-Aug-23 10:14am    
Looks good.
Since it's been over 5 hours, and you still haven't told us what the error message you are getting is, the best we can do is give you generic syntax error message help: How to Write Code to Solve a Problem, A Beginner's Guide Part 2: Syntax Errors[^]
And I'll throw this in there as well: Asking questions is a skill[^] - I'd suggest you have a good read of them both, they should help you in future.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900