Lior shem
Lior shem

Reputation: 31

Trying to use multi-thread to receive data of socket

edit: After my plan changed (Bryan saying I could not use the 'select' library for TkInter) I tried using multi-threading and I've typed something which doesn't seem to work:

def receive_data():
    try:
        (client_socket, address) = server_socket.accept()
        print client_socket.recv(1024)
    except socket.error:
        print 'error'


def server_window():
    window = Tk()
    data = ''
    activate_window(window, 666, 666)
    b1 = Button(window, text='RECEIVE DATA', fg='sienna', bg='khaki', command=lambda info=data: handle_waiter(info))
    b1.grid(sticky='W', row=2, column=0, columnspan=1)
    b1 = Button(window, text='ORDERS',  fg='sienna', bg='khaki', command=orders_window)
    b1.grid(sticky='W', row=1, column=0, columnspan=1)
    thread = threading.Thread(target=receive_data())
    thread.start()

    window.mainloop()

Yet, what I have done seems to be blocking the GUI... I would be glad if anyone could help me

Upvotes: 0

Views: 82

Answers (2)

Lior shem
Lior shem

Reputation: 31

after some time I managed to use select without it blocking my TKinter code,

for now i configured some random button(b5) to send a message (which should be blocking)

def rms_window(waiter):
    """MAIN WAITER'S WINDOW"""
    window = waiter.get_window()  # Main window called from the waiter class.
    activate_window(window, 600, 482)  # 600x482

    bg_icon = ImageTk.PhotoImage(Image.open('bg_icon.png'))  # Image background picture.
    bg_label = Label(window, height=482, width=600, image=bg_icon)  # Create an image label for the window background.
    bg_label.place(x=0, y=0)

    order_list = Listbox(window, height=10, width=30, bg='white', fg='brown')  # Order list ListBox.
    sort_gui(window, order_list)  # sort scrollbar, labels and order list inside the waiter's window.

    menu_icon = ImageTk.PhotoImage(Image.open('menu_icon.png'))  # Image of the menu button.
    b1 = Button(window, image=menu_icon)  # Append button to the main window and apply picture.
    set_gui(b1, 'Menu', 'cyan', 'cyan')
    b1.configure(command=lambda i=waiter.get_socket(): open_menu(waiter, order_list))  # on click - open menu window.
    b1.grid(row=0, column=0)

    t1 = Text(window, width=25, height=1, bg='brown')  # Simple text box used to read bill number in the bill button
    t1.grid(row=14, column=0)

    b2 = Button(window)  # Bill button - reads text from variable t1 and sends the bill of the number given.
    set_gui(b2, 'Bill', 'pale goldenrod', 'chocolate')
    b2.configure(command=lambda i=waiter.get_socket(): send_bill('BILL ' + t1.get(1.0, END), i))
    b2.grid(row=15, column=0)  # Sends the bill to the server once you type an order number inside the textbox.

    b3 = Button(window)
    set_gui(b3, 'SEND ORDER', 'brown', 'chocolate')
    b3.configure(command=lambda i=waiter: i.send_order(order_list))  # On click send the whole order list to the server.
    b3.grid(row=10, column=0)  # Send the order listed in the list box widget.

    chat_icon = ImageTk.PhotoImage(Image.open("chat_icon.png"))
    b4 = Button(window, image=chat_icon)  # Apply chat icon image to waiters chatting button.
    set_gui(b4, 'WAITERS CHAT', 'green', 'green')
    b4.configure(command=lambda i=waiter: waiters_chat(i))  # On click - opens the chat service.
    b4.grid(row=0, column=1, sticky='W')

    b5 = Button(window)
    set_gui(b5, 'TESTER', 'green', 'green')
    b5.configure(command=test_cmd(messages_to_send, waiter.get_socket()))
    b5.grid(row=5, column=5)

    read_list, write_list, x_list = select.select([waiter.get_socket()], [waiter.get_socket()], [])
    send_waiting_messages(write_list, messages_to_send)
    others_messages(read_list)

while the functions are:

def others_messages(read_list):
    for current_socket in read_list:
        try:
            data = current_socket.recv(1024)
            print data
        except:
            print "Connection with server closed."
            current_socket.close()


def send_waiting_messages(write_list, m_to_send):
    for message in m_to_send:
        (client_socket, data) = message
        if client_socket in write_list:
            print data
            client_socket.send(data)
            m_to_send.remove(message)

Upvotes: 1

Right leg
Right leg

Reputation: 16730

The problem is that the target of a thread is a callable. What you're passing to Thread, on the other hand, is not receive_data, but receive_data().

Long story short, the receive_data function is called on the current thread when you reach the point of the parameter evaluation for the Thread constructor, and you stay inside of it until it ends.

You just need to remove the parentheses, and create your thread as follows:

thread = threading.Thread(target=receive_data)

Upvotes: 1

Related Questions